2014-10-04 14 views
8

Opracowałem aplikację na iOS7, a teraz próbuję zaktualizować ją na iOS8. Problem jest następujący:IOS8, jak przenieść aktywny popover

Orientację ekranu aplikacji można obracać, a kilka przycisków w niektórych przypadkach porusza się drastycznie. Mam kilka popoverów wskazujących na te przyciski, więc jeśli popover jest otwarty po obróceniu ekranu, przycisk się porusza, potrzebuję również popover.

W iOS7 Robiłam to przez następujące: Kiedy ekran obracany zaktualizowałem ograniczeń

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

ja też przesunąć popover

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{ 

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

początkowo załadować 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] po prostu zwraca pozycję przycisku.

To wszystko działało bez zarzutu, byłem szczęśliwy, iPad był szczęśliwy i wszyscy się zachowywali.

Teraz z powodu iOS8 muszę zmienić kilka bitów.

self.interfaceOrientation amortyzuje

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

w didRotateFromInterfaceOrientation zgłasza błąd

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

udało mi się naprawić self.interfaceOrientation przez

- (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]; 
} 

, ale nie mają pojęcia, jak rozwiązać problem z popover. Próbowałem już raz, ale nie mogę sprawić, żeby działało.

może ktoś rada

Dzięki

+0

sam problem tutaj. Musimy zapytać Apple ... – giuseppe

+0

cześć, nadal nie rozwiązałem tego <(przy czym nieco rozproszony z czymś innym) –

+0

Wszelkie aktualizacje na ten temat? Mam ten sam problem, –

Odpowiedz

1

Podczas korzystania popoverController:willRepositionPopoverToRect:inView:, gdy realokacja do parametru rect, spróbuj:

*rect = myNewRect; 

a nie:

rect = &presentingRect; 

również zrobić na pewno poprawnie przypisałeś pop nad delegatem kontrolera.

4

w iOS 8 można użyć -viewWillTransitionToSize:withTransitionCoordinator: obsłużyć rozmiar ekranu (i orientacji) zmiany:

- (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]; 
    }]; 
} 

Podczas realizacji tej metody, przestarzałe metody rotacji jak willAnimateRotationToInterfaceOrientation: nie zostanie wywołana, gdy działa na iOS 8.

-1

Bardzo interesujące - mam to do pracy bez aktualizowania pozycji ręcznie. Nie wiem, dlaczego to działa.

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) 

Umieść przycisk wyświetlany w okienku "widok kontenera". Następnie popover będzie automatycznie dostosowywać położenie po zmianie orientacji.

+0

Proszę wypróbować to rozwiązanie wcześniej głosowanie w dół. Wiem, że to brzmi szalenie, ale to działa dla mnie. –

0

Po pierwsze, nie musisz odrzucać i pokazywać popover podczas obracania. UIPopoverPresentationController robi to za Ciebie. Nie musisz nawet aktualizować sourceView/sourceRect, gdy są ustawione na tworzenie popover.

Teraz sztuczka z animate(alongsideTransition: ((UIViewControllerTransitionCoordinatorContext) -> Void)?, completion: ((UIViewControllerTransitionCoordinatorContext) -> Void)? = nil) polega na tym, że należy zaktualizować ograniczenia w alongsideTransition zamknięcia, a nie w completion. W ten sposób upewnisz się, że UIPopoverPresentationController ma zaktualizowany sourceRect podczas przywracania popover na końcu rotacji.

To, co może wydawać się sprzeczne z intuicją, polega na tym, że w zamknięciu alongsideTransition masz już swój nowy układ, z którego czerpiesz kalkulacje ograniczeń.

Oto przykład w 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) 
}