如何更新DetailView

时间:2016-07-10 21:23:29

标签: ios swift master-detail redraw

我有一个基于Master-Detail模板的快速应用。 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!
}

2 个答案:

答案 0 :(得分:0)

您需要使用处理程序

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

答案 1 :(得分:0)

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

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

很可能这个解决方案过于复杂,但它的工作原理和简单性可以用于各种目的。