Wil*_*ken 9 model-view-controller ios swift
我从CS193P课程中学到了Swift.它建议使用以下API来使ViewController FaceViewController更新其视图FaceView:
var expression = FacialExpression(eyes: .Closed, eyeBrows: .Relaxed, mouth: .Smirk) {
didSet {
updateUI() // Model changed, so update the View
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当视图更新自己的模型时,我还没有看到这个概念的扩展.例如,这没有意义:
// Implementing an imaginary delegate UIFaceViewDelegate
func faceView(_ faceView: FaceView, didEpdateExpressionTo expression: FacialExpression {
self.expression = expression
// This triggers another update to the view, and possibly infinite recursion
}
Run Code Online (Sandbox Code Playgroud)
在Objective-C中,这非常简单,因为您可以将getter和setter用作公共API,将后备存储用作私有状态.Swift也可以使用计算变量来使用这种方法,但我相信Swift设计师有一些不同的想法.
那么,视图控制器在响应视图更新时表示状态更改的适当方式是什么,同时还为其他人公开合理的读/写API以检查其状态?
我还观看了cs193p2017年冬季视频.对于FaceIt应用程序,mdoel需要转换为how it will be displayed on the view.它不是1 to 1 翻译,而是更像3 to 2或类似的东西.这就是我们有辅助方法的原因updateUI(_:).
关于如何根据变化进行view controller更新的问题.在这个例子中,我们无法更新,因为我们需要弄清楚?如果我们想要持久性,我们可以只存储in 或.modelviewmodelhow to map 2 values to 3 valuesview statecore datauserDefaults
在更一般的设置中,model change need to update the view和view change need to update the model,然后我们需要indirection避免cycle像你想象的那样.
例如,因为它FacialExpression是值类型.我们可以有类似的东西:
private var realExpression = FacialExpression(eyes: .Closed, eyeBrows: .Relaxed, mouth: .Smirk)
var expression: FacialExpression {
get { return realExpression }
set {
realExpression = newValue
updateUI() // Model changed, so update the View
}
}
Run Code Online (Sandbox Code Playgroud)
}
然后在你的 imaginary delegate UIFaceViewDelegate我们可以有以下内容:
// Implementing an imaginary delegate UIFaceViewDelegate
func faceView(_ faceView: FaceView, didEpdateExpressionTo expression: FacialExpression {
self.realExpression = expression
// This WILL NOT triggers another update to the view, and AVOID THE possibly of infinite recursion
Run Code Online (Sandbox Code Playgroud)
}
以下是我的测试代码:
class SubView:UIView{
}
class TestVC: UIViewController {
var testView : SubView = SubView.init(frame: CGRect.zero) {
didSet{
print("testView didSet")
}
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
var testBtn = UIButton.init(frame: CGRect(x: 0, y: 0, width: 264, height: 45))
testBtn.backgroundColor = .red
testBtn.addTarget(self, action: #selector(clickToUpdateTestView), for: UIControlEvents.touchUpInside)
self.view.addSubview(testBtn)
}
func clickToUpdateTestView() -> Void {
self.testView = SubView.init(frame: CGRect.zero)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Run Code Online (Sandbox Code Playgroud)
但是当单击按钮时,我在控制台输出中得到“ testView didSet ”。和你的工具有什么区别?
| 归档时间: |
|
| 查看次数: |
386 次 |
| 最近记录: |