2014-09-11 11 views
12

Die setContentViewController-Methode in UIPopoverController scheint einen Absturz in iOS 8 zu verursachen. Ich frage mich, ob jemand anderes auch dieses Problem in iOS 8 konfrontiert. Dies funktioniert ohne Probleme in iOS 7.setContentViewController-Methode im Popover iOS8 verursacht App-Absturz

der Fehler in der Ausnahme wies scheint irreführend zu sein, wie es heißt, dass die setContentViewController sollte nach Vorlage der popover

- (void)buttonPressed { 

UIViewController *tableViewController = [UIViewController new]; 

if(_popover == nil){ 

    _popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController]; 

    [_popover presentPopoverFromRect:CGRectMake(self.textField.frame.size.width/2, self.textField.frame.size.height/1, 1, 1) inView:self.textField permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES]; 
}else{ 
    [_popover setContentViewController:tableViewController]; 
}  

}

Hier ist Stack-Trace von der heißen Absturz,

2014-09-11 16:48:39.904 iOS 8 Rotation[3969:67869] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIPopoverController setContentViewController:animated:] can only be called after the popover has been presented.' 
*** First throw call stack: 
(
    0 CoreFoundation      0x01c79df6 __exceptionPreprocess + 182 
    1 libobjc.A.dylib      0x01903a97 objc_exception_throw + 44 
    2 CoreFoundation      0x01c79d1d +[NSException raise:format:] + 141 
    3 UIKit        0x00b1946f -[UIPopoverPresentationController _setContentViewController:animated:] + 89 
    4 UIKit        0x009bb1b4 -[UIPopoverController setContentViewController:animated:] + 155 
    5 UIKit        0x009bb114 -[UIPopoverController setContentViewController:] + 48 
    6 iOS 8 Rotation      0x00046ca5 -[MianViewController buttonPressed] + 933 
    7 libobjc.A.dylib      0x019197cd -[NSObject performSelector:withObject:withObject:] + 84 
    8 UIKit        0x002ef79d -[UIApplication sendAction:to:from:forEvent:] + 99 
    9 UIKit        0x002ef72f -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64 
    10 UIKit        0x00422a16 -[UIControl sendAction:to:forEvent:] + 69 
    11 UIKit        0x00422e33 -[UIControl _sendActionsForEvents:withEvent:] + 598 
    12 UIKit        0x0042209d -[UIControl touchesEnded:withEvent:] + 660 
    13 UIKit        0x0033faba -[UIWindow _sendTouchesForEvent:] + 874 
    14 UIKit        0x00340595 -[UIWindow sendEvent:] + 791 
    15 UIKit        0x00305aa9 -[UIApplication sendEvent:] + 242 
    16 UIKit        0x003158de _UIApplicationHandleEventFromQueueEvent + 20690 
    17 UIKit        0x002ea079 _UIApplicationHandleEventQueue + 2206 
    18 CoreFoundation      0x01b9d7bf __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15 
    19 CoreFoundation      0x01b932cd __CFRunLoopDoSources0 + 253 
    20 CoreFoundation      0x01b92828 __CFRunLoopRun + 952 
    21 CoreFoundation      0x01b921ab CFRunLoopRunSpecific + 443 
    22 CoreFoundation      0x01b91fdb CFRunLoopRunInMode + 123 
    23 GraphicsServices     0x040cc24f GSEventRunModal + 192 
    24 GraphicsServices     0x040cc08c GSEventRun + 104 
    25 UIKit        0x002ede16 UIApplicationMain + 1526 
    26 iOS 8 Rotation      0x0004774d main + 141 
    27 libdyld.dylib      0x0224cac9 start + 1 
    28 ???         0x00000001 0x0 + 1 
) 
libc++abi.dylib: terminating with uncaught exception of type NSException 
+0

** Immer ** einen Initialisierer aufrufen! 'UIViewController * tableViewController = [UIViewController Alloc];' ist falsch, es muss '[[UIViewController Alloc] init]' oder '[[UIViewController Alloc] initWithNibName: @" SomeNibName "Bündel: nil]' sein. Da jedoch ein generischer, leerer View-Controller nutzlos ist, möchten Sie stattdessen eine benutzerdefinierte View-Controller-Subklasse instanziieren. – DarkDust

+0

Einverstanden, geändert zu [UIViewController new] – Padmika

+0

gleich hier. Ich stelle das Popover nicht jedes Mal neu her, wenn ich es präsentieren muss, also präsentiere ich es einfach. aber es verursacht zufällige Abstürze. Ich bin wirklich in einer festen ... was zu tun ist –

Antwort

4

mir diese gleichen Fehler testen unsere App unter iOS 8. In unserem Fall nur begegnet, habe ich die Fehlermeldung mit dem Nennwert und geändert, um ein Muster, das wir an einigen Stellen hatten.

Das Muster, das wir ändern mussten, war: (1) in unserer Sicht Controller-Init, instanziieren Sie eine Popover-Controller-Instanz. (2) Bei einem Ereignis setzen Sie die Eigenschaft contentViewController des Popover-Controllers auf die gewünschte vc. (3) rufen presentPopoverFromRect auf dem popover Controller

und wir einfach Schritt geändert (2) erneut instanziiert die popover Controller mit dem gewünschten Inhalt vc als Init-Parameter und beendet die contentViewController-Eigenschaft (wie wir sind immer tun, bevor Sie das Popover präsentieren).

0

Ich hatte das gleiche Problem und das ist, was es für mich behoben.

Probieren Sie diese

- (void)buttonPressed{ 

    UIViewController *tableViewController = [UIViewController new]; 

    //Check if the popover is nil or not visible 
    if(_popover == nil || _popover.popoverVisible == false){ 

    _popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController]; 

    [_popover presentPopoverFromRect:CGRectMake(self.textField.frame.size.width/2, self.textField.frame.size.height/1, 1, 1) inView:self.textField permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES]; 
    }else{ 
    [_popover setContentViewController:tableViewController]; 
    } 
} 
+0

Diese Methode funktioniert nicht auf ios8 – Emmy

3

ich das gleiche Problem wurde erlebt und schließlich löste es.

Ich habe zwei Tasten, jeder zeigt seinen eigenen Popover. Ich benutzte den gleichen UIPopoverController, um beide zu zeigen. Der erste Klick hat gut funktioniert, aber wenn du auf den anderen geklickt hast, ist die App abgestürzt.

So wie ich es gelöst ist, ein neues UIPopoverController auf jeden Klick erstellen:

importImagePickerControlPopoverController=[[UIPopoverController alloc] initWithContentViewController:pickerController]; 
[importImagePickerControlPopoverController setDelegate:self]; 

switch(pickerType) 
{ 
    case UIImagePickerControllerSourceTypePhotoLibrary: 
    case UIImagePickerControllerSourceTypeSavedPhotosAlbum: 
     [importImagePickerControlPopoverController setPopoverContentSize:CGSizeMake(320, 300) animated:YES]; 
     break; 
    case UIImagePickerControllerSourceTypeCamera: 
     [importImagePickerControlPopoverController setPopoverContentSize:CGSizeMake(640, 640) animated:YES]; 
     break; 
} 
[importImagePickerControlPopoverController setContentViewController:pickerController]; 
0

Fügen Sie diese beiden Methoden in Ihre UIWebview Hauptklasse. fügen Sie <UIPopoverPresentationControllerDelegate> in Ihrer webview interface.h Klasse hinzu. definieren.

@property (strong, nonatomic) UIPopoverPresentationController *pop; 

dann

@synthesize pop; 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    // Assuming you've hooked this all up in a Storyboard with a popover presentation style 
    if ([segue.identifier isEqualToString:@"showPopover"]) { 
     UINavigationController *destNav = segue.destinationViewController; 
     pop = destNav.viewControllers.firstObject; 

     // This is the important part 
     UIPopoverPresentationController *popPC = destNav.popoverPresentationController; 
     popPC.delegate = self; 
    } 
} 
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller { 
    return UIModalPresentationNone; 
} 
2

Ähnlich @ user3495742 Lösung:

-(void)testAndSetPopoverWithVc:(UIViewController*)vc { 
    if (popover4Menu) { 
     if ([popover4Menu isPopoverVisible]) { 
      [popover4Menu setContentViewController:vc animated:YES]; 
      return; 
     } else { 
      popover4Menu=nil; 
     } 
    }; 
    popover4Menu=[[UIPopoverController alloc] initWithContentViewController:vc]; 
    popover4Menu.delegate=self; 
} 

Problem steigt, wenn ein View-Controller zu einem bestehenden popover Neuzuordnung. Free und Realloc Popover vor dem Zuweisen neuer Content-View-Controller: das für mich behoben.

+2

Ciao Giorgio, diese Zeile popover4Menu = nil wird in einem Speicherleck/dangling Zeiger führen. Sie können den gleichen Effekt erzielen, indem Sie die synthetisierte Eigenschaft ausnutzen, die den Retain-Zähler auf Null setzt und den Popover korrekt freigibt. – johndpope

+0

Danke @johnpope, ich habe diesen Hinweis gewählt. In meiner Implementierung ist popover4Menu eine private Variable der Klasse, keine Eigenschaft, also denke ich, dass ich es ARC nicht zuweisen kann, um die Zuweisung von Deallokationen zu verwalten, aber ich habe es noch nicht tief durchgecheckt. –

+0

Sie können sehen, indem Sie das Popover ableiten - dann überschreiben Sie die Dealloc-Methode (ohne Super Dealloc aufrufen) und setzen Sie dort einen Haltepunkt. Es sollte klar werden, wenn Sie die Variable auslassen - sie wird nicht korrekt aufgelöst. Durch das Setzen einer self.property = nil wird die Instanz korrekt freigegeben. – johndpope

0

Sie haben bereits den Inhalt View-Controller-Set haben:

_popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController]; 
                     ↑ 
                     Here 

Also, warum nicht nur die Zeile löschen ?:

[_popover setContentViewController:tableViewController]; 

Das sollte funktionieren.

0

Wenn Popover nicht angezeigt wird, wenn Sie [_popover setContentViewController:tableViewController]; aufrufen, wird die App abstürzen.

Da diese Methode aufgerufen werden sollte, wenn Popover auf dem Bildschirm sichtbar ist.

Stellen Sie sicher, popover sichtbar ist,

if(_popover != nil && [_popover isPopoverVisible] == YES) 
{ 
    [_popover setContentViewController:tableViewController]; 
}else 
{ 
     //create new popover object if _popover is nil or present it 
} 
0
[self.popover dismissPopoverAnimated:YES]; //in case it's already showing. 
    self.popover = nil; // N.B. this is not the same as popover = nil. 
    self.popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController]; 
    [self.popover presentPopoverFromRect:CGRectMake(self.textField.frame.size.width/
    2, self.textField.frame.size.height/1, 1, 1) inView:self.textField 
    permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES]; 
0

Sie brauchen keine neue Instanz von UIPopoverController zu schaffen weder setzen neue contentViewController Eigenschaft nach dem ersten vorhanden UIPopoverViewController. (es hängt davon ab, wie Sie Sie popoverController entlassen)

Jedoch contentViewController kann vor der Präsentation von popoverController nicht geändert werden.

Zur Problemumgehung überprüfen Sie popoverController.contentViewController Eigenschaften. Wenn es Null ist, conntentViewController setzen, sonst nur vorhanden Popover.

Wenn SiecontentViewController ändern tun sie nach der Präsentation: setContentViewController verwenden: animierte: Methode. Überprüfen Sie, dass popoverController.isPopoverVisible vor Aufruf dieser Methode.