2016-07-10 21 views
0

Ich habe eine schnelle App basierend auf Master-Detail Vorlage. Jede Zeile in der Tabelle MasterView basiert auf einer benutzerdefinierten Zelle, die von einer Schreibfeder empfangen wurde. Jede Zelle enthält UIlabel und UIbutton. Die Logik der App folgt. Wenn der Benutzer auf eine Zeile tippt, zeigt DetailView je nach ausgewählter Zeile einige Details an. Die Schaltfläche in der Zeile ruft tableView(_, didSelectRowAtIndexPath) nicht auf. Wenn der Benutzer auf die Schaltfläche innerhalb einer Zeile klickt, sollte nur ein Bild zu DetailView geändert werden (andere Elemente auf DetailView bleiben gleich), aber es ist nicht. Wenn ich eine andere Zeile auswähle und dann die vorherige Zeile zurück wähle, wird das geänderte Bild auf der DetailView angezeigt, wie es vorhergesehen wurde. Die Frage ist, wie man das Bild in der DetailView nur durch Tippen auf die Schaltfläche neu zu zeichnen. Ich habe versucht, folgendes zu tun, aber ohne Erfolg:So aktualisieren Sie 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! 
} 

Antwort

0

Ich habe die Lösung gefunden. Ich habe Protokoll-Delegierten-Mechanismus verwendet. Jetzt ist der Code:

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

Es kann gut sein, dass diese Lösung zu komplex ist, aber es funktioniert und einfach für verschiedene Zwecke angepasst werden könnte.

+0

Während Ihre Methode korrekt ist, verwenden wir oft keine Delegationen für Master-> Detailkommunikation. Wir verwenden Delegationen, wenn die Detailansicht ** mit dem Master ** sprechen möchte. –

+0

@RayTso, stimme ich zu. Aber für dieses spezifische Problem scheint es die beste Lösung zu sein. –

+0

Sie *** do *** wissen, ich spreche über Übergänge? –

0

Sie benötigen einen 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) 
    } 
} 

zu verwenden und in Ihrem Master

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

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

+0

Vielen Dank. Es klappt. Aber tatsächlich habe ich eine andere Lösung gefunden, die flexibler erscheint und für andere Zwecke angepasst werden könnte. Siehe meinen Kommentar unter –