Ios 在swift中跨不同视图控制器访问UI属性

Ios 在swift中跨不同视图控制器访问UI属性,ios,iphone,swift,uiviewcontroller,Ios,Iphone,Swift,Uiviewcontroller,在我的应用程序中,我有一个摘要页面,该页面将显示每个付款人的付款人摘要和收件人列表。也就是说,摘要页面的左侧将有一个列表,单击每个列表将在右侧(iPad)显示其详细信息。为了在iPhone版本中重复使用相同的代码,我将其作为单独的视图控制器。也就是说,我有一个基本的ViewController(SummaryViewController)。在此子视图中,我查看列表的ViewController(SummaryListViewController)和详细信息的ViewController(Summ

在我的应用程序中,我有一个摘要页面,该页面将显示每个付款人的付款人摘要和收件人列表。也就是说,摘要页面的左侧将有一个列表,单击每个列表将在右侧(iPad)显示其详细信息。为了在iPhone版本中重复使用相同的代码,我将其作为单独的视图控制器。也就是说,我有一个基本的ViewController(SummaryViewController)。在此子视图中,我查看列表的ViewController(SummaryListViewController)和详细信息的ViewController(SummaryDetailViewController)。现在,当基本视图控制器SummaryViewController加载时,我将子视图列表和详图视图控制器,如下所示

//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)
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)
//DetailView是基本ViewController中的一个视图,我在其中子视图Detail 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)
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)
现在,问题是,我必须从SummaryListViewController的tableView didSelectRow调用SummaryDetailViewController中的一个方法,该方法将根据我发送的数据更新UI元素

为了实现这一目标,我尝试了以下几点:

  • 我尝试在NotificationCenter中使用addObserver。当我点击列表时,我添加了一个观察者。该观察者触发detailViewController中的方法,该方法将更新UI元素。但这并不总是奏效。当我进入摘要页面时,请返回,如果我再次进入摘要页面并执行相同操作,则即使在ViewDidInviser中删除了观察者,也会调用观察者两次。我还从一些网站了解到,NotificationCenter不应该用于这种情况

  • 第二,我尝试使用协议。我想我应该在SummaryListViewController中编写一个协议

  • 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)
    
    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)
    
    现在在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)
    }
    

    有谁能帮我摆脱这个困境吗?协议解决方案是最好的。你可以这样用

    SummaryListViewController文件:

    protocol SummaryDetailProtocol {
        func setSummaryDetails()
    }
    
    class SummaryListViewController: UIViewController
    {
        var summaryDetailsDelegate : SummaryDetailProtocol?
    
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
        {
            self.summaryDetailsDelegate?.setSummaryDetails()//use here
        }
    }
    
    class SummaryDetailViewController: UIViewController,SummaryDetailProtocol
    {
        internal func setSummaryDetails() {
            //return whatever you want
        }
    
    
    }
    
    SummaryDetailViewController文件:

    protocol SummaryDetailProtocol {
        func setSummaryDetails()
    }
    
    class SummaryListViewController: UIViewController
    {
        var summaryDetailsDelegate : SummaryDetailProtocol?
    
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
        {
            self.summaryDetailsDelegate?.setSummaryDetails()//use here
        }
    }
    
    class SummaryDetailViewController: UIViewController,SummaryDetailProtocol
    {
        internal func setSummaryDetails() {
            //return whatever you want
        }
    
    
    }
    
    最后将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