简体   繁体   English

快速访问不同View Controller中的UI属性

[英]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, 为了达到这个目的,我尝试了以下方法:

  1. 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不应用于这种情况。

  2. 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.

相关问题 UIAlertController 作为跨视图控制器访问的通用函数 - UIAlertController as a common function to access across view controllers 如何在Swift中子类化不同的View Controller - How to subclass different View Controllers in Swift 使用swift在不同的视图控制器之间切换 - Switch between different view controllers using swift 如何创建跨不同视图控制器使用的可重用警报视图? - How to create a reusable alert view used across different view controllers? 如何跨视图控制器访问蓝牙数据? 在xcode中 - How to access bluetooth data across view controllers? in xcode 为什么UI元素以快速的编程方式在视图控制器之间共享? - Why the ui elements are shared between view controllers in swift programmatic way? iOS-如何在Swift中的不同视图控制器中使用小视图 - iOS - How to use a small view in different view controllers in Swift 根据选择的选项为视图控制器提供不同的视图:Swift 4 - Presenting View Controllers with a different view depending on which option is selected: Swift 4 如何使用TableView项访问Swift 2中的View Controller? - How can you use TableView items to access View Controllers in Swift 2? iOS / Swift-每天最多只能访问一次视图控制器 - iOS / Swift - Limiting access to view controllers to once per day
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM