2016-10-04 6 views
0

У меня есть объект модели, называемый PlayerStore, который представляет собой массив объектов Player. Они добавляются в контроллер MainVC для просмотра UITableView. Здесь пользователь может добавить Player объектов, которые отображаются в UITableView.Показать UIView, когда переменная соответствует условию

У меня есть UILabel, который является @IBOutlet называется pressPlusLbl, что я хочу, чтобы отображать только когда нет игроков осталось в PlayerStore.

Я могу справиться с этим легко, когда вид нагрузки в ViewDidLoad с чем-то вроде:

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

Но я всегда хочу, чтобы мой взгляд контроллер для прослушивания объектов модели (PlayerStore), чтобы знать, когда он пуст: !store.hasPlayers() так что я могу снова отобразить pressPlusLbl.

EDIT 1:

Не знаю, если это уместно, но вот один из тех мест, пользователь может удалить из TableView:

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: Заглядывая реализовать шаблон делегата из PlayerStore. Вот что я имею, что строит, но не совсем работает.

в MainVC.Swift (View Controller) с помощью моих существующих протоколов:

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 
     } 

    } 

} 

В PlayerStore.swift (модель)

class PlayerStore { 

... 

    var delegate: PlayerIncrementor! 

    private var _playerArray = [Player]() 

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


... 

} 
+0

Как «tableView» получает уведомление о том, что пользователь удалил «player» –

+0

@ New16, добавил код. – Macness

+0

@Macness Пожалуйста, проверьте мой ответ и ответ – KSR

ответ

1

Вы можете использовать шаблон делегирования.

protocol MainViewControllerDelegate { 
    func playersDidChange() 
} 

class MainViewController: UIViewController, MainViewControllerDelegate { 

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

Затем в магазине плеера просто создайте ссылку на делегат и вызовите функцию delegate.playersDidChange.

Когда вы добавляете/удаляете игрока из магазина плеера, вы можете позвонить делегату. Например,

class PlayerStore { 

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

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

Таким образом, в вашей функции UITableViewDelegate,

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

Вызывая функцию store.removePlayer, ваша метка IsHidden будет обрабатываться MainViewControllerDelegate.

Кроме того, вам просто нужно установить store.delegate = self один раз, возможно, сразу после инициализации магазина.

+0

Ваше решение элегантно, и я не уверен, что делаю все правильно. Я обновил свой код в разделе «Редактировать 2» в попытке. Сейчас он не работает. – Macness

+0

Я обновил свой ответ только сейчас, вы попробовали? – koropok

+0

обновил его и реорганизовал для одного использования. Это намного лучше, чем копирование работающего bool каждый раз, когда я добавляю или удаляю из модели. – Macness

0

Вызов checkTableData() после удаления строки:

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 
        } 


      } 

Не забудьте перезагрузить tableView.

+0

Я не хочу, чтобы ViewController периодически проверял. Я хочу, чтобы он знал, что больше нет игроков, слушая модель. – Macness

+0

wait Я редактирую – KSR

+0

Проблема заключается в том, что я должен проверять каждый метод, который вставляет/удаляет строки. Я не хочу добавлять это к каждому методу - я думаю, что ищу делегата здесь из PlayerStore. – Macness

0

Лучший способ проверить это, где вы в основном редактируете источник данных.Итак, в вашем случае numberOfRowsForSection, commitEditingStyle. Если вы попытаетесь вставить также, вам может потребоваться удалить ярлык, если количество источников данных будет выше.

Смежные вопросы