1

我通过谷歌和SO搜索了很多,所以请原谅我,如果这个问题已经回答了!

问题: 我有一个UICollectionViewwith n UICollectionViewCells。每个单元格都包含一个UIView来自 XIB 文件的内容。视图用于数据输入,因此所有单元格都有一个唯一的reuseIdentifier. 每个 View 也有一个独特的restorationIdentifier. 一切正常使用,但在状态恢复时却不行:

前 3 或 4 个单元格正在正确恢复,因为它们在启动时在屏幕上可见,但其余不可见的单元格没有得到恢复。

当前解决方案: 所以到目前为止,我发现只有在启动时将视图添加到用户界面时才会恢复视图。我目前的工作解决方案是在恢复过程中将所有单元格的高度设置为 1。现在每个单元格都已加载,所有视图都已恢复。当applicationFinishedRestoringState()被调用时,我用正确的高度重新加载 CollectionView。

现在我的问题是:我对这个解决方案不满意,有没有更干净的方法来实现所有 UIView 的恢复?

4

1 回答 1

1

我认为您在数据模型和视图之间有些困惑。首次初始化时,您的表格视图是从数据模型构造的,提取存储的值以填充每个单元格中的任何内容。但是,您的用户不直接与数据模型交互,而是与屏幕上的视图交互。如果用户更改了表格视图中的某些内容,您需要将该更改发回给视图控制器,以便它可以记录对数据模型的更改。这反过来意味着,如果需要重新创建视图,则视图控制器具有重建应用程序进入后台时表中的任何内容所需的信息。

我在这里整理了一个简单的 gitHub 存储库:https ://github.com/mpj-chandler/StateManagementDemo

这包括一个 CustomTableViewController 类,该类管理一个填充有 CustomTableViewCells 的标准 UITableView。自定义单元格包含三个开关按钮,允许每个单元格的状态由布尔值数组表示。

我为单元创建了一个委托协议,这样如果任何开关被触发,就会向视图控制器发送一个信号:

protocol CustomTableViewCellDelegate {
    func stateDidChange(sender: CustomTableViewCell) -> Void
}

// Code in CustomTableViewCell.swift:

@objc fileprivate func switched(sender: UISwitch) -> Void {

    guard let index : Int = switches.index(of: sender) else { return }

    state[index] = sender.isOn   
}

// The cell's state is an observed parameter with the following didSet method:

fileprivate var state : [Bool] = Array(repeating: false, count: 3) {
    didSet {
        if state != oldValue, let _ = delegate {
            delegate!.stateDidChange(sender: self)
        }
    }
}

CustomTableViewController 注册到 CustomTableViewCellDelegate 协议中,这样就可以记录模型中的变化,如下:

// Code in CustomTableViewController.swift

//# MARK:- CustomTableViewCellDelegate methods

internal func stateDidChange(sender: CustomTableViewCell) -> Void {
    guard let indexPath : IndexPath = tableView.indexPath(for: sender) else { return }
    guard indexPath.row < model.count else { print("Error in \(#function) - cell index larger than model size!") ; return }

    print("CHANGING MODEL ROW [\(indexPath.row)] TO: \(sender.getState())")
    model[indexPath.row] = sender.getState()

}

您可以在此处看到该功能已设置为将模型更改输出到控制台。

如果您在模拟器中运行项目并退出到主屏幕并再次返回,您将看到 tableView 单元格的状态被保留,因为模型反映了应用程序进入后台之前所做的更改。

希望有帮助。

于 2017-09-22T11:24:34.627 回答