【问题标题】:How to update DetailView如何更新 DetailView
【发布时间】:2016-11-12 18:56:47
【问题描述】:

我有一个基于 Master-Detail 模板的 swift 应用程序。 MasterView 表中的每一行都基于从笔尖接收的自定义单元格。每个单元格都包含UIlabelUIbutton。该应用程序的逻辑如下。如果用户点击行DetailView 会根据所选行显示一些详细信息。行上的按钮不调用tableView(_, didSelectRowAtIndexPath)。如果用户点击一行内的按钮,则只有属于DetailView 的图像应更改(DetailView 上的其他元素保持不变)但事实并非如此。如果我选择另一行而不是选择前一行,则更改后的图像将显示在DetailView 上,正如预期的那样。问题是如何通过点击按钮重绘DetailView 中的图像。 我尝试过以下操作,但没有成功:

class MasterViewCell: UITableViewCell {
   weak var detailViewController: DetailViewController?

   @IBAction func buttonTap(sender: AnyObject) {
       //method to set new image
       detailViewController!.setNewImage()
       detailViewController!.view.setNeedsDisplay()    
   }
}

class MasterViewController: UITableViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let nib = UINib(nibName: "itemCell", bundle: nil)
        tableView.registerNib(nib, forCellReuseIdentifier: "Cell")
        if let split = self.splitViewController {
            let controllers = split.viewControllers
            self.detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
        }
    }

   override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as? MasterViewCell
        cell?.detailView = self.detailViewController
        return cell!
}

【问题讨论】:

    标签: ios swift master-detail redraw


    【解决方案1】:

    我找到了解决方案。我使用了协议委托机制。现在代码是:

    //protocol declaration:
    protocol MasterViewCellDelegate: class {
      func updateImage(sender: MasterViewCell, detVC: DetailViewController)
    }
    // cell class
    class MasterViewCell: UITableViewCell {
       weak var masterViewCellDelegate: MasterViewCellDelegate?  // protocol property
       weak var masterViewController: MasterViewController? {
         didSet {
            // set delegate
            self.masterViewDelegate = masterViewController!.detailViewController
         }
       }
    
       @IBAction func buttonTap(sender: AnyObject) {
         var detVC: DetailViewController?
         if let split = masterViewController!.splitViewController {
            let controllers = split.viewControllers
            detVC = (controllers[controllers.count - 1] as! UINavigationController).topViewController as? DetailViewController
       }
       // call delegate 
       masterViewCellDelegate?.updateImage(self, detVC: detVC)
    }
    
    class MasterViewController: UITableViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            let nib = UINib(nibName: "itemCell", bundle: nil)
            tableView.registerNib(nib, forCellReuseIdentifier: "Cell")
            if let split = self.splitViewController {
                let controllers = split.viewControllers
                self.detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
            }
        }
    
       override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as? MasterViewCell
            cell?.masterViewController = self
            return cell!
    }
    
    // declare detailviewcontroller as delegate 
    class DetailViewController: UIViewController, MasterViewCellDelegate {
      func updateImage(sender: MasterViewCell, detVC: DetailViewController){
        detVC.setNewImage()
      }
    }
    

    这个解决方案很可能过于复杂,但它很有效,而且很容易适应各种用途。

    【讨论】:

    • 虽然您的方法是正确的,但我们通常不使用委托进行主->从通信。当 detailView 想要 回话 与 master 时,我们使用委托。
    • @RayTso,我同意。但是对于这个特定的问题,它似乎是最好的解决方案。
    • 确实知道我说的是segues吗?
    • @RayTso,我以为我们在谈论代表团。我开始认为这没有让你明白。
    • 对于 master 到 detail 通信:segues,对于 detail 到 master 通信:代表团。但是您不必必须这样做,通常就是这样做。
    【解决方案2】:

    您需要使用处理程序

    typealias ButtonHandler = (Cell) -> Void
    
    class Cell: UITableViewCell {
    
        var changeImage: ButtonHandler?
    
        func configureButton(changeImage: ButtonHandler?) {
            self.changeImage = changeImage
        }
    
    
        @IBAction func buttonTap(sender: UIButton) {
            changeImage?(self)
        }
    }
    

    在您的 MasterView 中

     override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
                let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! Cell
    
                cell.configureButton(setNewImage())
    
                return cell
            }
    
            private func setNewImage() -> ButtonHandler {
                return { [unowned self] cell in
                    let row = self.tableView.indexPathForCell(cell)?.row //Get the row that was touched
                    //set the new Image
                }
            }
    

    来源:iOS Swift, Update UITableView custom cell label outside of tableview CellForRow using tag

    【讨论】:

    • 非常感谢。有用。但实际上我找到了另一种解决方案,它看起来更灵活,可以适应其他目的。请参阅下面的评论
    猜你喜欢
    • 2021-05-15
    • 1970-01-01
    • 2021-03-25
    • 2020-08-31
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    • 2019-12-29
    • 2017-09-12
    相关资源
    最近更新 更多