Reputation: 1226
I have a model object called PlayerStore
which is an array of Player
objects. These get added to the MainVC
view controller's UITableView
. Here a user can add Player
objects that are displayed in UITableView
.
I have a UILabel
that is an @IBOutlet
called pressPlusLbl
that I want to only display when there are no players left in the PlayerStore
.
I can handle that easily when the view loads in ViewDidLoad
with something like:
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
}
}
But I always want my view controller to listen to the model objects (PlayerStore) to know when it's empty: !store.hasPlayers()
so that I can display the pressPlusLbl
again.
EDIT 1:
Don't know if it's relevant, but here's one of the places the user can delete from the 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:
Looking to implement a delegate pattern from the PlayerStore
. Here's what I have that builds but doesn't quite work.
in MainVC.Swift
(View Controller) using my existing protocols:
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
}
}
}
In the PlayerStore.swift
(Model)
class PlayerStore {
...
var delegate: PlayerIncrementor!
private var _playerArray = [Player]()
func hasPlayers() -> Bool {
return !_playerArray.isEmpty
}
...
}
Upvotes: 0
Views: 157
Reputation: 1413
You can use the Delegate pattern.
protocol MainViewControllerDelegate {
func playersDidChange()
}
class MainViewController: UIViewController, MainViewControllerDelegate {
func playersDidChange() {
// Check store to determine if label is to be shown
}
}
Then in your player store simply create a reference to the delegate and call delegate.playersDidChange function.
When you add/remove a player from your player store, you can call the delegate. For example,
class PlayerStore {
func addPlayer(player: Player) {
// Add player to your array
delegate.playersDidChange()
}
func removePlayer(player: Player) {
// Remove player from your array
delegate.playersDidChange()
}
}
So in your UITableViewDelegate function,
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
By calling store.removePlayer function, your label isHidden will be handled by the MainViewControllerDelegate.
Also, you just have to set store.delegate = self once, probably right after you initialised the store.
Upvotes: 1
Reputation: 1709
Call checkTableData() after deleting the row:
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
}
}
Don't forget to reload the tableView.
Upvotes: 0
Reputation: 1767
The best way to check this is where you basically editing the datasource. So, in your case numberOfRowsForSection
, commitEditingStyle
. If you try to insert also, you may need to remove the label if the datasource count goes higher.
Upvotes: 0