这个
activityIndicator
是计算属性,因此每次引用计算属性时,
get
将调用块。净效果是,正如所写,每次引用
活动指示器
,您将获得
UIActivityIndicatorView
这显然不是你的意图。
考虑你的
showLoadingIndicator
:
func showLoadingIndicator() {
activityIndicator.startAnimating()
activityIndicator.isHidden = false
}
第一行
startAnimating
)将返回新的
活动指示器视图
第二行
isHidden
)将再次返回。这两个都不是你添加到子视图中的那个。
这个
活动指示器
真的应该实例化一次,而且只实例化一次。不幸的是,您可以在扩展中定义存储的属性,因此有几种方法:
-
你可以让
UIViewController
声明存储的属性,只需定义方法方法来配置、显示和隐藏它:
protocol LoadingIndicatorProtocol: class {
var loadingActivityIndicator: UIActivityIndicatorView? { get set }
}
extension LoadingIndicatorProtocol where Self: UIViewController {
func addLoadingIndicator() {
let indicator = UIActivityIndicatorView(style: .gray)
indicator.hidesWhenStopped = true
indicator.style = .whiteLarge
indicator.color = .red
indicator.backgroundColor = .gray
indicator.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(indicator)
loadingActivityIndicator = indicator
}
func showLoadingIndicator() {
loadingActivityIndicator?.startAnimating()
loadingActivityIndicator?.isHidden = false
}
func hideLoadingIndicator() {
loadingActivityIndicator?.stopAnimating()
loadingActivityIndicator?.isHidden = true
}
}
然后一个
ui视图控制器
子类只需为
活动指示器
,例如
class ViewController: UIViewController, LoadingIndicatorProtocol {
var loadingActivityIndicator: UIActivityIndicatorView?
override viewDidLoad() {
super.viewDidLoad()
addLoadingIndicator()
}
...
}
-
另一种方法是
associated objects
通过
objc_getAssociatedObject
和
objc_setAssociatedObject
,要实现存储的属性行为:
protocol LoadingIndicatorProtocol {
var loadingActivityIndicator: UIActivityIndicatorView { get }
}
private var associatedObjectKey = 0
extension LoadingIndicatorProtocol {
var loadingActivityIndicator: UIActivityIndicatorView {
if let indicatorView = objc_getAssociatedObject(self, &associatedObjectKey) as? UIActivityIndicatorView {
return indicatorView
}
let indicator = UIActivityIndicatorView(style: .gray)
indicator.hidesWhenStopped = true
indicator.style = .whiteLarge
indicator.color = .red
indicator.backgroundColor = .gray
indicator.translatesAutoresizingMaskIntoConstraints = false
objc_setAssociatedObject(self, &associatedObjectKey, indicator, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
return indicator
}
func showLoadingIndicator() {
loadingActivityIndicator.startAnimating()
loadingActivityIndicator.isHidden = false
}
func hideLoadingIndicator() {
loadingActivityIndicator.stopAnimating()
loadingActivityIndicator.isHidden = true
}
}