【问题标题】:Show a UIView when a variable meets a condition当变量满足条件时显示 UIView
【发布时间】:2016-10-04 04:03:59
【问题描述】:

我有一个名为PlayerStore 的模型对象,它是Player 对象的数组。这些被添加到MainVC 视图控制器的UITableView。在这里,用户可以添加Player 显示在UITableView 中的对象。

我有一个UILabel,它是一个名为pressPlusLbl@IBOutlet,我只想在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

编辑 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)

    }
}

编辑 2: 希望从PlayerStore 实现委托模式。以下是我所构建但不太有效的内容。

MainVC.Swift(视图控制器)中使用我现有的协议:

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
    }


...

}

【问题讨论】:

  • tableView 如何收到用户删除player 的通知
  • @New16 添加了代码。
  • @Macness 请检查我的回答并回复

标签: ios swift uiviewcontroller uilabel swift3


【解决方案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,可能就在您初始化存储之后。

【讨论】:

  • 您的解决方案很优雅,但我不确定我是否做得对。我尝试在“编辑 2”下更新了我的代码。暂时无法使用。
  • 对其进行了更新和重构以供一次性使用。这比我每次在模型中添加或删除时复制一个正在运行的布尔值要好得多。
【解决方案2】:

检查这一点的最佳方法是基本上编辑数据源。所以,在你的情况下numberOfRowsForSectioncommitEditingStyle。如果您也尝试插入,如果数据源计数增加,您可能需要删除标签。

【讨论】:

    【解决方案3】:

    删除行后调用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。

    【讨论】:

    • 我不希望 ViewController 定期检查。我想让它通过听模型知道没有更多的玩家。
    • 这个问题是我必须检查每个插入/删除行的方法。我不想将它添加到每个方法中 - 我想我正在从 PlayerStore 中寻找一个委托。
    猜你喜欢
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    • 2020-10-04
    • 2022-01-22
    相关资源
    最近更新 更多