How to update DetailView

為{幸葍}努か 提交于 2019-12-12 01:43:43

问题


I have a swift app based on Master-Detail template. Every row in MasterView table is based on custom cell received from a nib. Every cell includes UIlabel and UIbutton. The logic of the app is following. If user taps on a row DetailView shows some details depending on selected row. The button on the row does not call tableView(_, didSelectRowAtIndexPath). If user taps on the button inside a row only an image belongs to DetailView should be changed (other elements on DetailView remain the same) but it isn't. If I select another row and than select previous row back, changed image is shown on the DetailView as it was foreseen. The question is how to redraw the image in the DetailView just by tapping on the button. I've tried to do following but with no success:

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

回答1:


You need to use a handler

typealias ButtonHandler = (Cell) -> Void

class Cell: UITableViewCell {

    var changeImage: ButtonHandler?

    func configureButton(changeImage: ButtonHandler?) {
        self.changeImage = changeImage
    }


    @IBAction func buttonTap(sender: UIButton) {
        changeImage?(self)
    }
}

And in your 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
            }
        }

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




回答2:


I've found the solution. I've used protocol-delegate mechanism. Now the code is:

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

It may well be that this solution is excessively complex, but it works and easy could be adapted for various purposes.



来源:https://stackoverflow.com/questions/38296588/how-to-update-detailview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!