UISplitViewController在ipadios13上发布时不会正确折叠
我正在将我的应用程序转换到iOS 13,UISplitViewController将折叠到细节视图,而不是发布时的主视图-仅在iPad上。此外,不会显示“后退”按钮,就像它是根视图控制器一样 我的应用程序由一个UISplitViewController在ipadios13上发布时不会正确折叠,ios,swift,ipad,uisplitviewcontroller,ios13,Ios,Swift,Ipad,Uisplitviewcontroller,Ios13,我正在将我的应用程序转换到iOS 13,UISplitViewController将折叠到细节视图,而不是发布时的主视图-仅在iPad上。此外,不会显示“后退”按钮,就像它是根视图控制器一样 我的应用程序由一个UISplitViewController组成,它已被子类化,符合UISplitViewControllerDelegate。拆分视图包含两个子视图-都是UINavigationControllers,并嵌入到UITabBarController(子类为TabViewController)
UISplitViewController
组成,它已被子类化,符合UISplitViewControllerDelegate
。拆分视图包含两个子视图-都是UINavigationControllers
,并嵌入到UITabBarController
(子类为TabViewController
)
在拆分视图viewDidLoad
中,代理设置为self
,preferredDisplayMode
设置为.allVisible
由于某些原因,没有调用方法splitViewController(u:collapseSecondary:on:)
在iPhone和iPad上的iOS 12中,在启动时正确调用方法splitViewController(\uuuOpseClapseSecondary:on:)
,介于应用程序(使用选项完成启动)
和ApplicationIDBecomeActive
之间
在iPhone上的iOS 13中,在启动时正确调用了方法splitViewController(uu2;:collapseSecondary:on:)
,在场景(将连接到会话:)
和场景界面前景之间
但是,在iPad上的iOS 13中,如果窗口在启动时具有紧凑的宽度,例如作为分割视图创建的新场景,则根本不会调用分割视图控制器(uu:collapseSecondary:on:)
方法。仅当将窗口扩展到规则宽度,然后收缩时,才调用该方法
class SplitViewController:UISplitViewController、UISplitViewController和UISplitViewController Delegate{
重写func viewDidLoad(){
super.viewDidLoad()
self.delegate=self
preferredDisplayMode=.allVisible
}
func splitViewController(uSplitViewController:UISplitViewController,将第二个辅助ViewController:UIViewController折叠到主ViewController:UIViewController)->Bool{
打印(“分割视图控制器功能”)
guard let secondaryAsNavController=secondaryViewController作为?UINavigationController else{return false}
guard让topAsDetailController=secondaryAsNavController.topViewController为?DetailViewController else{return false}
如果topAsDetailController.passedEntry==nil{
返回真值
}
返回错误
}
}
这让我很困惑,为什么在iPhone中调用这个方法,而不是在iPad中!我是一名新开发人员,这是我的第一篇帖子,如果我的代码没有提供足够的细节或格式不正确,我深表歉意 您需要在类“SceneDelegate”中的函数“scene”中添加此项: splitViewController.delegate=self 例如:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Setup split controller
let tabViewController = self.window!.rootViewController as! TabViewController
let splitViewController = tabViewController.viewControllers![0] as! SplitViewController
let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as! UINavigationController
navigationController.topViewController!.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem
navigationController.topViewController!.navigationItem.leftBarButtonItem?.tintColor = UIColor(named: "Theme Colour")
splitViewController.preferredDisplayMode = .allVisible
splitViewController.delegate = self//<<<<<<<<add this
}
class SceneDelegate:UIResponder,UIWindowSceneDelegate{
func场景(场景:UIScene,willConnectTo会话:UISceneSession,选项connectionOptions:UIScene.connectionOptions){
//设置分割控制器
让tabViewController=self.window!.rootViewController为!tabViewController
设splitViewController=tabViewController.ViewController![0]为!splitViewController
将navigationController=splitViewController.ViewController[splitViewController.ViewController.count-1]设为!UINavigationController
navigationController.topViewController!.navigationItem.leftBarButtonItem=splitViewController.displayModeButtonItem
navigationController.topViewController!.navigationItem.leftBarButtonItem?.tintColor=UIColor(名为:“主题颜色”)
splitViewController.preferredDisplayMode=.allVisible
splitViewController.delegate=self//由于某些原因,在iOS 13上,特别是在iPad上的compact traitCollections中,在UISplitViewController上调用viewDidLoad之前,会调用委托以查看它是否应该崩溃,因此当它调用时,不会设置委托,并且永远不会调用该方法
如果您以编程方式创建splitViewController,这是一个简单的解决方案,但如果您使用的故事板并不多。您可以通过在awakeFromNib()而不是viewDidLoad()中设置委托来解决此问题
使用原始帖子中的示例,代码示例如下
class SplitViewController: UISplitViewController, UISplitViewControllerDelegate {
override func awakeFromNib() {
super.awakeFromNib()
delegate = self
preferredDisplayMode = .allVisible
}
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController:UIViewController, onto primaryViewController:UIViewController) -> Bool {
return true
}
}
您还需要确保collapseSecondary函数中使用的任何逻辑都不会引用尚未填充的变量,因为viewDidLoad尚未被调用。我有一个Xcode项目,现在用于iOS 13,它使用一个选项卡栏控制器,该控制器与五个拆分视图控制器有关系,每个控制器都有自己的主视图详图(表格)视图和控制器
以前-iOS 12.x和更早版本,事实上早在我编写Objective-C时-我的分割视图控制器委托是在每个(父)主视图控制器的代码中设置的拆分视图控制器-我在子类UITableViewController
的viewDidLoad
方法中设置委托。这在iPhone和iPad上都成功运行了多年
e、 g
要明确的是,我没有子类化选项卡栏控制器或拆分视图控制器
随着Xcode 11和iOS 13的发布,主视图控制器中的拆分视图控制器委托方法不再被调用
需要明确的是,对于iOS 13,无论是设备还是模拟器,splitViewController(\uu:collapseSecondary:on:)
都不会被调用(使用断点进行测试),其结果是:
- iPhone-当应用程序在设备或模拟器上运行时,显示详细视图控制器
- iPad——当应用程序在设备或模拟器上运行时,细节视图控制器就会出现,没有后退按钮,因此没有明显的机制来“逃离”细节视图
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Setup split controller
let tabViewController = self.window!.rootViewController as! TabViewController
let splitViewController = tabViewController.viewControllers![0] as! SplitViewController
let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as! UINavigationController
navigationController.topViewController!.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem
navigationController.topViewController!.navigationItem.leftBarButtonItem?.tintColor = UIColor(named: "Theme Colour")
splitViewController.preferredDisplayMode = .allVisible
splitViewController.delegate = self//<<<<<<<<add this
}
class SplitViewController: UISplitViewController, UISplitViewControllerDelegate {
override func awakeFromNib() {
super.awakeFromNib()
delegate = self
preferredDisplayMode = .allVisible
}
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController:UIViewController, onto primaryViewController:UIViewController) -> Bool {
return true
}
}
class MasterViewController: UITableViewController, UISplitViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
splitViewController?.preferredDisplayMode = UISplitViewController.DisplayMode.allVisible
splitViewController?.delegate = self
...
}
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController:UIViewController, onto primaryViewController:UIViewController) -> Bool {
...
}
}
class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let window = window else { return }
guard let tabBarController = window.rootViewController as? UITabBarController else { return }
guard let splitViewController = tabBarController.viewControllers?.first as? UISplitViewController else { return }
splitViewController.delegate = self
splitViewController.preferredDisplayMode = UISplitViewController.DisplayMode.allVisible
}
...
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController:UIViewController, onto primaryViewController:UIViewController) -> Bool {
...
}
}
guard let window = window else { return }
guard let tabBarController = window.rootViewController as? UITabBarController else { return }
guard let splitViewControllers = tabBarController.viewControllers else { return }
for controller in splitViewControllers {
guard let splitViewController = controller as? UISplitViewController else { return }
splitViewController.delegate = self
splitViewController.preferredDisplayMode = UISplitViewController.DisplayMode.allVisible
}
guard let window = window else { return }
guard let tabBarController = window.rootViewController as? UITabBarController else { return }
guard let splitViewControllers = tabBarController.viewControllers else { return }
for controller in splitViewControllers {
guard let splitViewController = controller as? UISplitViewController else { return }
guard let navigationController = splitViewController.viewControllers.first else { return }
guard let masterViewController = navigationController.children.first else { return }
splitViewController.delegate = masterViewController as? UISplitViewControllerDelegate
splitViewController.preferredDisplayMode = UISplitViewController.DisplayMode.allVisible
}
class MasterViewController: UITableViewController, UISplitViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// the following two calls now in the scene(_:willConnectTo:options:) method...
// splitViewController?.preferredDisplayMode = UISplitViewController.DisplayMode.allVisible
// splitViewController?.delegate = self
...
}
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController:UIViewController, onto primaryViewController:UIViewController) -> Bool {
...
}
}
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController:UIViewController, onto primaryViewController:UIViewController) -> Bool {
...
}
@available(iOS 14.0, *)
func splitViewController(_ svc: UISplitViewController, topColumnForCollapsingToProposedTopColumn proposedTopColumn: UISplitViewController.Column) -> UISplitViewController.Column {
return .primary
}