UINavigationControllerをホストするUIPopoverControllerがあります。これには、View Controllerの小さな階層が含まれています。
私はドキュメントに従って、各View Controllerについて、ビューのポップオーバーコンテキストサイズを次のように設定しました:
[self setContentSizeForViewInPopover:CGSizeMake(320, 500)];
(コントローラーごとに異なるサイズ)
階層内を前方に移動すると、期待どおりに機能します。ポップオーバーは、プッシュされたコントローラーに対応するサイズ変更を自動的にアニメーション化します。
ただし、ナビゲーションバーの[戻る]ボタンを使用してビュースタックを[戻る]に移動すると、ポップオーバーのサイズは変わりません。最も深いビューに到達したときと同じ大きさのままです。これは私には壊れているようです。ポップオーバーは、ビュースタックを介してポップするときに設定されるサイズを尊重することを期待しています。
何か不足していますか?
ありがとう。
わかりました、私は同じ問題に苦労していました。上記の解決策はどれも私にはうまくいきませんでした。だから私は少し調査をして、これがどのように機能するかを調べることにしました。これは私が発見したことです。-View ControllerでcontentSizeForViewInPopover
を設定すると、ポップオーバー自体によって変更されません-異なるコントローラーへの移動中にポップオーバーのサイズが変更される場合があります。 -別のコントローラーにナビゲートしているときにポップオーバーのサイズが変わると、戻る間、ポップオーバーのサイズは復元されません-viewWillAppearのポップオーバーのサイズを変更すると、非常に奇妙なアニメーションが表示されます私はそれをお勧めしません-私にとっては、コントローラ内でハードコードされたサイズを設定してもまったく機能しません-私のコントローラは時には大きくなければならないことがあります-それらを提示するコントローラはサイズについての考えを持っていますが
すべての痛みの解決策は次のとおりです。viewDidAppearでcurrentSetSizeForPopover
のサイズをリセットする必要があります。ただし、フィールドcurrentSetSizeForPopover
に既に設定されているサイズと同じサイズを設定する場合、ポップオーバーはサイズを変更しません。これを実現するには、最初に偽のサイズ(前に設定したサイズとは異なる)を設定し、その後適切なサイズを設定します。このソリューションは、コントローラーがNavigation Controller内にネストされていても機能し、コントローラー間をナビゲートするときにPopoverのサイズが適宜変更されます。
サイズを設定するトリックを行う次のヘルパーメソッドを使用して、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は、ポップオーバーで必要なビューをpresentingViewControllerビューコントローラのpresentedViewControllerに静かにラップします。 2014年のWWDCビデオでは、popovercontrollerの新機能について説明しています。
とにかく、Navigation Controllerスタックに表示されるView Controllerがすべて独自のサイズ設定を必要とする場合、これらのView Controllerは(iOS 8で)このコードを呼び出してpreferredContentSizeを動的に設定する必要があります。
self.presentingViewController.presentedViewController.preferredContentSize = CGSizeMake(320, heightOfTable);
HeightOfTableを計算されたテーブルまたはビューの高さに置き換えます。
多くの重複コードを回避し、一般的なiOS 7およびiOS 8ソリューションを作成するために、tableTablesでviewDidAppearが呼び出されたときにこの作業を実行するためにUITableViewControllerにカテゴリを作成しました。
- (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メソッドを呼び出します。私も同じ問題を抱えていました。しかし、これを追加すると問題は解決しました。
もう1つ:5より前のベータバージョンを使用している場合、ポップオーバーの管理がより困難になります。彼らはベータバージョン5からより友好的であるようです。それは最終バージョンが出ているのは良いことです。 ;)
お役に立てれば。
Navigation Controllerで使用しているすべてのView Controllerの-(void)viewDidLoad
に、以下を追加します:
[self setContentSizeForViewInPopover:CGSizeMake(320, 500)];
ナビゲートされている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;
}
Well i worked out. Have a look.
Made a ViewController in StoryBoard. Associated with PopOverViewController class.
import UIKit
class PopOverViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.preferredContentSize = CGSizeMake(200, 200)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: "dismiss:")
}
func dismiss(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
See ViewController:
//
// ViewController.Swift
// iOS8-PopOver
//
// Created by Alvin George on 13.08.15.
// Copyright (c) 2015 Fingent Technologies. All rights reserved.
//
import UIKit
class ViewController: UIViewController, UIPopoverPresentationControllerDelegate
{
func showPopover(base: UIView)
{
if let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("popover") as? PopOverViewController {
let navController = UINavigationController(rootViewController: viewController)
navController.modalPresentationStyle = .Popover
if let pctrl = navController.popoverPresentationController {
pctrl.delegate = self
pctrl.sourceView = base
pctrl.sourceRect = base.bounds
self.presentViewController(navController, animated: true, completion: nil)
}
}
}
override func viewDidLoad(){
super.viewDidLoad()
}
@IBAction func onShow(sender: UIButton)
{
self.showPopover(sender)
}
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return .None
}
}
Note: The func showPopover(base: UIView) method should be placed before ViewDidLoad. Hope it helps !
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バージョンと互換性があるはずだと思います...
受け入れられた答え はiOS 8では正常に動作しません。私がしたことは、そのポップオーバーで使用するUINavigationController
のサブクラスを作成し、このメソッドpreferredContentSize
をオーバーライドすることでした。方法:
- (CGSize)preferredContentSize {
return [[self.viewControllers lastObject] preferredContentSize];
}
さらに、forcePopoverSize
でviewDidAppear
(@krasnykによって実装されるメソッド)を呼び出す代わりに、前述のナビゲーション(ポップオーバー)のデリゲートとしてviewController(ポップオーバーを表示)を設定し、(強制メソッドが行うこと)
-(void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
渡されたviewController
のデリゲートメソッド。 1つの重要なことは、forcePopoverSize
メソッドでUINavigationControllerDelegate
を実行すると、アニメーションをスムーズにする必要がない場合は問題ありませんが、viewDidAppear
のままにしておくことは問題ありません。
私にとって、このソリューションは機能します。これは、UITableViewControllerを拡張し、UINavigationControllerのルートコントローラーであるView Controllerのメソッドです。
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.contentSizeForViewInPopover = self.tableView.bounds.size;
}
そして、ナビゲーションスタックにプッシュするView Controllerのコンテンツサイズを設定することを忘れないでください
- (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];
}
あなたがアサンブラーを想像できるなら、私はこれがわずかに優れていると思います:
-(void)forcePopoverSize { CGSize currentSetSizeForPopover = self.contentSizeForViewInPopover; self.contentSizeForViewInPopover = CGSizeMake(0、0); self.contentSizeForViewInPopover; currentSetSizeForPopover; }
これはiOS7でこれを行う正しい方法です。NavigationStackの各View ControllerのviewDidLoadで優先コンテンツサイズを設定します(一度だけ実行します)。次に、viewWillAppearでポップオーバーコントローラーへの参照を取得し、そこでcontentSizeを更新します。
-(void)viewDidLoad:(BOOL)animated
{
...
self.popoverSize = CGSizeMake(420, height);
[self setPreferredContentSize:self.popoverSize];
}
-(void)viewWillAppear:(BOOL)animated
{
...
UIPopoverController *popoverControllerReference = ***GET REFERENCE TO IT FROM SOMEWHERE***;
[popoverControllerReference setPopoverContentSize:self.popoverSize];
}
あなたがしなければならないことはすべてです:
-popOvers contentViewのviewWillAppearメソッドで、以下のスニペットを追加します。ロード時にpopOverのサイズを最初に指定する必要があります。
CGSize size = CGSizeMake(width,height);
self.contentSizeForViewInPopover = size;
NavigationControllerのpreferredContentSize
プロパティをviewWillAppear
に設定する必要があります。
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.preferredContentSize = CGSizeMake(320, 500);}
開始時にpopoverContentSize = CGSizeMake(320、600)であるポップオーバーコントローラーでこの問題が発生しましたが、ContentViewController(UINavigationController)をナビゲートすると大きくなります。
NavコントローラーはカスタムUITableViewControllersをプッシュおよびポップするだけだったので、カスタムテーブルビューコントローラークラスのviewDidLoadでself.contentSizeForViewInPopover = CGSizeMake(320、556)を設定しました
44個少ないピクセルは、Navコントローラーのnavバーを説明するためのものであり、もう問題はありません。
同じ問題に直面し、UIPopoverControllerのinitが配置される前にコンテンツビューサイズをNavigation ControllerとView Controllerに設定することで修正しました。
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];
これをポップオーバー内にプッシュするすべてのView Controllerに入れます
CGSize currentSetSizeForPopover = CGSizeMake(260, 390);
CGSize fakeMomentarySize = CGSizeMake(currentSetSizeForPopover.width - 1.0f,
currentSetSizeForPopover.height - 1.0f);
self.contentSizeForViewInPopover = fakeMomentarySize;
self.contentSizeForViewInPopover = currentSetSizeForPopover;
@krasnykソリューションは、以前のiOSバージョンではうまく機能しましたが、iOS8では機能しませんでした。次のソリューションは私のために働いた。
- (void) forcePopoverSize {
CGSize currentSetSizeForPopover = self.preferredContentSize;
//Yes, there are coupling. We need to access the popovercontroller. In my case, the popover controller is a weak property in the app's rootVC.
id mainVC = [MyAppDelegate appDelegate].myRootVC;
if ([mainVC valueForKey:@"_myPopoverController"]) {
UIPopoverController *popover = [mainVC valueForKey:@"_myPopoverController"];
[popover setPopoverContentSize:currentSetSizeForPopover animated:YES];
}
}
これは最善の解決策ではありませんが、機能します。
新しいUIPopoverPresentationControllerにもサイズ変更の問題があります:(。
Viewdidappearに以下を配置することで、私は幸運に恵まれました。
[self.popoverController setPopoverContentSize:self.contentSizeForViewInPopover animated:NO];
ただし、異なるサイズのポップオーバーをプッシュ/ポップする場合、これはうまくアニメーション化されない場合があります。しかし、私の場合、完全に動作します!
これらのどれも私のために働いていなかったので、私は別のソリューションを提供したいだけです...
私は実際にこれで使用しています 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;
}
次に、子ビューについて繰り返します...
私は同じ問題に直面していましたが、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プロパティを設定します