2016-07-10 24 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

非常感謝。有用。但實際上,我發現了另一種解決方案,它似乎更加靈活,可以用於其他目的。請參閱我的意見 –