2014-10-04 11 views
8

Ho sviluppato un'app per iOS7 e ora sto provando ad aggiornarla per iOS8. Il problema è il seguente:IOS8 come spostare un popover attivo

L'orientamento dello schermo dell'app può essere ruotato e in alcuni casi alcuni pulsanti si spostano drasticamente. Ho alcuni popover che puntano a questi pulsanti, quindi se un popover è aperto quando lo schermo ruota, il pulsante si sposta, ho bisogno anche del popover.

In iOS7 Ho fatto questo seguenti: Quando schermo ruotata ho aggiornato i vincoli

- (void) updateViewConstraints 
{ 
    if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) 
    { 
     self.Button.constant = (CGFloat)10; 
    } 
    else 
    { 
     self.Button.constant = (CGFloat)5; 
    } 
    [super updateViewConstraints]; 
} 

Ho anche spostare il popover

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{ 

    if(TempDisplayPopoverController == examplePopoverController) 
    { 
     [examplePopoverController presentPopoverFromRect:[self ExamplePopoverPosition] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 
    } 
} 

inizialmente carico la popover

- (void) LoadPopover{ 
    examplePopover = [[examplep alloc] initWithNibName:@"exampleP" bundle:nil]; 
    [examplePopover setDelegate:self]; 
    examplePopoverController = [[UIPopoverController alloc] initWithContentViewController: examplePopover]; 
    [examplePopoverController setDelegate:self]; 

    examplePopoverController.popoverContentSize = examplePopover.view.frame.size; 

    TempDisplayPopoverController = examplePopoverController; 


    if ([examplePopoverController isPopoverVisible]) 
    { 
     [examplePopoverController dismissPopoverAnimated:YES]; 
    } 
    else 
    { 
     [examplePopoverController presentPopoverFromRect:[self ExamplePopoverPosition] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 
    } 
} 

[self ExamplePopoverPosition] restituisce semplicemente la posizione del pulsante.

Questo ha funzionato tutto bene, ero felice, iPad era felice e si sono comportati tutti.

Ora a causa di iOS8 devo cambiare alcuni bit.

self.interfaceOrientation è ammortizzata

[examplePopoverController presentPopoverFromRect:[self ExamplePopoverPosition] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

in didRotateFromInterfaceOrientation genera un errore

"Application tried to represent an active popover presentation: <UIPopoverPresentationController: 0x7bf59280>"

Sono riuscito a rimediare self.interfaceOrientation da

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 
{ 
    [self SetUpScreen:toInterfaceOrientation]; 
} 

- (void) SetUpScreen:(UIInterfaceOrientation)toInterfaceOrientation{ 
    if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || 
     toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) 
    { 
     self.Button.constant = (CGFloat)10; 
    } 
    else 
    { 
     self.Button.constant = (CGFloat)5; 
    } 
    [super updateViewConstraints]; 
} 

ma non hanno idea di come risolvere il problema del popover. Ho provato

popoverController: willRepositionPopoverToRect: inView: 

ma proprio non riesco a sembrare farlo funzionare.

chiunque può consigli

Grazie

+0

stesso problema qui. Dobbiamo chiedere ad Apple ... – giuseppe

+0

Ciao, non ho ancora risolto questo <(concesso stato un po 'distratto con qualcos'altro però) –

+0

Qualche aggiornamento su questo? Ho lo stesso problema –

risposta

1

Quando si utilizza popoverController:willRepositionPopoverToRect:inView:, quando riassegnazione al parametro rect, provare a utilizzare:

*rect = myNewRect; 

e non:

rect = &presentingRect; 

Inoltre, assicurarsi sicuro di aver assegnato correttamente il pop delegato del controllore.

4

In iOS 8 è possibile utilizzare -viewWillTransitionToSize:withTransitionCoordinator: per gestire le dimensioni dello schermo (ed orientamento) cambiamenti:

- (void)viewWillTransitionToSize:(CGSize)size 
     withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator 
{ 
    [_popover dismissPopoverAnimated:NO]; 
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) { 
     // Update your layout for the new size, if necessary. 
     // Compare size.width and size.height to see if you're in landscape or portrait. 
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) { 
     [_popover presentPopoverFromRect:[self popoverFrame] 
            inView:self.view 
       permittedArrowDirections:UIPopoverArrowDirectionAny 
           animated:NO]; 
    }]; 
} 

Quando si implementa questo metodo, non saranno chiamati i metodi di rotazione obsoleti come willAnimateRotationToInterfaceOrientation: durante l'esecuzione su iOS 8.

-1

Molto interessante - Ho ottenuto questo per funzionare senza aggiornare la posizione manualmente. Non so perché questo funziona però.

let buttonContainer = UIView(frame: CGRectMake(0, 0, 44, 44)) 
let button = UIButton(frame: CGRectMake(0, 0, 44, 44)) 
buttonContainer.addSubview(button) 
view.addSubview(buttonContainer) 

popover!.presentPopoverFromRect(button, inView: button.superview!, permittedArrowDirections: .Any, animated: true) 

Inserire il pulsante che il popover presenta all'interno di una "vista contenitore". Quindi il popover sarà automaticamente regolare la posizione al cambio di orientamento.

+0

Prova prima questa soluzione giù voto. So che sembra pazzesco, ma funziona per me. –

0

In primo luogo, non è necessario chiudere e presentare il popover a rotazione. UIPopoverPresentationController lo fa per te. Non è nemmeno necessario aggiornare sourceView/sourceRect dopo aver impostato la creazione del popover.

Ora, il trucco con animate(alongsideTransition: ((UIViewControllerTransitionCoordinatorContext) -> Void)?, completion: ((UIViewControllerTransitionCoordinatorContext) -> Void)? = nil) è che è necessario aggiornare i vincoli nella chiusura alongsideTransition, non in completion. In questo modo si garantisce che UIPopoverPresentationController abbia il sourceRect aggiornato quando si ripristina il popover alla fine della rotazione.

Ciò che potrebbe sembrare contro-intuitivo è che all'interno della chiusura alongsideTransition si dispone già del nuovo layout da cui si ricava il calcolo dei vincoli.

Ecco un esempio a Swift:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 
    super.viewWillTransition(to: size, with: coordinator) 
    coordinator.animate(alongsideTransition: { _ in 
     if self.popover != nil { 
      // optionally scroll to popover source rect, if inside scroll view 
      let rect = ... 
      self.scrollView.scrollRectToVisible(rect, animated: false) 

      // update source rect constraints 
      myConstraint.constant = ... 
      myConstrainedView.setNeedsLayout() 
      myConstrainedView.layoutIfNeeded() 
     } 
    }, completion: nil) 
} 
Problemi correlati