[ios] 내비게이션 컨트롤러가 내장 된 팝 오버는 백 내비게이션의 크기를 고려하지 않습니다.

뷰 컨트롤러의 작은 계층 구조를 포함하는 UINavigationController를 호스팅하는 UIPopoverController가 있습니다.

문서를 따랐고 각 뷰 컨트롤러에 대해 뷰의 팝 오버 컨텍스트 크기를 다음과 같이 설정했습니다.

[self setContentSizeForViewInPopover:CGSizeMake(320, 500)];

(컨트롤러마다 크기가 다름)

이것은 계층에서 앞으로 이동할 때 예상대로 작동합니다. 팝 오버는 푸시 된 컨트롤러에 따라 크기 변경을 자동으로 애니메이션합니다.

그러나 내비게이션 바의 뒤로 버튼을 통해 뷰 스택을 통해 “뒤로”를 탐색 할 때 팝 오버는 크기가 변경되지 않고 가장 깊은 뷰에 도달 한만큼 커집니다. 이것은 나에게 깨진 것 같습니다. 팝업이 뷰 스택을 통해 팝업 될 때 설정된 크기를 존중할 것으로 기대합니다.

내가 뭔가를 놓치고 있습니까?

감사.



답변

좋아, 나는 같은 문제로 어려움을 겪고 있었다. 위의 솔루션 중 어느 것도 나를 위해 잘 작동하지 않았기 때문에 약간의 조사를 수행하고 이것이 어떻게 작동하는지 알아보기로 결정했습니다. 이것이 내가 발견 한 것입니다.-당신이contentSizeForViewInPopover뷰 컨트롤러에서는 다른 컨트롤러로 이동하는 동안 팝 오버 크기가 변경 될 수 있지만 팝 오버 자체에 의해 변경되지 않습니다. -다른 컨트롤러로 이동하는 동안 팝 오버의 크기가 변경 될 때, 되돌아가는 동안 팝 오버의 크기는 복원되지 않습니다.-viewWillAppear에서 팝 오버의 크기를 변경하면 매우 이상한 애니메이션이 나타납니다. 나는 그것을 권장하지 않습니다-컨트롤러 내부에 하드 코딩 된 크기를 설정하는 것은 전혀 작동하지 않을 것입니다. 내 컨트롤러는 때때로 크고 때로는 작을 것입니다.

이 모든 고통에 대한 해결책은 다음과 같습니다. currentSetSizeForPopoverviewDidAppear에서 의 크기를 재설정해야합니다 . 하지만주의해야합니다. 필드에 이미 설정된 것과 같은 크기를 설정 currentSetSizeForPopover하면 팝 오버가 크기를 변경하지 않습니다. 이를 위해 먼저 가짜 크기 (이전에 설정된 것과 다를 것임)를 설정 한 다음 적절한 크기를 설정할 수 있습니다. 이 솔루션은 컨트롤러가 내비게이션 컨트롤러 내부에 중첩되어 있어도 작동하며 컨트롤러 사이를 다시 탐색 할 때 그에 따라 팝 오버의 크기가 변경됩니다.

크기를 설정하는 트릭을 수행하는 다음 도우미 메서드를 사용하여 UIViewController에 범주를 쉽게 만들 수 있습니다.


- (void) forcePopoverSize {
    CGSize currentSetSizeForPopover = self.contentSizeForViewInPopover;
    CGSize fakeMomentarySize = CGSizeMake(currentSetSizeForPopover.width - 1.0f, currentSetSizeForPopover.height - 1.0f);
    self.contentSizeForViewInPopover = fakeMomentarySize;
    self.contentSizeForViewInPopover = currentSetSizeForPopover;
}

그런 다음 -viewDidAppear원하는 컨트롤러 에서 호출하십시오 .


답변

iOS 7 및 8에서 해결 한 방법은 다음과 같습니다.

iOS 8에서 iOS는 popover에서 원하는 뷰를 presentingViewController 뷰 컨트롤러의 presentViewController로 자동 래핑합니다. popovercontroller의 새로운 기능을 설명하는 2014 년 WWDC 비디오가 있습니다.

어쨌든, 모두 자체 크기 조정을 원하는 탐색 컨트롤러 스택에 표시되는 뷰 컨트롤러의 경우 이러한 뷰 컨트롤러는이 코드를 호출하여 (iOS 8에서) preferredContentSize를 동적으로 설정해야합니다.

self.presentingViewController.presentedViewController.preferredContentSize = CGSizeMake(320, heightOfTable);

heightOfTable을 계산 된 테이블 또는 뷰 높이로 바꿉니다.

많은 중복 코드를 방지하고 일반적인 iOS 7 및 iOS 8 솔루션을 만들기 위해 UITableViewController에 범주를 만들어 viewDidAppear가 테이블 뷰에서 호출 될 때이 작업을 수행합니다.

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self setPopOverViewContentSize];
}

Category.h :

#import <UIKit/UIKit.h>

@interface UITableViewController (PreferredContentSize)

- (void) setPopOverViewContentSize;

@end

Category.m :

#import "Category.h"

@implementation UITableViewController (PreferredContentSize)

- (void) setPopOverViewContentSize
{
    [self.tableView layoutIfNeeded];
    int heightOfTable = [self.tableView contentSize].height;

    if (heightOfTable > 600)
        heightOfTable = 600;

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0)
            self.preferredContentSize=CGSizeMake(320, heightOfTable);
        else
            self.presentingViewController.presentedViewController.preferredContentSize = CGSizeMake(320, heightOfTable);
    }
}

@end


답변

이것은 krasnyk 의 대답 에 대한 개선입니다 .

솔루션은 훌륭하지만 매끄럽게 애니메이션되지는 않습니다.
약간의 개선은 멋진 애니메이션을 제공

합니다. - (void) forcePopoverSize메서드의 마지막 줄을 제거합니다 .

- (void) forcePopoverSize {
    CGSize currentSetSizeForPopover = self.contentSizeForViewInPopover;
    CGSize fakeMomentarySize = CGSizeMake(currentSetSizeForPopover.width - 1.0f, currentSetSizeForPopover.height - 1.0f);
    self.contentSizeForViewInPopover = fakeMomentarySize;
}

- (void)viewWillAppear:(BOOL)animated메소드에 [self forcePopoverSize]를 넣으십시오 .

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self forcePopoverSize];
}

마지막으로 - (void)viewDidAppear:(BOOL)animated방법 에서 원하는 크기를 설정하십시오 .

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    CGSize currentSetSizeForPopover = self.contentSizeForViewInPopover;
    self.contentSizeForViewInPopover = currentSetSizeForPopover;
}


답변

에서 콘텐츠 크기를 다시 설정해야합니다 viewWillAppear. popovercontroller의 크기를 설정하는 delagate 메서드를 호출합니다. 나도 같은 문제가 있었다. 그러나 이것을 추가하면 문제가 해결되었습니다.

한 가지 더 : 5 미만의 베타 버전을 사용하는 경우 팝 오버를 관리하기가 더 어려워집니다. 베타 버전 5에서 더 친근한 것 같습니다. 최종 버전이 나간 것이 좋습니다. 😉

도움이 되었기를 바랍니다.


답변

에서 -(void)viewDidLoad당신이 탐색 컨트롤러에서 사용하는 모든 뷰 컨트롤러, 추가 :

[self setContentSizeForViewInPopover:CGSizeMake(320, 500)];


답변

다시 탐색되는 뷰 컨트롤러의 viewWillDisappear : (BOOL) animated 메서드에서 크기를 재설정합니다.

-(void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    CGSize contentSize = [self contentSizeForViewInPopover];
    contentSize.height = 0.0;
    self.contentSizeForViewInPopover = contentSize;
}

그런 다음 다시 탐색중인보기가 나타나면 크기를 적절하게 재설정합니다.

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    CGSize contentSize;
    contentSize.width = self.contentSizeForViewInPopover.width;
    contentSize.height = [[self.fetchedResultsController fetchedObjects] count] *  self.tableView.rowHeight;
    self.contentSizeForViewInPopover = contentSize;
}


답변

iOS 8의 경우 다음이 작동합니다.

- (void) forcePopoverSize {
    CGSize currentSetSizeForPopover = self.preferredContentSize;
    CGSize fakeMomentarySize = CGSizeMake(currentSetSizeForPopover.width - 1.0f, currentSetSizeForPopover.height - 1.0f);
    self.preferredContentSize = fakeMomentarySize;
    self.navigationController.preferredContentSize = fakeMomentarySize;
    self.preferredContentSize = currentSetSizeForPopover;
    self.navigationController.preferredContentSize = currentSetSizeForPopover;
}

BTW 나는 이것이 이전 iOS 버전과 호환되어야한다고 생각합니다 …