Swift 4 Split View Controller 详细信息替换 Master

Posted

技术标签:

【中文标题】Swift 4 Split View Controller 详细信息替换 Master【英文标题】:Swift 4 Split View Controller Detail Replaces Master 【发布时间】:2017-09-29 18:52:25 【问题描述】:

我刚刚开始构建一个应用程序,现在我正在添加 2 个拆分视图控制器,在我的 Main.storyboard 中它看起来像这张图片

我将以下代码添加到我的 Master:

import UIKit

class ContactsMaster: UITableViewController 

    var ContactsDetailController: ContactsDetail? = nil
    var objects = [Any]()


    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        navigationItem.leftBarButtonItem = editButtonItem

        let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject(_:)))
        navigationItem.rightBarButtonItem = addButton
        if let split = splitViewController 
            let controllers = split.viewControllers
            ContactsDetailController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? ContactsDetail
        
    

    override func viewWillAppear(_ animated: Bool) 
        clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
        super.viewWillAppear(animated)
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    @objc
    func insertNewObject(_ sender: Any) 
        objects.insert(NSDate(), at: 0)
        let indexPath = IndexPath(row: 0, section: 0)
        tableView.insertRows(at: [indexPath], with: .automatic)
    

    // MARK: - Segues

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
        if segue.identifier == "showContactDetail" 
            if let indexPath = tableView.indexPathForSelectedRow 
                let object = objects[indexPath.row] as! NSDate
                let controller = (segue.destination as! UINavigationController).topViewController as! ContactsDetail
                controller.detailItem = object
                controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
                controller.navigationItem.leftItemsSupplementBackButton = true
            
        
    

    // MARK: - Table View

    override func numberOfSections(in tableView: UITableView) -> Int 
        return 1
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return objects.count
    

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

        let object = objects[indexPath.row] as! NSDate
        cell.textLabel!.text = object.description
        return cell
    

    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool 
        // Return false if you do not want the specified item to be editable.
        return true
    

    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
        if editingStyle == .delete 
            objects.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .fade)
         else if editingStyle == .insert 
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
        
    



这是我的详细信息:

import UIKit

class ContactsDetail: UIViewController 

    @IBOutlet weak var detailDescriptionLabel: UILabel!


    func configureView() 
        // Update the user interface for the detail item.
        if let detail = detailItem 
            if let label = detailDescriptionLabel 
                label.text = detail.description
            
        
    

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        configureView()
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    var detailItem: NSDate? 
        didSet 
            // Update the view.
            configureView()
        
    



我的问题是当我运行我的应用程序并转到拆分视图控制器并在主视图中选择一个项目时,它没有转到详细信息,而是替换了主视图。

我有一个示例应用程序,它只是拆分视图控制器,我在示例应用程序的 App Delegate 文件中注意到应用程序中有此代码(_ 应用程序:UIApplication,didFinishLaunchingWithOptions launchOptions:[UIApplicationLaunchOptionsKey:Any]?) -> 布尔方法:

let splitViewController = window!.rootViewController as! UISplitViewController
        let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as! UINavigationController
        navigationController.topViewController!.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem
        splitViewController.delegate = self 

还有这个方法:

func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController:UIViewController, onto 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
    

我对这段代码的问题是我的拆分视图控制器不是初始控制器,而我的 splitViewController 方法存在问题,我有 2 个拆分视图控制器,我只能指定其中的 1 个。如何在不使其成为初始控制器的情况下获得此拆分视图控制器?

【问题讨论】:

【参考方案1】:

您的大师班必须实现 UISplitViewControllerDelegate。 所以你需要做的第一件事:

class ContactsMaster: UITableViewController,UISplitViewControllerDelegate 

并在你的 master 中覆盖这个函数:

func splitViewController(splitViewController: UISplitViewController, collapseSecondaryViewController secondaryViewController: UIViewController, ontoPrimaryViewController primaryViewController: UIViewController) -> Bool 
return true    

然后在 viewDidLoad(master class) 中添加以下代码:

self.splitViewController!.delegate = self;

self.splitViewController!.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible

self.extendedLayoutIncludesOpaqueBars = true  

我认为你跳过了配置 splitviewcontroller 的许多步骤,如果你想完全理解,你可以阅读为它编写的许多教程之一,例如:

http://nshipster.com/uisplitviewcontroller/

【讨论】:

【参考方案2】:

您是否偶然忘记在 Storyboard 中为您的 Detail VC 设置 ContactsDetail 类?

【讨论】:

以上是关于Swift 4 Split View Controller 详细信息替换 Master的主要内容,如果未能解决你的问题,请参考以下文章

swift UI数组创建BUTTON

如何在 Swift 4 中设置从 collectionView 底部到 Input Accessory View 顶部的约束

如何使用Swift 4将数据从Pop-Over子视图传递到View Controller

Swift 怎么用xib 自定义View

Mac Split View屏幕分割,Mac分屏怎么用

swift--动画效果