15

含まれているUINavigationControllerが新しいコントローラーをプッシュするときにUIPopoverControllerにそのサイズをアニメーション化させるにはどうすればよいですか?

iPadアプリでUIPopoverから表示されています。UIBarButtonItemこれには、UINavigationViewControllerルートビューコントローラとして一種の設定ウィンドウがあるが含まれています。設定ウィンドウはUITableViewController(スタイルがグループ化に設定された)のサブクラスであり、そのセルのいずれかをタップすると、のサブクラスでもあるnavコントローラー上のさまざまな「選択」ビューコントローラーがプッシュされUITableViewControllerます。

チューザービューごとに、で適切viewDidAppearに設定しています。contentSizeForViewInPopover

self.contentSizeForViewInPopover = CGSizeMake(320, self.items.count * 44);

しかし、それは変化をアニメートしません。ナビゲーションアニメーションが終了すると、ポップオーバーは新しい高さにスナップします(幅は320から変更されません)。後方にナビゲートすると、サイズの変更がアニメートされます(この回答の手法で実現されます)が、前方にナビゲートすると、サイズの変更はアニメートされません。

ポップオーバーへの参照を取得して使用しようとしましsetPopoverContentSize:animated:たが、機能しません。私は無駄に他の 質問を見てきました。

サイズ変更を常に適切にアニメーション化するにはどうすればよいですか?

更新:これを試すための簡単なテストプロジェクトを設定しました。これは、XcodeでセットアップされたiPad用のタブバーアプリケーションです。ビューコントローラの1つでナビゲーションバーにタブバーアイテムを追加しました。そのボタンが押されると、コントローラーは、ルートビューコントローラーとしてUITableViewControllerと呼ばれる非常に単純なサブクラスを持つナビゲーションコントローラーを含むポップオーバーを表示します。TestContentViewController

そのviewDidLoadサブクラスの中で、私はランダムにいくつかのアイテムを生成します。

self.numItems = arc4random() % 10 + 3;

これは私の行数です。セクション数は1です。cellForRowAtIndexPathセルのラベルテキストを設定して返します。行が選択されると、同じクラスの別のインスタンスを生成し、それをスタックにプッシュします。

VCのプロパティで何もしなくてもcontentSizeForViewInPopover、ポップオーバーは最大の高さになり、テーブルビューの行数に関係なくそこにとどまります。

viewDidAppearでサイズを設定すると、次のようになります。

-(void)viewDidAppear:(BOOL)animated
{
  self.contentSizeForViewInPopover = CGSizeMake(320, self.numItems * 44);
  [super viewDidAppear:animated];
{
  • ポップオーバーが最初に表示されると、非常にすばやくフルハイトに点滅してから、設定した高さにスナップします。
  • 新しいコントローラーがナビゲーションコントローラーにプッシュされると、アニメーションなしでその高さにスナップします。
  • 戻るときに、ポップ先のVCが、ポップ元のVCよりも高い場合は、正しいサイズにアニメーション化されます。私がポップしているものが小さければ、それは何もしません。

私が同じことをするが、でviewWillAppear

  • ポップオーバーが最初に表示されるとき、それはフルハイトです
  • 最初に行をタップしてスタックに新しいコントローラーを追加すると、最低でも約400pxの高さにアニメーション化されます。新しいコントローラーがスタックにプッシュされたときに、より高い高さが必要な場合は、それを取得します。そうでなければ、それは以前の状態にとどまります。

で同じことをすると、最初は正しいサイズで表示されることviewDidLoadを除いて、基本的に同じです。viewWillAppear

navコントローラーのデリゲートをポップオーバーを表示するVCに設定してから、ポップオーバーの高さ(setPopoverContentSize:animated:)をに設定しようとしましnavigationController:didShowViewController:animated:たが、結果の高さは少しずれています。そこに設定したサイズは、ポップオーバーの上部に組み込まれているナビゲーションバーの余分な高さを考慮する必要があると思います。そして、スタックに新しいコントローラーをプッシュするときのアニメーションは奇妙です。

再度更新する:新しいで解決された同じ問題については、ここを参照してくださいUIPopoverPresentationController

4

3 に答える 3

8

すべてのUITableViewControllerに対して次のことを試してみてください。試してみましたが、うまくいきました。

- (void)setSize:(BOOL)fake
{
    CGSize view_size;
    int sections_height, rows_height;

    //if you dynamically change the number of visible rows
    //for example overriding numberOfRowsInSection:section
    //this can help you to evaluate the correct popover height
    int sections = [self.tableView numberOfSections];
    int rows = 0;
    for(int i = 0; i < sections; i++){
        rows += [self.tableView numberOfRowsInSection:i];
    }
    sections_height = sections * 30 /*section height*/;
    rows_height = rows * 44 /*row height*/;

    view_size = CGSizeMake(320 /*fixed width*/, sections_height + rows_height);

    if(fake){
        view_size.width -= 1;
        view_size.height -= 1;
    }

    [self setContentSizeForViewInPopover:view_size];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    //...    
    [self setSize:FALSE];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self setSize:TRUE];
}

- (void)viewDidAppear:(BOOL)animated
{
    [self setSize:FALSE];
    [super viewDidAppear:animated];
}
于 2012-11-12T10:09:04.750 に答える
2

popoverControllerへの参照を保持しようとして使用した場合、あなたは近くにいたと思いますsetPopoverContentSize:animated:

私にとってうまくいくのは、スタックに置くコントローラーごとに、この特定の順序でのsetPopoverContentSize:animated:ANDの組み合わせです。contentSizeForViewInPopover

-(void)viewDidAppear:(BOOL)animated
{
    [self.popoverController setPopoverContentSize:whateverSize animated:true];
    self.contentSizeForViewInPopover = whateverSize;
    [super viewDidAppear:animated];
}

この場合、self.popoverControllerは、スタックにプッシュされる各コントローラーに保持する参照です。そのためにシングルトン変数を使用する方がおそらくクリーンです。

于 2012-11-10T08:40:42.990 に答える
0

アニメーションが目的の場合は、次のコードを試すことができます。正直言って、私はiPad開発の経験がありませんが、ほとんどすべてのプロジェクトでフレームとアルファの変更をアニメーション化するためにiPadを使用しています。パラメータは単純で、アニメーションが発生する期間、時間遅延、アニメーションオプション、ビューの変更を指定するブロック、および余波を指定する別のブロックオブジェクトが順番にあります。

[UIView animateWithDuration:1.0
                      delay:0.0
                    options: UIViewAnimationCurveEaseOut
                 animations:^{
               self.contentSizeForViewInPopover = CGSizeMake(320, self.items.count * 44);
                 }
                 completion:^(BOOL finished){
                //Insert what you need to do after the animation is over
                 }];

-(void)viewDidAppear:(BOOL)animatedに入れてみることができます

試してみて、うまくいくかどうか教えてください。

于 2012-11-07T04:45:08.410 に答える