如何更新 DetailView

How to update DetailView

我有一个基于 Master-Detail 模板的 swift 应用程序。 MasterView table 中的每一行都基于从 nib 接收到的自定义单元格。每个单元格包括 UIlabelUIbutton。该应用程序的逻辑如下。如果用户点击一行 DetailView 会根据 selected 行显示一些详细信息。行上的按钮不调用 tableView(_, didSelectRowAtIndexPath)。如果用户点击一行内的按钮,则只有属于 DetailView 的图像应该更改(DetailView 上的其他元素保持不变)但事实并非如此。如果我 select 另一行而不是 select 前一行,则更改后的图像将按预期显示在 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!
}

您需要使用处理程序

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
            }
        }

来源:

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

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

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