我有一个带有目标iPhone 6应用程序的拆分视图界面。在第一次启动应用程序时,它将打开详细信息视图;我希望它能打开Master View。我试过了:
self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.PrimaryOverlay
其他地方(Prior StackOverFlow Question)建议但它似乎没有做任何事情,并且在发布时不会打开主视图。我还尝试将以下行添加到AppDelegate中:
splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
但是尽管回归真或假(Another Prior Stack Overflow Question)我没有成功。
我确实在Xcode中启动了示例Master-Detail应用程序,并根据splitViewController加载到Master视图:call returns false;但是,我不确定如何在更复杂的布局中完成这项工作。
答案 0 :(得分:47)
UISplitViewController display master view above detail in portrait orientation不是关于显示主视图,而是关于在主视图下方以全宽显示详细信息视图。
UISplitViewController in portrait on iPhone shows detail VC instead of master是关于崩溃机制的原则。
本答案致辞:
您必须设置preferredDisplayMode
。你想要的是 .primaryVisible
,如果它存在的话!如果只有1个视图符合(紧凑宽度),则使用.allVisible
,iOS会选择Detail
;在该尺寸中,以下代码将选择Master
。
诀窍是将{em>两者 preferredDisplayMode
更改为.allVisible
和以在true
中返回collapseSecondary: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
}
}
答案 1 :(得分:7)
第1步 - 打开MasterViewController
第2步 - 确保表视图具有UISplitViewControllerDelegate协议。例如:
class ListVC: UITableViewController,UISplitViewControllerDelegate {}
第3步 - 在ViewDidLoad中添加
splitViewController?.delegate = self
第4步 - 然后重写此方法,说主视图控制器应始终折叠到详细视图控制器上:
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
return true
}
答案 2 :(得分:6)
我没有收到splitViewController(_:collapseSecondary:onto:)
的回调,而是使用了以下新方法。
func splitViewController(_ svc: UISplitViewController, topColumnForCollapsingToProposedTopColumn proposedTopColumn: UISplitViewController.Column) -> UISplitViewController.Column {
return .primary
}
答案 3 :(得分:4)
首次启动应用程序时,它会打开详细信息视图;我希望它打开主视图
假设你只想在第一次发射时,但并非总是如此;例如,在主视图显示空数据集的情况下;然后解决方案就像Master-Detail模板显示的那样:
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 :(得分:0)
这是一个古老的问题,答案都不是针对目标C的,即使我移植了Swift答案,也没有一个对我有用。一个是由@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;
}
注意:经过一些测试,我发现拆分视图委托方法和拆分视图协议不是必需的。没有它,它的工作原理似乎完全相同。也许这是自最初提出并回答问题以来iOS更改的结果。
通过将这一行放入我的ViewDidLoad方法中,我就可以正常工作
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;
答案 5 :(得分:0)
或者仅继承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
}
}
答案 6 :(得分:0)
Swift 5 ,iOS 13
我发现其他答案很有用,但不完全是,因为它们在iPad或iPhone上表现出了我想要的行为,但并没有同时出现。
下面的解决方案是我用来做的:
iPhone:主视图始终首先出现
iPad Portrait:总是显示细节,但要覆盖主视图;详细信息是全屏显示(不仅是母版显示)
iPad Landscape:大师总是在左边,细节总是在右边
class RootSplitViewController: UISplitViewController {
override func viewDidLoad() {
if UIDevice.current.userInterfaceIdiom == .pad {
self.preferredDisplayMode = .automatic
}
else {
self.preferredDisplayMode = .allVisible
}
self.delegate = self
}
}
extension RootSplitViewController: UISplitViewControllerDelegate {
func splitViewController(_ splitViewController: UISplitViewController,
collapseSecondary secondaryViewController:UIViewController,
onto primaryViewController:UIViewController)
-> Bool
{
if AppState.instance.currentSelectedEvent == nil {
// Return true to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
return true
}
else {
return false
}
}
}
答案 7 :(得分:0)
iOS 14
在WWDC 2020 - Build for iPad中,您可以通过选中属性检查器中的使用单独的视图控制器,为紧凑宽度类添加特定的视图控制器(例如,纵向iPhone,纵向滑行iPad)的SplitViewController。
因此,您可以通过设置关系segue将任何视图控制器设置为所需的初始视图控制器。
答案 8 :(得分:0)
iOS 14 -- 两列模式更新
我为此苦苦挣扎了一段时间,最终发现拆分视图控制器已在 iOS14 中重新设计,因此上述答案都不再相关。
我建议从这篇文章开始here。
但如果您正在寻找快速解决方案:
didSelectRowAt
函数中: // If we are in compact mode, we need to push the detail view controller
if let splitViewController = splitViewController {
if splitViewController.isCollapsed {
let shipmentDetailViewController = storyboard?.instantiateViewController(identifier: "shipmentDetailViewController") as! ShipmentDetailViewController
shipmentDetailViewController.shipment = selectedShipment
self.navigationController?.pushViewController(shipmentDetailViewController, animated: true)
}
}