Подтвердить что ты не робот

PerformSegueWithIdentifier очень медленный, когда segue является модальным

У меня есть простой вид таблицы, где я обрабатываю действие select в представлении таблицы. Это действие следует за шагом.

Если segue является push segue, следующее представление отображается немедленно. Если segue является modal segue, следующий вид:

  • требуется около 6 секунд для отображения
  • показывает сразу, если я снова нажимаю (второй раз)

Я попытался оглянуться на некоторые идеи, но ни одна из них не применима к моей ситуации. В частности:

  • Я выполняю segue в основном потоке пользовательского интерфейса.
  • Мое мнение очень просто (поэтому нет проблем в viewDidLoad). Плюс тот факт, что он отображается почти мгновенно, когда segue push указывает, что нет проблем с загрузкой целевого представления
  • Я пробовал передать nil в sender; такой же эффект.

Есть ли у кого-нибудь идеи по этому поводу?

4b9b3361

Ответ 1

Поверьте мне и попробуйте это. Я несколько раз сталкивался с этой проблемой.

В Swift 2:

dispatch_async(dispatch_get_main_queue(),{
    self.performSegue(withIdentifier:mysegueIdentifier,sender: self)
})

или для Swift 3:

DispatchQueue.main.async {
    self.performSegue(withIdentifier: mysegueIdentifier,sender: self)
}

Как обсуждалось здесь и здесь.

Ответ 2

Кажется (мне...), что эта проблема возникает только тогда, когда ячейка selectionType не .none.

Вы можете изменить его на любой другой вариант (в раскадровке Attribute inspector, установите поле Selection), и он будет работать нормально (работает для меня...). Недостатком является то, что он испортил пользовательский интерфейс ячейки.

Вы можете вызвать segue в блоке DispatchQueue.main.async{} в функции делегата didSelect от UITableViewDelegate, как упоминалось ранее.

Я использовал первое решение и добавил его в ячейку -

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(false, animated: false)
}

Это сделает ячейку "выделенной" на кране, но она вернется к своему обычному пользовательскому интерфейсу сразу, и это отлично для меня...

Ответ 3

Кажется, что различные ситуации, когда выполнение segue не будет работать должным образом. Например, если вы вызываете performSegue из обработчика события разматывания, вы столкнетесь с различными проблемами, даже если вы находитесь в основном потоке. В моем текущем проекте я вызываю performSegue из метода didSelectRowAt представления таблицы. Это один из самых основных сегментов и, конечно же, я нахожусь в основном потоке, но я видел точные симптомы, описанные ОП.

Я не знаю, почему это происходит в некоторых случаях, а не в других, но я обнаружил, что отсрочка вызова performSegue с помощью async устраняет любые потенциальные проблемы. Раньше это выглядело как хак и заставляло меня нервничать, но на данный момент у меня есть несколько зрелых проектов, использующих этот подход, и теперь это похоже на "правильный" способ сделать ручной сеанс.

Вот версия кода Swift 3 (см. другие сообщения для версий Swift 2 и Obj-C):

DispatchQueue.main.async {
    self.performSegue(withIdentifier: "theIdentifier", sender: theSender)
}

Ответ 4

Принятое решение сработало для меня. Код обновлен для Swift 2.0 ниже:

dispatch_async(dispatch_get_main_queue(),{
     self.performSegueWithIdentifier(mysegueIdentifier, sender:self)
})

Ответ 5

Надеемся, что эта помощь может создать программно-модальный переход, подобный этому в Swift:

       let myStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let modalViewController = myStoryboard.instantiateViewControllerWithIdentifier("myModalViewController") as! myModalViewController
        modalViewController.modalTransitionStyle = UIModalTransitionStyle.CoverVertical
        let navController = UINavigationController(rootViewController: accountManager)
        dispatch_async(dispatch_get_main_queue(),{
            self.presentViewController(navController, animated: true, completion: nil)
        })

Ответ 6

Для разработчиков, организующих свой код с помощью подкласса, я пришел к довольно простому решению, которое хотел бы поделиться (Swift 4):

import UIKit

class ABCViewController: UIViewController {

  // ... Other useful methods like overriding deinit and didReceiveMemoryWarning

  // Performs a segue on the main thread to ensure it will 
  // transition once a UI-slot is available
  func performSegueOnMainThread(with identifier: String, sender: Any?) {
    DispatchQueue.main.async {
      self.performSegue(with: identifier, sender: sender)
    }
  }
}

Затем просто назовите его из своей реализации:

myViewController.performSegueOnMainThread(with: "ShowDetailsSegue", sender: self)

Ответ 7

Для меня это было то, что у меня было слишком много "чистых" цветных представлений в моем следующем виде, поэтому, когда переход был анимированным, казалось, что он задерживается из-за этого. Я просмотрел иерархию пользовательского интерфейса контроллера представления в поисках чистых цветов, заменил их сплошным черным или белым и убедился, что альфа равна 1 (если не нужно было иначе). Моя задержка теперь прошла, и мое модальное представление гладко.

Ответ 8

Я попытался исправить это несколько способов, в том числе переместить его в основной поток выше. Это сработало для меня:

В раскадровке выберите рассматриваемое представление таблицы (выберите его в контуре документа, чтобы убедиться, что у вас есть правильная вещь. Затем в инспекторе атрибутов вы сможете увидеть атрибуты для представления таблицы, а также содержащего scrollview под ним (все представления таблиц основаны на просмотре прокрутки). В этой глупой маленькой коробке есть "задержек содержания". Снимите флажок. Также есть "разрешает отменить касания", которые, я думаю, вы хотите сделать уверен, также не отмечен, так как я думаю, что двойные касания были беспорядочными.