Ios 使用属性观察者修改Swift中的UI组件
我已经创建了UICollectionViewCell的一个子类,它显示了一些信息。我有一个天气类型的属性。当设置了一个实例时,我想更新单元格。下面的方法糟糕吗?我想,如果在加载UI组件之前访问它,我可能会提前触发要创建的视图。或者,这是无意义的,并且仅适用于UIViewController(关于使用Ios 使用属性观察者修改Swift中的UI组件,ios,swift,uicollectionview,Ios,Swift,Uicollectionview,我已经创建了UICollectionViewCell的一个子类,它显示了一些信息。我有一个天气类型的属性。当设置了一个实例时,我想更新单元格。下面的方法糟糕吗?我想,如果在加载UI组件之前访问它,我可能会提前触发要创建的视图。或者,这是无意义的,并且仅适用于UIViewController(关于使用viewproperty提前查看) 如果这不好,正确的方法是什么 var weather: Weather? { didSet { if let weather
view
property提前查看)
如果这不好,正确的方法是什么
var weather: Weather? {
didSet {
if let weather = weather {
dayLabel.text = dayFormatter.stringFromDate(weather.fromDate)
// ... more code like this
}
}
}
如果我计划在用户会话期间更新值,我会使用属性观察者。如果这是一个仅在用户首次加载时才更新的值,则我只需在最初加载视图时调用一个方法即可 如果使用属性观察者,则可以在定义它时为其提供初始值,以便在用户需要时数据就在那里。此外,如果要更新用户界面,请确保在主队列上进行更新
var weather: Weather = data {
didSet {
dispatch_async(dispatch_get_main_queue(),{
if let weather = weather {
dayLabel.text = dayFormatter.stringFromDate(weather.fromDate)
// ... more code like this
}
})
}
}
您可能需要一个
else
子句,如果weather
为nil
,则清除文本字段。类似地,如果您可能从后台线程更新此内容,则可能希望将该UI更新分派回主线程
请注意,当您在单元格的init
中设置weather
时,不会调用此观察者(无论如何,@IBOutlet
也不会在该点进行配置)。所以要确保你没有依赖它
另外,如果Weather
是可变的,请注意,如果您更改现有Weather
对象的fromDate
,则不会捕获该对象。(如果Weather
是可变的,那么您真的希望通过KVO、代理协议模式或您所拥有的任何东西来捕获其不断变化的属性。)但是如果您使Weather
不可变,您应该可以
因此,从技术上讲,这就是问题的答案,但这会引起一些设计考虑:
weather
参数用于更新UI控件,而不用于存储任何内容。因此,我只想使用一个方法,而不是存储的属性:
func updateWithWeather(weather: Weather?) {
if let weather = weather {
dayLabel.text = dayFormatter.stringFromDate(weather.fromDate)
// ... more code like this
} else {
dayLabel.text = nil
// ... more code like this
}
}
这可能只能从collectionView:cellForItemAtIndexPath:
中调用
但是,这清楚地表明,您只是根据天气参数更新控件,而不是尝试执行其他操作。而且,巧合的是,天气物体的易变性现在是无关紧要的,这是应该的。如果模型发生更改,请调用reloadItemsAtIndexPaths:
,这将触发调用您的collectionView:cellForItemAtIndexPath:
有时,带有didSet
observer的存储属性是一种有用的模式。但是,只有当该属性确实是视图属性时,才应该这样做。例如,考虑一个绘制一些形状的自定义视图。您可能已经存储了指定(例如)绘制路径时要使用的笔划的宽度和颜色的属性。然后,为lineWidth
和strokeColor
存储属性可能有意义,然后您可能会有一个didSet
,它调用setNeedsDisplay()
(这会触发视图的重画)
因此,您建议的模式确实有实际的应用,只是它应该局限于属性确实是视图对象属性的情况。谢谢您的反馈。你有没有其他更好的方法?除了用您描述的要点改进代码之外。好的,谢谢。我把问题“未回答”留到那时。@LuckyLuke-顺便说一句,除了单元和天气之间不幸的紧密耦合之外,使用存储属性存储模型信息的想法也是不可取的。见修订后的答复,