2016-07-10 26 views
0

我有一个基于Master-Detail模板的快速应用程序。 MasterView表中的每一行均基于从nib收到的自定义单元格。每个单元包括UIlabelUIbutton。该应用程序的逻辑如下。如果用户在行DetailView上点击显示取决于所选行的一些细节。该行上的按钮不叫tableView(_, didSelectRowAtIndexPath)。如果用户点击一行内的按钮,则只应更改图像属于DetailViewDetailView上的其他元素保持不变),但不是。如果我选择另一行并选择上一行,则更改的图像会显示在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! 
} 

回答

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

它可能是,这种解决方案过于复杂,但它的工作原理,容易能够适应各种用途。

+0

尽管您的方法正确,但我们通常不会使用授权进行主 - >详细通信。当detailView想**向主人回话时,我们使用代表团。 –

+0

@RayTso,我同意。但对于这个特定问题,它似乎是最好的解决方案。 –

+0

你*** ***知道我在谈论segues? –

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

而在你马西德威

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

+0

非常感谢。有用。但实际上,我发现了另一种解决方案,它似乎更加灵活,可以用于其他目的。请参阅我的意见 –