Приложение вылетает при представлении представления (поповера) во второй раз - PullRequest
0 голосов
/ 28 июня 2018

Я только что наткнулся на эту проблему, и мне было интересно, если кто-нибудь может помочь объяснить проблему.

При использовании на iPad мое представление имеет вложенную UINavigationController, которая отображается во всплывающем окне. Недавно я конвертировал этот код в Swift и попытался использовать ленивую инициализацию следующим образом:

lazy var secondaryNavigationController: UINavigationController = {
    let navController = UINavigationController(rootViewController: menuView)
    navController.modalPresentationStyle = .popover
    navController.popoverPresentationController?.barButtonItem = menuButton
    return navController
}()

Обратите внимание, что menuView и menuButton также лениво инициализируются

Затем я попытался представить вид следующим образом:

@objc private func openMenu() {
    if UIDevice.current.userInterfaceIdiom == .pad {
        present(secondaryNavigationController, animated: true, completion: nil)
    } else {
        navigationController?.pushViewController(menuView, animated: true)
    }
}

При первом открытии меню все работает нормально, меню отображается так, как ожидалось. Однако, если я закрываю меню, нажимая на другую область экрана, а затем пытаюсь открыть его второй раз, я получаю следующий сбой:

UIPopoverPresentationController () должен иметь не ноль sourceView или barButtonItem. до презентации.

Эта ошибка исчезнет, ​​если я внесу следующее изменение в функцию openMenu():

@objc private func openMenu() {
    if UIDevice.current.userInterfaceIdiom == .pad {
        secondaryNavigationController.popoverPresentationController?.barButtonItem = menuButton // hurrah!
        present(secondaryNavigationController, animated: true, completion: nil)
    } else {
        navigationController?.pushViewController(menuView, animated: true)
    }
}

Так что исправление выше необходимо? Я упускаю что-то очевидное, что позволило бы установить его в блоке отложенной инициализации?


(Crash Log из примера проекта)

2018-06-29 21: 13: 09.836061 + 0100 PopoverBugExample [90568: 1465443] * Завершение приложения из-за необработанного исключения «NSGenericException», причина: 'UIPopoverPresentationController () должен иметь отличный от нуля sourceView или barButtonItem, установленный перед презентацией происходит.' * Стек первого вызова вызова: (0 CoreFoundation 0x0000000110c4b7f6 exceptionPreprocess + 294 1 libobjc.A.dylib
0x000000010f2a3035 objc_exception_throw + 48 2 UIKitCore
0x0000000113323a0e - [UIPopoverPresentationController presentationTransitionWillBegin] + 3168 3 UIKitCore
0x000000011332d568 __71- [UIPresentationController _initViewHierarchyForPresentationSuperview:] _ block_invoke + 2495 4 UIKitCore 0x000000011332ab5c __56- [UIPresentationController runTransitionForCurrentState] _block_invoke + 468 5 UIKitCore
0x0000000112fd8965 _runAfterCACommitDeferredBlocks + 318 6
UIKitCore 0x0000000112fc77d3 _cleanUpAfterCAFlushAndRunDeferredBlocks + 397 7 UIKitCore 0x0000000112ff7131 _afterCACommitHandler + 141 8 CoreFoundation
0x0000000110baee97 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION
+ 23 9 CoreFoundation 0x0000000110ba92ce __CFRunLoopDoObservers + 430 10 CoreFoundation 0x0000000110ba9971 __CFRunLoopRun + 1553 11 CoreFoundation
0x0000000110ba9021 CFRunLoopRunSpecific + 625 12 графических сервисов
0x000000011825c16e GSEventRunModal + 62 13 UIKitCore
0x0000000112fcd3ff UIApplicationMain + 140 14 PopoverBugExample
0x000000010e97c857 main + 71 15 libdyld.dylib
0x00000001120dce61 start + 1 16 ???
0x0000000000000001 0x0 + 1) libc ++ abi.dylib: заканчивается необработанное исключение типа NSException

...