我想在此开头说我是IOS开发的新手。 我在这里发现了与我要问的问题类似的帖子: Swift 4 Split View Controller Detail Replaces Master 但是,这并不能解决我的问题。 但是,我的问题非常相似,我有一个拆分视图控制器,它是我的根视图,它可以按预期工作。从主表中选择一个项目会更改详细视图控制器。
这是我制作的情节提要。 顶部是第一个splitview(根视图) 底部的表格视图是侧面推动菜单,在这里我可以导航到左侧部分。这是我遇到问题的第二个拆分视图。
当我添加第二个视图控制器时,我的问题开始了。 当我导航到第二个视图控制器并尝试在主表(现在在第二个拆分视图中)中选择一个项目时,它不会更新第二个拆分视图的详细信息视图控制器。
基本上,我复制并粘贴了已经为第一个拆分视图编写的代码,但是显然我遗漏了一些东西。
这是我的应用程序代表(我开始认为应用程序代表是我的问题所在)
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]?) -> Bool {
guard let splitViewController = window!.rootViewController as? UISplitViewController,
let leftNavController = splitViewController.viewControllers.first as? UINavigationController,
let masterViewController = leftNavController.topViewController as? MasterVC,
// let rightNavController = splitViewController.viewControllers.last as? UINavigationController,
let detailViewController = splitViewController.viewControllers.last as? DetailVC
else { fatalError() }
// else {return true}
let firstMail = masterViewController.mail.first
detailViewController.mails = firstMail
masterViewController.delegate = detailViewController
masterViewController.navigationItem.leftItemsSupplementBackButton = true
detailViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem
UISearchBar.appearance().tintColor = .blue
UINavigationBar.appearance().tintColor = .blue
splitViewController.preferredDisplayMode = .automatic
splitViewController.delegate = self
return true
}
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? DetailVC else {return false}
if topAsDetailController.detailMail == nil {
return true
}
return false
}
}
这是第一个拆分视图控制器(根视图/ masterViewController)
import UIKit
protocol MailSelectionDelegate: class {
func mailSelected(_ newMail: Mailing)
}
class MasterVC: UITableViewController{
@IBOutlet weak var SearchFooter: SearchFooter!
var filteredMail = [Mailing]()
var mail = [Mailing]()
var detailViewController: DetailVC? = nil
let searchController = UISearchController(searchResultsController: nil)
weak var delegate: MailSelectionDelegate?
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Mail Received Today"
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search"
navigationItem.searchController = searchController
definesPresentationContext = true
//scope bar
searchController.searchBar.scopeButtonTitles = ["###","###","###","###]
searchController.searchBar.delegate = self
//search footer
tableView.tableFooterView = SearchFooter
mail = [
Mailing(from: "###", to: "###",department: "###", trackingId: "019283", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "02346", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "056894", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "076767", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "098789", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "012345", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "021342", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from:"###", to: "###", department: "###", trackingId: "032312", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "034432", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "011211", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###",department: "###", trackingId: "099999", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "044323", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "098899", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "011211", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "084449", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "056788", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "022222", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from:"###", to: "###", department: "###", trackingId: "093753", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "01572", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailing(from: "###", to: "###", department: "###", trackingId: "059678", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false)
]
}
override func viewWillAppear(_ animated: Bool) {
if splitViewController!.isCollapsed {
if let selectionIndexPath = tableView.indexPathForSelectedRow {
tableView.deselectRow(at: selectionIndexPath, animated: animated)
}
}
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isFiltering() {
SearchFooter.setIsFilteringToShow(filteredItemCount: filteredMail.count, of: mail.count)
return filteredMail.count
}
SearchFooter.setNotFiltering()
return mail.count
}
func filterContentForSearchText(_ searchText: String, scope: String = "All") {
filteredMail = mail.filter({(mail: Mailing)-> Bool in
let doesMatch = (scope == "All") || (mail.trackingId == scope) || (scope == "TrackingID") || (mail.department == scope) || (scope == "Department")
// return mail.from.lowercased().contains(searchText.lowercased())
if searchBarIsEmpty() {
tableView.reloadData()
return doesMatch
// return mail.from.lowercased().contains(searchText.lowercased())
} else {
return doesMatch && mail.trackingId.lowercased().contains(searchText.lowercased()) || mail.from.lowercased().contains(searchText.lowercased()) || mail.department.lowercased().contains(searchText.lowercased())
}
})
tableView.reloadData()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let searchCell = tableView.dequeueReusableCell(withIdentifier: "searchCell", for: indexPath)
let searchMail: Mailing
if isFiltering() {
searchMail = filteredMail[indexPath.row]
} else {
searchMail = mail[indexPath.row]
}
searchCell.textLabel!.text = searchMail.from
searchCell.textLabel?.textAlignment = .center
return searchCell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let mails: Mailing
if isFiltering() {
mails = filteredMail[indexPath.row]
} else {
mails = mail[indexPath.row]
}
let controller = (segue.destination as! UINavigationController).topViewController as! DetailVC
controller.detailMail = mails
controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
}
func searchBarIsEmpty() -> Bool {
return searchController.searchBar.text?.isEmpty ?? true
}
func isFiltering() -> Bool {
let searchBarScopeIsFiltering = searchController.searchBar.selectedScopeButtonIndex != 0
return searchController.isActive && (!searchBarIsEmpty() || searchBarScopeIsFiltering)
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
let selectedMail = mail[indexPath.row]
delegate?.mailSelected(selectedMail)
if let detailViewController = delegate as? DetailVC,
let detailNavigationController = detailViewController.navigationController {
splitViewController?.showDetailViewController(detailNavigationController, sender: nil)
}
if isFiltering() {
tableView.reloadData()
let selectedMail = filteredMail[indexPath.row]
delegate?.mailSelected(selectedMail)
}
searchController.dimsBackgroundDuringPresentation = false
}
}
extension MasterVC: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
}
}
extension MasterVC: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
let searchBar = searchController.searchBar
let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
filterContentForSearchText(searchController.searchBar.text!, scope: scope)
}
}
这是masterViewController的detailViewController。当在主表中选择一个单元格时,便可以更新详细视图。
import UIKit
class DetailVC: UIViewController {
@IBOutlet weak var fromLabel: UILabel!
@IBOutlet weak var toLabel: UILabel!
@IBOutlet weak var deliveryDateLabel: UILabel!
@IBOutlet weak var trackingIdLabel: UILabel!
@IBOutlet weak var dateReceivedLabel: UILabel!
@IBOutlet weak var departmentLabel: UILabel!
@IBOutlet weak var signauteOnFile: UIImageView!
var mails: Mailing? {
didSet {
refreshUI()
}
}
var detailMail: Mailing? {
didSet {
configureView()
}
}
func refreshUI() {
loadViewIfNeeded()
fromLabel.text = mails?.from
toLabel.text = mails?.to
deliveryDateLabel.text = mails?.deliveryDate
trackingIdLabel.text = mails?.trackingId
dateReceivedLabel.text = mails?.receivedDate
departmentLabel.text = mails?.department
}
func configureView() {
if let detailMail = detailMail {
title = detailMail.from
}
}
override func viewDidLoad() {
super.viewDidLoad()
configureView()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
extension DetailVC: MailSelectionDelegate {
func mailSelected(_ newMails: Mailing){
mails = newMails
}
}
现在这是第二个拆分视图的第二个masterViewController: 在下面,您会注意到一些变量中有'typos'。这是我天真的尝试,以解决由于“无效的变量名重新声明”而引起的常量错误。为了解决这个问题,我只是在每个变量的末尾添加了一个“ s”,以使其有所不同。 也许正是在这里,我错过了一些天真尝试所弄乱的东西...
import UIKit
protocol MailSelectionDelegates: class {
func mailSelecteds(_ newMails: Mailings)
}
class MasterView2: UITableViewController, UISplitViewControllerDelegate {
@IBOutlet weak var SearchFooter2: SearchFooter2!
var mailsss = [Mailings]()
var filteredMails = [Mailings]()
var detailViewController: DetailVC2? = nil
let searchControllers = UISearchController(searchResultsController: nil)
weak var delegates: MailSelectionDelegates?
override func viewDidLoad() {
super.viewDidLoad()
self.title = "#####"
searchControllers.searchResultsUpdater = self
searchControllers.obscuresBackgroundDuringPresentation = false
searchControllers.searchBar.placeholder = "Search"
navigationItem.searchController = searchControllers
definesPresentationContext = true
searchControllers.searchBar.scopeButtonTitles = ["###","###","###"]
searchControllers.searchBar.delegate = self
tableView.tableFooterView = SearchFooterWarehouse
//fixingSplitViews
//this didnt do anything... grrr
self.splitViewController!.delegate = self
self.splitViewController!.preferredDisplayMode = UISplitViewControllerDisplayMode.allVisible
self.extendedLayoutIncludesOpaqueBars = true
mailsss = [
Mailings(from: "###", to: "###",department: "###", trackingId: "019283", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "02346", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "056894", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "076767", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "098789", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "012345", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "021342", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from:"###", to: "###", department: "###", trackingId: "032312", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "034432", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "011211", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###",department: "###", trackingId: "099999", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "044323", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "098899", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "011211", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "084449", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "056788", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "022222", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from:"###", to: "###", department: "###", trackingId: "093753", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "01572", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false),
Mailings(from: "###", to: "###", department: "###", trackingId: "059678", receivedDate: "02/12/2018", deliveryDate: "03/12/2018", signedFor: false, expanded: false)
]
}
override func viewWillAppear(_ animated: Bool) {
if splitViewController!.isCollapsed {
if let selectionIndexPaths = tableView.indexPathForSelectedRow {
tableView.deselectRow(at: selectionIndexPaths, animated: animated)
}
}
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isFilterings() {
SearchFooterWarehouse.setIsFilteringToShows(filteredItemCount: filteredMails.count, of: mailsss.count)
return filteredMails.count
}
SearchFooter2.setNotFilterings()
return mailsss.count
}
func filterContentForSearchTexts(_ searchText: String, scope: String = "All") {
filteredMails = mailsss.filter({(mailsss: Mailings)-> Bool in
let doesMatchs = (scope == "All") || (mailsss.trackingId == scope) || (scope == "TrackingID") ||
(mailsss.department == scope) || (scope == "Department")
if searchBarIsEmpty() {
tableView.reloadData()
return doesMatchs
} else {
return doesMatchs && mailsss.trackingId.lowercased().contains(searchText.lowercased()) || mailsss.from.lowercased().contains(searchText.lowercased()) || mailsss.department.lowercased().contains(searchText.lowercased())
}
})
tableView.reloadData()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let searchCells = tableView.dequeueReusableCell(withIdentifier: "searchingCell", for: indexPath)
let searchMails: Mailings
if isFilterings() {
searchMails = filteredMails[indexPath.row]
} else {
searchMails = mailsss[indexPath.row]
}
searchCells.textLabel!.text = searchMails.from
searchCells.textLabel?.textAlignment = .center
return searchCells
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
if let indexPaths = tableView.indexPathForSelectedRow {
let mailss: Mailings
if isFilterings() {
mailss = filteredMails[indexPaths.row]
} else {
mailss = mailsss[indexPaths.row]
}
let controllers = (segue.destination as! UINavigationController).topViewController as! DetailVC2
controllers.detailMails = mailss
controllers.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
controllers.navigationItem.leftItemsSupplementBackButton = true
}
}
}
func searchBarIsEmpty() -> Bool {
return searchControllers.searchBar.text?.isEmpty ?? true
}
func isFilterings() -> Bool {
let searchBarScopeIsFiltering = searchControllers.searchBar.selectedScopeButtonIndex != 0
return searchControllers.isActive && (!searchBarIsEmpty() || searchBarScopeIsFiltering)
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedMail = mailsss[indexPath.row]
delegates?.mailSelecteds(selectedMail)
if let detailViewController = delegates as? DetailVC2,
let detailNavigationController = detailViewController.navigationController {
splitViewController?.showDetailViewController(detailNavigationController, sender: nil)
}
print("step1")
tableView.reloadData()
if isFilterings() {
tableView.reloadData()
let selectedMail = filteredMails[indexPath.row]
delegates?.mailSelecteds(selectedMail)
}
searchControllers.dimsBackgroundDuringPresentation = false
// tableView.reloadRows(at: [indexPath], with: .fade)
}
func splitViewController(splitViewController: UISplitViewController, collapseSecondaryViewController secondaryViewController: UIViewController, ontoPrimaryViewController primaryViewController: UIViewController) -> Bool {
return true
}
}
extension MasterView2: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
filterContentForSearchTexts(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
}
}
extension MasterView2: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
let searchBar = searchControllers.searchBar
let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
filterContentForSearchTexts(searchController.searchBar.text!, scope: scope)
}
}
现在是第二个主视图控制器的第二个Detail视图控制器。
import UIKit
class DetailVC2: UIViewController {
@IBOutlet weak var fromLabels: UILabel!
@IBOutlet weak var toLabels: UILabel!
@IBOutlet weak var departmentLabels: UILabel!
@IBOutlet weak var deliveryDateLabels: UILabel!
@IBOutlet weak var trackingIdLabels: UILabel!
@IBOutlet weak var dateReceivedLabels: UILabel!
var wareMail: Mailings? {
didSet {
refreshUIS()
}
}
var detailMails: Mailings!{
didSet {
configureViews()
}
}
func refreshUIS() {
loadViewIfNeeded()
fromLabels.text = wareMail?.from
toLabels.text = wareMail?.to
deliveryDateLabels.text = wareMail?.deliveryDate
trackingIdLabels.text = wareMail?.trackingId
dateReceivedLabels.text = wareMail?.receivedDate
departmentLabels.text = wareMail?.department
}
func configureViews() {
if let detailMails = detailMails {
title = detailMails.from
}
}
override func viewDidLoad() {
super.viewDidLoad()
configureViews()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension DetailVC2: MailSelectionDelegates{
func mailSelecteds(_ newMails: Mailings) {
wareMail = newMails
}
}
我想念什么?
运行应用程序并选择第二个masterclass单元时,没有错误代码。