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 4 中设置从 collectionView 底部到 Input Accessory View 顶部的约束