web-dev-qa-db-ja.com

UISplitViewControllerを詳細ではなくマスタービューに開きます

ターゲットのiPhone 6アプリケーションに分割ビューインターフェイスがあります。アプリケーションを初めて起動すると、詳細ビ​​ューが開きます。マスタービューで開いてください。私が試してみました:

self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.PrimaryOverlay

これは他の場所で提案されました (Prior StackOverFlow Question) しかし、何も実行しないようで、起動時にマスタービューが開きません。また、次の行をAppDelegateに追加しようとしました。

splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:

しかし、trueまたはfalseを返すにもかかわらず( 別の以前のスタックオーバーフローの質問 )、成功しませんでした。

Xcodeでサンプルのマスター/詳細アプリケーションを起動しましたが、splitViewControllerに基づいてマスタービューに読み込まれます。ただし、これをより複雑なレイアウトで機能させる方法がわかりません。

32
Tom Foutz

Swift

ISplitViewControllerマスタービューをディテールの上に縦向きで表示 は、マスタービューを表示することではなく、マスタービューの下に詳細ビューを全幅で表示することです。

iPhoneの縦向きのUISplitViewControllerは詳細を示しますVC は、折りたたみメカニズムの原理についてです。

この現在の答えは次のとおりです。

  • マスター→詳細(コンパクト幅)
    • iPhone 4s、5、5s、SE、6、6s、7(任意の向き)
    • iPod Touch
    • 任意のiPhone Plus(縦)
  • 並べて(他のすべてのサイズ)
    • iPad
    • iPhone Plus(横)

preferredDisplayModeを設定する必要があります。存在する場合は、.primaryVisibleを使用します。 iOSは、.allVisibleを使用して、ビューが1つしかフィットしない場合にDetailを選択します(コンパクトな幅);そのサイズで、以下のコードはMasterを選択します。

コツは両方preferredDisplayMode.allVisibleに変更することですandtruecollapseSecondary:ontoに返すようにします。

class PrimarySplitViewController: UISplitViewController,
                                  UISplitViewControllerDelegate {

    override func viewDidLoad() {
        self.delegate = self
        self.preferredDisplayMode = .allVisible
    }

    func splitViewController(
             _ splitViewController: UISplitViewController,
             collapseSecondary secondaryViewController: UIViewController,
             onto primaryViewController: UIViewController) -> Bool {
        // Return true to prevent UIKit from applying its default behavior
        return true 
    }
}
56
SwiftArchitect

ステップ1-MasterViewControllerを開く

ステップ2-テーブルビューにUISplitViewControllerDelegateプロトコルが含まれていることを確認します。例えば:

class ListVC: UITableViewController,UISplitViewControllerDelegate {}

ステップ-ViewDidLoadに追加します

splitViewController?.delegate = self

手順4-次に、このメソッドをオーバーライドして、マスタービューコントローラーが常に詳細ビューコントローラーに折りたたまれるようにします。

func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
    return true
}
8
iOS Lifee

アプリケーションを初めて起動すると、詳細ビ​​ューが開きます。マスタービューを開いてほしい

最初の起動時にのみそれが必要であると仮定しますが、常にではありません。たとえば、マスタービューに空のデータセットが表示されている場合。ソリューションは、マスター/ディテールテンプレートが示すとおりです。

func splitViewController(splitViewController: UISplitViewController, collapseSecondaryViewController secondaryViewController:UIViewController, ontoPrimaryViewController primaryViewController:UIViewController) -> Bool {
    guard let secondaryAsNavController = secondaryViewController as? UINavigationController else { return false }
    guard let topAsDetailController = secondaryAsNavController.topViewController as? DetailViewController else { return false }
    if topAsDetailController.detailItem == nil {
        // Return true to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
        return true
    }
    return false
}
4
NiñoScript

または、単にUISplitViewControllerを継承して、ストーリーボードでこの新しいクラスを使用します(SwiftArchitectの回答に基づく):

class MasterShowingSplitViewController :UISplitViewController, UISplitViewControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()

        self.delegate = self
        self.preferredDisplayMode = .allVisible
    }

    func splitViewController(
        _ splitViewController: UISplitViewController,
        collapseSecondary secondaryViewController: UIViewController,
        onto primaryViewController: UIViewController) -> Bool {
        // Return true to prevent UIKit from applying its default behavior
        return true
    }
}
1
Mohsenasm

これは古い質問であり、Objective Cに対する回答はありませんでした。また、Swiftの回答を移植した場合でも、どれもうまくいきませんでした。1つは、@ SwiftArchitectによるものでした。

ただし、コンテンツモードを.allVisible(Objective CではUISplitViewControllerDisplayModeAllVisible)に設定することをお勧めします。これにより、マスタービューが常に表示され、ビューが片側でマスターに、もう片側で詳細に分割されます。それはちょっとクールですが、OPは最初の起動時にマスタービューを表示するように特別に要求しました。

変更は、表示モードにUISplitViewControllerDisplayModePrimaryOverlayを使用することでした。

この回答は、Xcode 9.4.1、デプロイメントターゲット11.4に対するものです。

これがMasterViewController.hです-プロトコル宣言にUISplitViewControllerDelegateを追加する必要があります:

#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#import "MasterDetailDemo+CoreDataModel.h"

@class DetailViewController;

@interface MasterViewController : UITableViewController
<UISplitViewControllerDelegate,
NSFetchedResultsControllerDelegate>

@property (strong, nonatomic) DetailViewController *detailViewController;

@property (strong, nonatomic) NSFetchedResultsController<Event *> *fetchedResultsController;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;

@end

次に、MasterViewController.mで、ViewDidLoadでスプリットビューコントローラーデリゲートとコンテンツモードを設定し、@ SwiftArchitectの回答に続いて、スプリットビューコントローラーデリゲートメソッドも追加する必要があります。

- (void)viewDidLoad {

    [super viewDidLoad];

    // needed to "slide out" MasterView on startup on iPad
    self.splitViewController.delegate = self;
    self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;

    self.navigationItem.leftBarButtonItem = self.editButtonItem;

    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];

    self.navigationItem.rightBarButtonItem = addButton;

    self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
}

// split view delegate method
- (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController {
    return true;
}

[〜#〜] note [〜#〜]:いくつかのテストの結果、分割ビューのデリゲートメソッドと分割ビュープロトコルは不要であることがわかりました。それがなければ、まったく同じように動作するように見えます。質問が最初に尋ねられて回答されたため、おそらくこれはiOSの変更の結果です。

この行をViewDidLoadメソッドに配置するだけで問題なく動作しました。

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;
0
ByteSlinger