89

View Controllerの小さな階層を含むUINavigationControllerをホストするUIPopoverControllerがあります。

私はドキュメントに従い、ビューコントローラーごとに、ビューのポップオーバーコンテキストサイズを次のように設定しました:

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

(コントローラーごとにサイズが異なります)

これは、階層を順方向にナビゲートするときに期待どおりに機能します。ポップオーバーは、プッシュされたコントローラーに対応するサイズの変更を自動的にアニメーション化します。

ただし、ナビゲーション バーの [戻る] ボタンを使用してビュー スタックを "戻る" に移動すると、ポップオーバーのサイズは変わりません。最も深いビューに到達したときと同じ大きさのままです。これは私には壊れているようです。ポップオーバーがビュースタックをポップするときに設定されたサイズを尊重することを期待しています。

何か不足していますか?

ありがとう。

4

21 に答える 21

95

私は同じ問題に苦しんでいました。上記の解決策はどれもうまく機能しませんでした。そのため、少し調査して、これがどのように機能するかを調べることにしました。

これは私が発見したものです:

  • ビュー コントローラーでを設定するcontentSizeForViewInPopoverと、ポップオーバー自体によって変更されることはありません。別のコントローラーに移動するときにポップオーバーのサイズが変更される場合があります。
  • 別のコントローラーに移動しているときにポップオーバーのサイズが変更され、戻るときにポップオーバーのサイズが復元されない
  • viewWillAppear でポップオーバーのサイズを変更すると、非常に奇妙なアニメーションが表示されます (ポップオーバー内で popController を使用するとします) - お勧めしません
  • 私にとって、コントローラー内のハードコードされたサイズの設定はまったく機能しません-コントローラーは時々大きく、時には小さくする必要があります-それらを提示するコントローラーはサイズについての考えを持っています

そのすべての痛みの解決策は次のとおりです。

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次に、目的のコントローラーで呼び出すだけです。

于 2011-02-17T18:17:29.017 に答える
19

iOS 7および8で解決した方法は次のとおりです。

iOS 8 では、iOS は、ポップオーバーに表示するビューを、presentingViewController ビュー コントローラーのpresentedViewController に静かにラップしています。popovercontroller の新機能について説明している 2014 WWDC ビデオがあります。

いずれにせよ、すべて独自のサイズ設定が必要なナビゲーション コントローラー スタックに表示されるビュー コントローラーの場合、これらのビュー コントローラーは (iOS 8 で) 次のコードを呼び出して、preferredContentSize を動的に設定する必要があります。

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

heightOfTable を、計算されたテーブルまたはビューの高さに置き換えます。

多くの重複コードを回避し、共通の iOS 7 および iOS 8 ソリューションを作成するために、テーブルビューで viewDidAppear が呼び出されたときにこの作業を実行するために、UITableViewController にカテゴリを作成しました。

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

カテゴリ.h:

#import <UIKit/UIKit.h>

@interface UITableViewController (PreferredContentSize)

- (void) setPopOverViewContentSize;

@end

カテゴリ.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
于 2014-11-17T02:59:45.247 に答える
12

これはkrasnykの回答の改善です。
あなたのソリューションは素晴らしいですが、スムーズにアニメーション化されていません。
少し改良すると素敵なアニメーションが得られます:メソッド

の最後の行を削除します:- (void) forcePopoverSize

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

[self forcePopoverSize] を- (void)viewWillAppear:(BOOL)animatedメソッドに入れます:

- (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;
}
于 2011-10-13T12:27:12.947 に答える
8

でコンテンツサイズを再設定する必要がありますviewWillAppear。popovercontrollerのサイズを設定するdelagateメソッドを呼び出す。私も同じ問題を抱えていました。しかし、これを追加すると、問題は解決しました。

もう1つ、5未満のベータバージョンを使用している場合、ポップオーバーの管理はより困難になります。ベータ版5からはより親しみやすいようです。最終版が出ているのは良いことです。;)

お役に立てれば。

于 2010-05-02T13:09:58.743 に答える
5

Navigation Controller で使用して-(void)viewDidLoadいるすべての View Controller に、以下を追加します。

[self setContentSizeForViewInPopover:CGSizeMake(320, 500)];
于 2012-09-11T04:39:16.860 に答える
3

次からナビゲートされているView Controllerの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;
}
于 2010-06-01T01:46:41.580 に答える
2

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

ところで、これは以前のiOSバージョンと互換性があるはずです...

于 2014-10-29T08:50:52.510 に答える
1

アサンブラーを想像できるなら、これは少し良いと思います:

- (無効) forcePopoverSize {
    CGSize currentSetSizeForPopover = self.contentSizeForViewInPopover;
    self.contentSizeForViewInPopover = CGSizeMake(0, 0);
    self.contentSizeForViewInPopover = currentSetSizeForPopover;
}
于 2012-09-30T04:30:26.950 に答える
1

受け入れられた答えは、iOS 8 ではうまく機能しません。私がしたことは、そのポップオーバーで使用する独自のサブクラスを作成しUINavigationControllerpreferredContentSizeこの方法でメソッドをオーバーライドすることでした。

- (CGSize)preferredContentSize {
    return [[self.viewControllers lastObject] preferredContentSize];
}

さらに、forcePopoverSize(@krasnyk によって実装されたメソッド)を呼び出す代わりにviewDidAppear、viewController (ポップオーバーを表示する) を前述のナビゲーション (ポップオーバー内) のデリゲートとして設定し、(force メソッドが行うこと) を実行することにしました。

-(void)navigationController:(UINavigationController *)navigationController
      didShowViewController:(UIViewController *)viewController 
                   animated:(BOOL)animated  

渡された のデリゲート メソッドviewController。重要なことの 1 つは、そのアニメーションをスムーズにする必要がない場合はforcePopoverSize、メソッドで実行しても問題ありません。UINavigationControllerDelegateviewDidAppear

于 2014-10-22T12:01:32.107 に答える
1

私にとって、このソリューションは機能します。これは、UITableViewController を拡張し、UINavigationController のルート コントローラーであるビュー コントローラーのメソッドです。

-(void)viewDidAppear:(BOOL)animated {
     [super viewDidAppear:animated];
     self.contentSizeForViewInPopover = self.tableView.bounds.size;
}

また、ナビゲーション スタックにプッシュするビュー コントローラーのコンテンツ サイズを設定することを忘れないでください。

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
    dc = [[DetailsController alloc] initWithBookmark:[[bookmarksArray objectAtIndex:indexPath.row] retain] bookmarkIsNew:NO];
    dc.detailsDelegate = self;
    dc.contentSizeForViewInPopover = self.contentSizeForViewInPopover;
    [self.navigationController pushViewController:dc animated:YES]; 
 }
于 2010-08-20T15:57:56.420 に答える
0

この問題は、最初にpopoverContentSize = CGSizeMake(320、600)のポップオーバーコントローラーで発生しましたが、ContentViewController(UINavigationController)をナビゲートすると大きくなります。

navコントローラーはカスタムUITableViewControllersをプッシュおよびポップするだけだったので、カスタムテーブルビューコントローラークラスのviewDidLoadでself.contentSizeForViewInPopover = CGSizeMake(320、556)を設定しました。

44ピクセル少ないピクセルは、Navコントローラーのナビゲーションバーを説明するためのものであり、今では問題はありません。

于 2013-02-04T21:52:32.363 に答える
0

同じ問題に直面し、UIPopoverController の初期化が配置される前にコンテンツ ビュー サイズをナビゲーション コントローラーとビュー コントローラーに設定することで修正しました。

     CGSize size = CGSizeMake(320.0, _options.count * 44.0);
    [self setContentSizeForViewInPopover:size];
    [self.view setFrame:CGRectMake(0.0, 0.0, size.width, size.height)];
    [navi setContentSizeForViewInPopover:size];

    _popoverController = [[UIPopoverController alloc] initWithContentViewController:navi];
于 2013-09-26T14:46:06.420 に答える
0

私は同じ問題に直面していましたが、viewWillAppear または viewWillDisappear メソッドで contentsize を設定したくありません。

AirPrintController *airPrintController = [[AirPrintController alloc] initWithNibName:@"AirPrintController" bundle:nil];
airPrintController.view.frame = [self.view frame];
airPrintController.contentSizeForViewInPopover = self.contentSizeForViewInPopover;
[self.navigationController pushViewController:airPrintController animated:YES];
[airPrintController release];

そのコントローラーを navigationController にプッシュする前に、そのコントローラーの contentSizeForViewInPopover プロパティを設定します

于 2011-08-12T10:43:59.263 に答える
0

これらのどれもうまくいかなかったので、別の解決策を提供したいと思います...

私は実際にこれでそれを使用しています https://github.com/nicolaschengdev/WYPopoverController

ポップアップを最初に呼び出すときは、これを使用します。

if ([sortTVC respondsToSelector:@selector(setPreferredContentSize:)]) {
   sortTVC.preferredContentSize = CGSizeMake(popoverContentSortWidth,
        popoverContentSortHeight);
}
else 
{
   sortTVC.contentSizeForViewInPopover = CGSizeMake(popoverContentSortWidth, 
        popoverContentSortHeight);
}

次に、そのポップアップでこれを使用します。

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

  if ([self respondsToSelector:@selector(setPreferredContentSize:)]) {
    self.preferredContentSize = CGSizeMake(popoverContentMainWidth, 
        popoverContentMainheight);
  }
  else 
  {
    self.contentSizeForViewInPopover = CGSizeMake(popoverContentMainWidth, 
        popoverContentMainheight);
  }
}

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

self.contentSizeForViewInPopover = CGSizeZero;

}

次に、子ビューについて繰り返します...

于 2014-04-30T12:41:37.290 に答える
0

あなたがしなければならないことはすべてです:

- popOvers contentView の viewWillAppear メソッドで、以下のスニペットを追加します。初めて popOver をロードするときに、そのサイズを指定する必要があります。

CGSize size = CGSizeMake(width,height);
self.contentSizeForViewInPopover = size;
于 2012-04-06T18:48:12.207 に答える