【问题标题】:Access UI properties across different View Controllers in swift快速访问不同视图控制器的 UI 属性
【发布时间】:2017-01-30 14:10:25
【问题描述】:

在我的应用程序中,我有一个摘要页面,其中将显示每个付款人的付款人和收件人列表的摘要。也就是说,摘要页面将在左侧有一个列表,单击每个列表将在右侧(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)

//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)

现在,问题是,我必须从 SummaryListViewController 的 tableView-didSelectRow 调用 SummaryDetailViewController 中的一个方法,该方法将根据我发送的数据更新 UI 元素。

我已经尝试了以下方法来实现这一点,

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

  2. 其次,我正在尝试使用协议。我以为我会在 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
    }
}

现在在SummaryDetailViewController的ViewDidLoad中,我想把delegate的引用发送给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)
}

谁能帮我摆脱困境

【问题讨论】:

    标签: ios iphone swift uiviewcontroller


    【解决方案1】:

    协议解决方案是最好的。你可以这样使用

    SummaryListViewController 文件:

    protocol SummaryDetailProtocol {
        func setSummaryDetails()
    }
    
    class SummaryListViewController: UIViewController
    {
        var summaryDetailsDelegate : SummaryDetailProtocol?
    
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
        {
            self.summaryDetailsDelegate?.setSummaryDetails()//use here
        }
    }
    

    SummaryDetailViewController 文件:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多