自动更新
一个简单的面向协议的框架,用于编写易于更新的,数据驱动的视图。
通讯协定
我使用的协议叫做Unit
因为我制作的游戏涉及战争内容。
模型协议
protocol Unit { var name: String { get set } var id: String { get } var status: UnitStatus { get set } }
我还需要能够等同于它们。
func ==(lhs: Unit?, rhs: Unit?) -> Bool { return (lhs?.id == rhs?.id) }
现在,我将创建一个简单的struct
以符合我的Unit
协议。
struct Hero: Unit { var id: String var name: String var status: UnitStatus }
查看协议
接下来是我用于显示Unit
视图协议。 这将令人震惊地称为UnitView
。
protocol UnitView { var unit: Unit? { get } func prepare(withUnit unit: Unit?) }
我可以在协议中添加任何内容,但是魔术发生在prepare(withUnit unit: Unit?)
。 我将所有视图更新代码都放在了prepare(withUnit unit: Unit?)
,我很高兴。
我需要扩展UnitView
协议(您也可以执行UIViewControllers),以便可以调用autoUpdate()
,这使视图成为数据存储更新的观察者。
extension UnitView where Self: UIView { func autoUpdate() { NotificationCenter.default.addObserver(forName: NSNotification.Name.objectUpdated, object: nil, queue: OperationQueue.main) { [weak self] (notification: Notification) in guard let unit = notification.userInfo?["unit"] as? Unit else { return } if self?.unit == unit { self?.unit = unit self?.prepare(withUnit: unit) } } } }
在视图初始化中调用autoUpdate()
函数后,视图(或视图控制器)将自行更新。
这是一个符合UnitView
可以自动更新的UICollectionViewCell
的示例。
class UnitCollectionViewCell: UICollectionViewCell, UnitView { var unit: Unit? @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var statusLabel: UILabel! override func awakeFromNib() { super.awakeFromNib() autoUpdate() } func prepare(withUnit unit: Unit?) { self.nameLabel.text = unit?.name self.statusLabel.text = unit?.face() } override func prepareForReuse() { super.prepareForReuse() prepare(withUnit: unit) } }
数据存储
自动更新框架的另一个关键组件是一个数据存储,用于向我们的UnitView
发送通知。
这就是我需要的简单数据存储。
class DataStore { static let shared = DataStore() func update(object: Unit?) { guard let updatedUnit = object else { return } // save the object in whatever way you need to // notifies our UnitViews that a Unit was updated NotificationCenter.default.post(name: NSNotification.Name.objectUpdated, object: nil, userInfo: [Constants.objectKey: updatedUnit]) } }
图表
👍