web-dev-qa-db-ja.com

UISplitViewController:アプリの起動時にマスターポップオーバーを表示する強制力(縦)

IPadアプリでは、UISplitViewControllerを使用しています。アプリをポートレートモードで起動したときに、マスターポップオーバーを強制的に表示する必要があります。

今、私はこのコードを使用しており、iOS 5.0でうまく動作します。

if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
   if ([[[AppDelegate sharedAppDelegate] splitViewController] respondsToSelector:[[[AppDelegate sharedAppDelegate] btnMenu] action]]) {
      [[[AppDelegate sharedAppDelegate] splitViewController] performSelector:[[[AppDelegate sharedAppDelegate] btnMenu] action]];
   }            
}

しかし、iOS 5.1(新しいタイプのマスターポップオーバー)では、動作がランダムになっているようです。ポップオーバーがフルスクリーンで表示されることもあれば、うまく機能することもあります。

5.1に関する提案はありますか?

27
alejandromp

私はしばらくの間これに苦労しました、そして今でも私は解決策に100%満足していませんが、現在の制約を考えると、それが思いつくことができた唯一のものです。

まず、次のデリゲートメソッドをオーバーライドします。

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController

それを使用してバーボタン項目への参照を取得し、iVarに保存します。

barButtonForMaster = barButtonItem;

次に、マスタービューコントローラーを表示する場合は、次のように呼び出します。

[barButtonForMaster.target performSelector: barButtonForMaster.action withObject: barButtonForMaster];

最初にこれを正しく実行したい場合は、アプリのクラッシュを防ぐために遅延を使用してください(役立つコメントのおかげです)。

[barButtonForMaster.target performSelector: barButtonForMaster.action withObject: barButtonForMaster afterDelay:1];

その場合は、分割ビューのデリゲートメソッドで直接セレクターを実行できます。

13
Rob Elkin

ここでは5.1の提案はありませんが、8.0の提案はあります。

IOS8では、UISplitViewController構成用の新しいメソッドがたくさんあります。

あなたの場合、正しい値をpreferredDisplayModeに設定してください。たとえば、masterViewController viewDidLoadに設定します。

Objective-C:

- (void)viewDidLoad {
    // configuring splitviewcontroller
    self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;

    //....
}

Swift:

    override func viewDidLoad() {
        self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible
    }

ただし、もちろんiOS8のみです。

26
Martin

ロブの答えを拡張すると、これは私のためにうまくいきます(詳細画面のviewDidLoadで):

//If in portrait mode, display the master view
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
    [self.navigationItem.leftBarButtonItem.target performSelector:self.navigationItem.leftBarButtonItem.action withObject:self.navigationItem];
}

代わりにself.navigationItem.leftBarButtonItemを使用して、個別の参照をフェッチする必要はありません

13
Setomidor

IOS8の場合、最も簡単な方法は次のとおりです。

 self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;

アプリを初めて起動したときにこれを使用して、masterViewControllerにログインを表示します。私が使用する他のすべての場合

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAutomatic
7
aquarius68

アプリの起動時に必要な場合は、詳細ビューコントローラーでこのメソッドをオーバーライドします。

-(BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
    return NO;
}

ただし、後で非表示にする必要がある場合は、メソッドが呼び出されていないように見えるため、手動で非表示にする必要があります。

5
SeanR

少しハックなバリエーション(Swift):

let btn = self.splitViewController!.displayModeButtonItem()
btn.target?.performSelector(btn.action, withObject: btn)
1
maniek

私はこのソリューションを使用します:
viewDidLoadのsplitViewControllerで、displayModeを.primaryOverlayに設定します

override func viewDidLoad() {
    if self.isCollapsed == false, self.displayMode == .primaryHidden {
        self.preferredDisplayMode = .primaryOverlay
    }
}

そしてviewWillAppearでそれを.automaticに戻します

override func viewWillAppear(_ animated: Bool) {
    self.preferredDisplayMode = .automatic
}

このようにして、マスタービューはUISplitViewControllerの起動時に表示され、方向が変更された後のデフォルトの動作になります。

1

BarButtonItemへの愚かな参照を保持する必要はありません。同じターゲット/アクションを呼び出すだけです。私の答えを見てください https://stackoverflow.com/a/25695923/10214

ターゲットは分割ビューコントローラーで、アクションはtoggleMasterVisibleです。

0
user1021430