在swift中

时间:2017-01-30 14:10:25

标签: ios iphone swift uiviewcontroller

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

子视图列表和详细视图控制器

// ListView是基础ViewController中的一个视图,i子视图列表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元素的方法。但这并不是一直都有效。当我进入Summary页面时,返回并且如果我再次进入摘要页面并执行相同操作,即使在ViewDidDisapper中删除观察者之后,观察者也会被调用两次。此外,我在少数几个网站上了解到NotificationCenter不应该用于这种情况。

  2. 其次,我试图使用协议。我以为我会在SummaryListViewController

  3. 中编写一个协议
    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中,我想将委托的引用发送到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)
    }
    

    任何人都可以帮我摆脱这个

1 个答案:

答案 0 :(得分:0)

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

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