¿Cómo evitar el presente modally un controller activo?

Tenemos 2 controlleres: MainVC y ProfileVC. Desde MainVC vamos a ProfileVC con profileButton (elemento izquierdo en la barra de navigation).

En Profile VC tenemos 2 botones en la barra de navigation: volver a principal (leftItem) y abrir un alertView (rightItem).

Por lo tanto, hay una testing KIF simple (solo pulsaciones eternas de izquierda a derecha en la barra de navigation):

 - (void)testProfileButtons { [tester waitForAnimationsToFinishWithTimeout:0.3]; while (true) { [tester tapScreenAtPoint:CGPointMake(20, 20)]; [tester waitForTimeInterval:0.1]; [tester tapScreenAtPoint:CGPointMake(380, 20)]; [tester waitForTimeInterval:0.1]; [tester tapScreenAtPoint:CGPointMake(20, 20)]; [tester waitForTimeInterval:0.1]; } } 

Se bloquea la aplicación con error:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <UINavigationController: 0x7fe862ef82d0>.'

 *** First throw call stack: ( 0 CoreFoundation 0x0000000110944c65 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x00000001105dabb7 objc_exception_throw + 45 2 UIKit 0x000000010f44b80d -[UIViewController _presentViewController:withAnimationController:completion:] + 3238 3 UIKit 0x000000010f44d6c1 __62-[UIViewController presentViewController:animated:completion:]_block_invoke + 132 4 UIKit 0x000000010fa5e5ae -[_UIViewControllerTransitionCoordinator _applyBlocks:releaseBlocks:] + 217 5 UIKit 0x000000010fa5b8e5 -[_UIViewControllerTransitionContext _runAlongsideCompletions] + 123 6 UIKit 0x000000010fa5b670 -[_UIViewControllerTransitionContext completeTransition:] + 126 7 UIKit 0x000000010f2fe8a6 __53-[_UINavigationParallaxTransition animateTransition:]_block_invoke93 + 687 8 UIKit 0x000000010f387193 -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 326 9 UIKit 0x000000010f36e0f6 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 209 10 UIKit 0x000000010f36e42c -[UIViewAnimationState animationDidStop:finished:] + 76 11 UIKit 0x000000011daf3fdf -[UIViewAnimationStateAccessibility animationDidStop:finished:] + 48 12 QuartzCore 0x000000010f03e892 _ZN2CA5Layer23run_animation_callbacksEPv + 308 13 libdispatch.dylib 0x0000000111c67964 _dispatch_client_callout + 8 14 libdispatch.dylib 0x0000000111c52a59 _dispatch_main_queue_callback_4CF + 704 15 CoreFoundation 0x00000001108ac1f9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9 16 CoreFoundation 0x000000011086ddcb __CFRunLoopRun + 2043 17 CoreFoundation 0x000000011086d366 CFRunLoopRunSpecific + 470 18 TurboChat UI Tests 0x000000011b73ef69 -[KIFTestActor tryRunningBlock:complete:timeout:error:] + 425 19 TurboChat UI Tests 0x000000011b73f179 -[KIFTestActor runBlock:complete:timeout:] + 137 20 TurboChat UI Tests 0x000000011b73f304 -[KIFTestActor runBlock:timeout:] + 84 21 TurboChat UI Tests 0x000000011b73f73e -[KIFTestActor waitForTimeInterval:] + 174 22 TurboChat UI Tests 0x000000011b73c2ad -[TCProfileButtonsTest testProfileButtons] + 909 23 CoreFoundation 0x000000011083adec __invoking___ + 140 24 CoreFoundation 0x000000011083ac42 -[NSInvocation invoke] + 290 25 XCTest 0x000000011b79217a -[XCTestCase invokeTest] + 253 26 XCTest 0x000000011b792379 -[XCTestCase performTest:] + 150 27 XCTest 0x000000011b79bc35 -[XCTest run] + 260 28 XCTest 0x000000011b79108b -[XCTestSuite performTest:] + 379 29 XCTest 0x000000011b79bc35 -[XCTest run] + 260 30 XCTest 0x000000011b79108b -[XCTestSuite performTest:] + 379 31 XCTest 0x000000011b79bc35 -[XCTest run] + 260 32 XCTest 0x000000011b79108b -[XCTestSuite performTest:] + 379 33 XCTest 0x000000011b79bc35 -[XCTest run] + 260 34 XCTest 0x000000011b78e129 __25-[XCTestDriver _runSuite]_block_invoke + 56 35 XCTest 0x000000011b798edd -[XCTestObservationCenter _observeTestExecutionForBlock:] + 162 36 XCTest 0x000000011b78e060 -[XCTestDriver _runSuite] + 269 37 XCTest 0x000000011b78ea8d -[XCTestDriver _checkForTestManager] + 234 38 XCTest 0x000000011b79eb20 +[XCTestProbe runTests:] + 182 39 Foundation 0x000000010e5f21e5 __NSFireDelayedPerform + 387 40 CoreFoundation 0x00000001108ac174 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20 41 CoreFoundation 0x00000001108abd35 __CFRunLoopDoTimer + 1045 42 CoreFoundation 0x000000011086dd3d __CFRunLoopRun + 1901 43 CoreFoundation 0x000000011086d366 CFRunLoopRunSpecific + 470 44 GraphicsServices 0x00000001123a8a3e GSEventRunModal + 161 45 UIKit 0x000000010f30e8c0 UIApplicationMain + 1282 46 TurboChat 0x000000010cd1e75f main + 111 47 libdyld.dylib 0x0000000111c97145 start + 1 ) 

También obtengo esto al probar en un dispositivo real:

 Presenting view controllers on detached view controllers is discouraged <TCProfileTableViewController: 0x14f6299c0>. 

y obteniendo alertView apareciendo sobre MainVC en lugar ProfileVC con pantalla negra debajo.

Así es como presentamos la alerta en ProfileVC:

 - (IBAction)menuButtonPressed:(id)sender { [self.navigationController presentViewController:self.menuAlert animated:YES completion:nil]; } 

AlertView:

 self.menuAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"%@?", NSLocalizedString(@"PROFILE_BTN_MENU", nil)] message:nil prefernetworkingStyle:UIAlertControllerStyleActionSheet]; 

¿Alguna sugerencia?

Creo que tendrás que descartar primero el controller de vista LAST antes de volver por el modo de segue actual, el control de visualización está activo, por lo que falla:

Use este segue after call segue from mainVC o algo que desee volver:

 [self dismissViewControllerAnimated:NO completion:nil] 

o

 [[self presentingViewController] dismissViewControllerAnimated:NO completion:nil] 

o use push segue, agrega automáticamente un button de retroceso que automáticamente agrega function de retroceso

He encontrado una especie de solución para esto

 - (IBAction)menuButtonPressed:(id)sender { [self.parentViewController presentViewController:self.menuAlert animated:YES completion:nil]; } 

La vista de alerta a veces aparece en menuVC, pero no falla la aplicación y funciona normalmente. La respuesta se encontró allí: Advertencia: se desaconseja la presentación de controlleres de vista en controlleres de vista desconectados