iOS中如何实现含iPad竖屏、iPhone全方向的SplitView分栏功能
- UISplitViewController的默认显示逻辑完全基于当前视图的水平尺寸类判断:iPad横屏状态下水平为
regular尺寸类,系统自动渲染双栏;只要切换到竖屏(包括iPad竖屏、全场景iPhone),水平尺寸类变为compact,系统就会自动触发折叠逻辑,把主、从栏合并为单栈显示,不会保留双栏布局。 - 你当前代码没有实现对应的代理方法拦截折叠行为,也没有指定强制双栏的显示模式,所以会出现方向切换就失效的问题。
- 拦截系统自动折叠逻辑
在CustomSplitViewController中实现UISplitViewControllerDelegate的核心方法,直接禁止系统折叠从栏:#pragma mark - UISplitViewControllerDelegate - (BOOL)splitViewController:(UISplitViewController *)splitViewController
collapseSecondaryViewController:(UIViewController *)secondaryViewController
ontoPrimaryViewController:(UIViewController *)primaryViewController {
// 返回NO 表示永远不把详情栏折叠合并到主栏
return NO;
} 同时在初始化SplitView的时候配置强制显示双栏的属性: objc
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
self.splitViewController.delegate = self;
// 关闭系统自动隐藏主栏的边缘手势触发
self.splitViewController.presentsWithGesture = NO;2. 自定义栏位宽度适配 因为iPhone屏幕宽度有限,需要手动指定主栏的最大宽度,避免栏位挤压变形: objc
// 按设备类型设置主栏宽度
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
self.splitViewController.maximumPrimaryColumnWidth = 320;
self.splitViewController.minimumPrimaryColumnWidth = 280;
} else {
self.splitViewController.maximumPrimaryColumnWidth = 400;
self.splitViewController.minimumPrimaryColumnWidth = 320;
}3. 修正现有代码的冗余问题 你当前代码中先执行`[self.window addSubview:tabBarController.view]`、再设置`window.rootViewController`为tabBarController的操作是冗余的,会触发视图生命周期的重复调用,导致SplitView的尺寸类判断提前失效,直接删除这行addSubview代码即可。 4. 配置全方向旋转权限 在`CustomSplitViewController`中重写方向支持方法,保证任何方向下都不会因为方向限制触发逻辑异常: objc
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
- (BOOL)shouldAutorotate {
return YES;
}
```
- 不要为了强制双栏去硬改全局的trait集合,这种操作会导致TabBar下其他页面的尺寸类错乱,用上面的代理拦截方法是系统提供的官方支持方案,兼容性更好。
- iPhone横屏如果是窄屏机型(比如iPhone SE),双栏布局下主栏宽度可以适当收窄到260pt,避免详情栏内容被过度挤压。
- 如果你适配的是iOS14及以上版本,初始化SplitView时需要显式指定样式为
UISplitViewControllerStyleDoubleColumn,避免系统默认的三栏样式触发兼容问题。
内容的提问来源于stack exchange,提问作者Ravikanth Manne

