2016-10-04 5 views
0

Ich habe ein Modellobjekt namens PlayerStore, das ein Array von Player Objekten ist. Diese werden zum MainVC View Controller UITableView hinzugefügt. Hier kann ein Benutzer Player Objekte hinzufügen, die in UITableView angezeigt werden.Eine UIView anzeigen, wenn eine Variable eine Bedingung erfüllt

Ich habe ein UILabel, dass ein @IBOutletpressPlusLbl genannt ist, dass ich nur angezeigt werden soll, wenn gibt es keine in den PlayerStore links Spieler.

ich umgehen kann, dass leicht, wenn die Sicht Belastungen in ViewDidLoad mit so etwas wie:

override func viewDidLoad() { 
     super.viewDidLoad() 

     players = store.getAllPlayers() 
     emptyTableShowsLabel() 

    } 

    func emptyTableShowsLabel(){ 

     if !store.hasPlayers(){ 
      pressPlusLbl.isHidden = false 
      // TODO: maybe animate this view? 
      // TODO: hide the table 
     } else { 
      pressPlusLbl.isHidden = true 
      // TODO: bring back the table 
     } 
    } 

Aber ich meiner Ansicht-Controller immer wollen die Modellobjekte (PlayerStor) zu hören zu wissen, wann es leer ist: !store.hasPlayers() so dass ich die pressPlusLbl wieder anzeigen kann.

EDIT 1:

Weiß nicht, ob es relevant ist, aber hier ist einer der Orte, der Benutzer aus dem Tableview löschen:

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
    if (editingStyle == .delete){ 

     store.deletePlayer(row: indexPath.row) 
     players = store.getAllPlayers() 
     tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.bottom) 

    } 
} 

EDIT 2: Mit Blick auf Implementieren Sie ein Delegatenmuster aus dem PlayerStore. Hier ist, was ich gebaut habe, aber nicht funktioniert.

in MainVC.Swift (View-Controller) mit meinem vorhandenen Protokoll:

protocol PlayerIncrementor { 
    func increment(playerPosition: Int) 
    func decrement(playerPosition: Int) 
    func isStoreEmpty() 
} 

class MainVC: UIViewController, UITableViewDataSource, UITableViewDelegate, PlayerIncrementor { 

... 

    func isStoreEmpty() { 

     store.delegate = self 

     if store.hasPlayers() { 
      pressPlusLbl.isHidden = true 
     } else { 
      pressPlusLbl.isHidden = false 
     } 

    } 

} 

Im PlayerStore.swift (Modell)

class PlayerStore { 

... 

    var delegate: PlayerIncrementor! 

    private var _playerArray = [Player]() 

    func hasPlayers() -> Bool { 
     return !_playerArray.isEmpty 
    } 


... 

} 
+0

Wie wird die 'tableView' benachrichtigt, dass der Benutzer den' player' löscht –

+0

@ New16 den Code hinzugefügt. – Macness

+0

@Macness Bitte überprüfen Sie meine Antwort und antworten Sie – KSR

Antwort

1

Sie können das Delegiertenmuster verwenden.

protocol MainViewControllerDelegate { 
    func playersDidChange() 
} 

class MainViewController: UIViewController, MainViewControllerDelegate { 

    func playersDidChange() { 
     // Check store to determine if label is to be shown 
    } 
} 

Dann in Ihrem Player speichern einfach einen Verweis auf den Delegaten und delegate.playersDidChange Funktion aufrufen.

Wenn Sie einen Player aus Ihrem Player Store hinzufügen/entfernen, können Sie den Delegierten anrufen. Zum Beispiel

class PlayerStore { 

    func addPlayer(player: Player) { 
     // Add player to your array 
     delegate.playersDidChange() 
    } 

    func removePlayer(player: Player) { 
     // Remove player from your array 
     delegate.playersDidChange() 
    } 
} 

Also in Ihrer UITableViewDelegate Funktion,

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 

Durch den Aufruf store.removePlayer Funktion, Ihr Label isHidden wird vom MainViewControllerDelegate behandelt werden.

Außerdem müssen Sie store.delegate = self nur einmal setzen, wahrscheinlich gleich nachdem Sie den Store initialisiert haben.

+0

Ihre Lösung ist elegant und ich bin mir nicht sicher, ob ich es richtig mache. Ich habe meinen Code unter "Edit 2" in einem Versuch aktualisiert. Es funktioniert im Moment nicht. – Macness

+0

Ich habe meine Antwort gerade aktualisiert, hast du es versucht? – koropok

+0

aktualisiert und für eine einmalige Verwendung refaktoriert. Dies ist viel besser als das Kopieren eines laufenden Bool jedes Mal, wenn ich das Modell hinzufüge oder aus dem Modell entferne. – Macness

0

Anruf checkTableData() nach der Zeile zu löschen:

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
    if (editingStyle == .delete){ 

     store.deletePlayer(row: indexPath.row) 
     players = store.getAllPlayers() 
     tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.bottom) 
checkTableData() 

    } 
} 

func checkTableData() { 

       if !store.hasPlayers(){ 
         pressPlusLbl.isHidden = false 
         // TODO: maybe animate this view? 
         // TODO: hide the table 
        } else { 
         pressPlusLbl.isHidden = true 
         // TODO: bring back the table 
        } 


      } 

Vergessen Sie nicht, das TableView neu zu laden.

+0

Ich möchte nicht, dass der ViewController regelmäßig überprüft. Ich will, dass es weiß, dass es keine Spieler mehr gibt, wenn ich das Modell höre. – Macness

+0

Warte ich bearbeite – KSR

+0

das Problem mit diesem ist, dass ich jede Methode überprüfen muss, die Zeilen einfügt/löscht. Ich möchte das nicht jeder Methode hinzufügen - ich denke, ich suche hier einen Delegierten aus dem PlayerStore. – Macness

0

Der beste Weg, dies zu überprüfen, ist, wo Sie im Grunde die Datenquelle bearbeiten.Also, in Ihrem Fall numberOfRowsForSection, commitEditingStyle. Wenn Sie versuchen, ebenfalls einzufügen, müssen Sie möglicherweise die Beschriftung entfernen, wenn die Datenquellenanzahl höher wird.

Verwandte Themen