[英]Access UI properties across different View Controllers in swift
In my app, I have a summary page which will display the summary of payers and recipients list of each payer. 在我的应用程序中,我有一个摘要页面,该页面将显示付款人的摘要以及每个付款人的收件人列表。 That is, the summary page will have a list in the left side and clicking on each list will show its details on the right side(iPad).
也就是说,摘要页面的左侧将有一个列表,单击每个列表将在右侧显示其详细信息(iPad)。 In order to re-use the same code for iPhone version too, I have it as separate view controllers.
为了也为iPhone版本重新使用相同的代码,我将其作为单独的视图控制器。 That is, I have a base ViewController(SummaryViewController).
也就是说,我有一个基本的ViewController(SummaryViewController)。 In this i subview the ViewController of the list(SummaryListViewController) and ViewController of the details(SummaryDetailViewController).
在此子视图中,列表的ViewController(SummaryListViewController)和详细信息的ViewController(SummaryDetailViewController)。 Now, when the base view controller SummaryViewController loads, i subview the list and detail view controllers like this
现在,当基本视图控制器SummaryViewController加载时,我会像这样子查看列表和详细信息视图控制器
//ListView is a view in the base ViewController to which i subview the list ViewController // ListView是基本ViewController中的一个视图,我将列表ViewController子视图到该视图
let listViewController = SummaryListViewController(nibName:"SummaryListViewController", bundle: nil)
addChildViewController(listViewController)
listViewController.view.frame = CGRect(x: 0, y: 0, width: self.ListView.frame.size.width, height: self.ListView.frame.size.height)
ListView.addSubview(listViewController.view)
listViewController.didMove(toParentViewController: self)
//DetailView is a view in the base ViewController to which i subview the Detail ViewController // DetailView是基本ViewController中的一个视图,我可以将Detail ViewController子视图到该视图
let detailViewController = SummaryDetailViewController(nibName: (UIDevice.current.userInterfaceIdiom == .pad ? "SummaryDetailViewController" : "SummaryDetailViewController_iPhone"), bundle: nil)
addChildViewController(detailViewController)
DetailView.frame = CGRect(x: DetailView.frame.origin.x, y: DetailView.frame.origin.y, width: self.DetailView.frame.size.width, height: self.DetailView.frame.size.height)
DetailView.addSubview(detailViewController.view)
detailViewController.didMove(toParentViewController: self)
Now, the prob is, I have to call a method in the SummaryDetailViewController from the tableView-didSelectRow of SummaryListViewController which will update the UI elements according to the data i send. 现在,问题是,我必须从SummaryListViewController的tableView-didSelectRow调用SummaryDetailViewController中的方法,该方法将根据我发送的数据更新UI元素。
I have tried the following things to achieve this, 为了达到这个目的,我尝试了以下方法:
I tried using addObserver in NotificationCenter. 我尝试在NotificationCenter中使用addObserver。 When i click on the list, i added an observer.
当我单击列表时,我添加了一个观察者。 And this observer triggers the method in the detailViewController that will update the UI elements.
这个观察者触发了detailViewController中的方法,该方法将更新UI元素。 But this doesn't work well all the time.
但这并不总是有效。 When i come to Summary page, go back and if i come again to summary page and do the same, the observer is called twice even after removing the observer in ViewDidDisapper.
当我进入“摘要”页面时,请返回,如果我再次来到“摘要”页面并执行相同的操作,即使在ViewDidDisapper中删除了观察者后,该观察者也会被调用两次。 And also i learnt in few websites that NotificationCenter should not be used for this kind of a situation.
而且我在一些网站上了解到,NotificationCenter不应用于这种情况。
Second, Am trying to use protocols. 第二,我试图使用协议。 I thought i would write a protocol in the SummaryListViewController
我以为我会在SummaryListViewController中写一个协议
protocol SummaryDetailProtocol { func setSummaryDetails() }
class SummaryListViewController: UIViewController
{
var summaryDetailsDelegate : SummaryDetailProtocol?
func delegateFromSummaryDetails(delegate: SummaryDetailProtocol)
{
self.summaryDetailsDelegate = delegate
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
self.summaryDetailsDelegate?.setSummaryDetails()
}
func delegateFromSummaryDetails(delegate: SummaryDetailProtocol)
{
self.summaryDetailsDelegate = delegate
}
}
Now in the ViewDidLoad of the SummaryDetailViewController, I would like to send the reference of the delegate to the listViewController so that the listViewController can call the setSummaryDetails method. 现在,在SummaryDetailViewController的ViewDidLoad中,我想将委托的引用发送到listViewController,以便listViewController可以调用setSummaryDetails方法。
override func viewDidLoad()
{
super.viewDidLoad()
sendDelegateReferenceToListPage()
}
func sendDelegateReferenceToListPage()
{
let summaryListObj = SummaryListView()
//This is where the error occurs. It throws the error since i try to cast SummaryDetailViewController to parameter of type SummaryDetailProtocol of SummaryListViewController
summaryListObj.delegateFromSummaryDetails(delegate: self as! SummaryDetailProtocol)
}
Can anyone help me to get out of this 谁能帮助我摆脱困境
Protocol solution is the best. 协议解决方案是最好的。 You can use like this
你可以这样使用
SummaryListViewController file: SummaryListViewController文件:
protocol SummaryDetailProtocol {
func setSummaryDetails()
}
class SummaryListViewController: UIViewController
{
var summaryDetailsDelegate : SummaryDetailProtocol?
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
self.summaryDetailsDelegate?.setSummaryDetails()//use here
}
}
SummaryDetailViewController file: SummaryDetailViewController文件:
class SummaryDetailViewController: UIViewController,SummaryDetailProtocol
{
internal func setSummaryDetails() {
//return whatever you want
}
}
And finally set SummaryListViewController delegate to SummaryDetailViewController: 最后将SummaryListViewController委托设置为SummaryDetailViewController:
let detailViewController = SummaryDetailViewController(nibName: (UIDevice.current.userInterfaceIdiom == .pad ? "SummaryDetailViewController" : "SummaryDetailViewController_iPhone"), bundle: nil)
addChildViewController(detailViewController)
DetailView.frame = CGRect(x: DetailView.frame.origin.x, y: DetailView.frame.origin.y, width: self.DetailView.frame.size.width, height: self.DetailView.frame.size.height)
DetailView.addSubview(detailViewController.view)
detailViewController.didMove(toParentViewController: self)
let listViewController = SummaryListViewController(nibName:"SummaryListViewController", bundle: nil)
addChildViewController(listViewController)
listViewController.view.frame = CGRect(x: 0, y: 0, width: self.ListView.frame.size.width, height: self.ListView.frame.size.height)
ListView.addSubview(listViewController.view)
listViewController.didMove(toParentViewController: self)
listViewController.summaryDetailsDelegate = detailViewController // set delegate detail view controller
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.