在扩展中移动函数时出错 "Value of type 'UIViewController' has no member..."
error "Value of type 'UIViewController' has no member..." when moving a func inside extension
我需要移动一个方法来在扩展中添加和删除日志视图,以便将它提供给每个控制器。为此,我在原始方法中添加了一个 inout UIVew 参数,我在其中为视图使用了一个全局变量。不,我有这个错误
Value of type 'UIViewController' has no member 'containerForLoading'
从 self.containerForLoading
中删除自己会给出错误:
Escaping closure captures 'inout' parameter 'containerForLoading'
在动画闭包内(见评论)
是整个过程都错了还是我在最后一步迷路了?
extension UIViewController {
func showLoadingView(containerForLoading: inout UIView, uponView: UIView) {
containerForLoading = UIView(frame: uponView.bounds)
uponView.addSubview(containerForLoading)
containerForLoading.backgroundColor = .white
containerForLoading.alpha = 0
UIView.animate(withDuration: 0.24) { self.containerForLoading.alpha = 0.8 } //here the error
let activivityIndicator = UIActivityIndicatorView()
containerForLoading.addSubview(activivityIndicator)
activivityIndicator.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
activivityIndicator.centerYAnchor.constraint(equalTo: uponView.centerYAnchor),
activivityIndicator.centerXAnchor.constraint(equalTo: uponView.centerXAnchor)
])
activivityIndicator.startAnimating()
}
func removeLoading(containerForLoading: inout UiView, uponView: UIView) {
containerForLoading.removeFromSuperview()
}
}
这是原来里面的代码viewController
使用这个变量
var containerForLoading = UIView()
需要时这样调用
self.showLoadingView(uponView: self.view)
extension ViewController {
func showLoadingView(uponView: UIView) {
containerForLoading = UIView(frame: uponView.bounds)
uponView.addSubview(containerForLoading)
containerForLoading.backgroundColor = .white
containerForLoading.alpha = 0
UIView.animate(withDuration: 0.24) { self.containerForLoading.alpha = 0.8 }
let activivityIndicator = UIActivityIndicatorView()
containerForLoading.addSubview(activivityIndicator)
activivityIndicator.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
activivityIndicator.centerYAnchor.constraint(equalTo: uponView.centerYAnchor),
activivityIndicator.centerXAnchor.constraint(equalTo: uponView.centerXAnchor)
])
activivityIndicator.startAnimating()
}
func removeLoading(uponView: UIView) {
containerForLoading.removeFromSuperview()
}
}
您可以将 loadingContainerTag
设为局部变量,并将参数名称更改为其他名称。然后在创建容器视图后分配给参数:
extension UIViewController {
func showLoadingView(containerForLoadingProperty: inout UIView, uponView: UIView) {
// local variable!
let containerForLoading = UIView(frame: uponView.bounds)
// also set property
containerForLoadingProperty = containerForLoading
uponView.addSubview(containerForLoading)
containerForLoading.backgroundColor = .white
containerForLoading.alpha = 0
// no "self."!
UIView.animate(withDuration: 0.24) { containerForLoading.alpha = 0.8 }
// ... everything else is the same
removeLoading
可以只有一个非 inout
参数:
func removeLoading(containerForLoadingProperty: UIView) {
containerForLoadingProperty.removeFromSuperview()
}
但是...
显示加载指示器的方法需要一个 inout
参数是非常奇怪的。它不应分配给 caller 提供的特殊 属性。它应该只显示加载指示器!
您 containerForLoading
属性 的目的是让您在 removeLoading
中知道要删除哪个视图。如果您不将 containerForLoading
视图存储在 属性 中的某处,您将不知道要删除哪个视图,对吗?那么,我们可以使用视图的 tag
属性 来标识视图,因此您可以将 containerForLoading
设为局部变量,然后在 removeLoading
中使用其标记来找到它。
extension UIViewController {
static let loadingContainerTag = <a number you like>
func showLoadingView(uponView: UIView) {
// local variable!
let containerForLoading = UIView(frame: uponView.bounds)
uponView.addSubview(containerForLoading)
containerForLoading.backgroundColor = .white
containerForLoading.alpha = 0
// set tag
containerForLoading.tag = UIViewController.loadingContainerTag
// no "self."!
UIView.animate(withDuration: 0.24) { containerForLoading.alpha = 0.8 }
let activivityIndicator = UIActivityIndicatorView()
containerForLoading.addSubview(activivityIndicator)
activivityIndicator.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
activivityIndicator.centerYAnchor.constraint(equalTo: uponView.centerYAnchor),
activivityIndicator.centerXAnchor.constraint(equalTo: uponView.centerXAnchor)
])
activivityIndicator.startAnimating()
}
func removeLoading(uponView: UIView) {
// find view with the tag
uponView.viewWithTag(UIViewController.loadingContainerTag)?.removeFromSuperview()
}
}
我需要移动一个方法来在扩展中添加和删除日志视图,以便将它提供给每个控制器。为此,我在原始方法中添加了一个 inout UIVew 参数,我在其中为视图使用了一个全局变量。不,我有这个错误
Value of type 'UIViewController' has no member 'containerForLoading'
从 self.containerForLoading
中删除自己会给出错误:
Escaping closure captures 'inout' parameter 'containerForLoading'
在动画闭包内(见评论) 是整个过程都错了还是我在最后一步迷路了?
extension UIViewController {
func showLoadingView(containerForLoading: inout UIView, uponView: UIView) {
containerForLoading = UIView(frame: uponView.bounds)
uponView.addSubview(containerForLoading)
containerForLoading.backgroundColor = .white
containerForLoading.alpha = 0
UIView.animate(withDuration: 0.24) { self.containerForLoading.alpha = 0.8 } //here the error
let activivityIndicator = UIActivityIndicatorView()
containerForLoading.addSubview(activivityIndicator)
activivityIndicator.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
activivityIndicator.centerYAnchor.constraint(equalTo: uponView.centerYAnchor),
activivityIndicator.centerXAnchor.constraint(equalTo: uponView.centerXAnchor)
])
activivityIndicator.startAnimating()
}
func removeLoading(containerForLoading: inout UiView, uponView: UIView) {
containerForLoading.removeFromSuperview()
}
}
这是原来里面的代码viewController
使用这个变量
var containerForLoading = UIView()
需要时这样调用
self.showLoadingView(uponView: self.view)
extension ViewController {
func showLoadingView(uponView: UIView) {
containerForLoading = UIView(frame: uponView.bounds)
uponView.addSubview(containerForLoading)
containerForLoading.backgroundColor = .white
containerForLoading.alpha = 0
UIView.animate(withDuration: 0.24) { self.containerForLoading.alpha = 0.8 }
let activivityIndicator = UIActivityIndicatorView()
containerForLoading.addSubview(activivityIndicator)
activivityIndicator.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
activivityIndicator.centerYAnchor.constraint(equalTo: uponView.centerYAnchor),
activivityIndicator.centerXAnchor.constraint(equalTo: uponView.centerXAnchor)
])
activivityIndicator.startAnimating()
}
func removeLoading(uponView: UIView) {
containerForLoading.removeFromSuperview()
}
}
您可以将 loadingContainerTag
设为局部变量,并将参数名称更改为其他名称。然后在创建容器视图后分配给参数:
extension UIViewController {
func showLoadingView(containerForLoadingProperty: inout UIView, uponView: UIView) {
// local variable!
let containerForLoading = UIView(frame: uponView.bounds)
// also set property
containerForLoadingProperty = containerForLoading
uponView.addSubview(containerForLoading)
containerForLoading.backgroundColor = .white
containerForLoading.alpha = 0
// no "self."!
UIView.animate(withDuration: 0.24) { containerForLoading.alpha = 0.8 }
// ... everything else is the same
removeLoading
可以只有一个非 inout
参数:
func removeLoading(containerForLoadingProperty: UIView) {
containerForLoadingProperty.removeFromSuperview()
}
但是...
显示加载指示器的方法需要一个 inout
参数是非常奇怪的。它不应分配给 caller 提供的特殊 属性。它应该只显示加载指示器!
您 containerForLoading
属性 的目的是让您在 removeLoading
中知道要删除哪个视图。如果您不将 containerForLoading
视图存储在 属性 中的某处,您将不知道要删除哪个视图,对吗?那么,我们可以使用视图的 tag
属性 来标识视图,因此您可以将 containerForLoading
设为局部变量,然后在 removeLoading
中使用其标记来找到它。
extension UIViewController {
static let loadingContainerTag = <a number you like>
func showLoadingView(uponView: UIView) {
// local variable!
let containerForLoading = UIView(frame: uponView.bounds)
uponView.addSubview(containerForLoading)
containerForLoading.backgroundColor = .white
containerForLoading.alpha = 0
// set tag
containerForLoading.tag = UIViewController.loadingContainerTag
// no "self."!
UIView.animate(withDuration: 0.24) { containerForLoading.alpha = 0.8 }
let activivityIndicator = UIActivityIndicatorView()
containerForLoading.addSubview(activivityIndicator)
activivityIndicator.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
activivityIndicator.centerYAnchor.constraint(equalTo: uponView.centerYAnchor),
activivityIndicator.centerXAnchor.constraint(equalTo: uponView.centerXAnchor)
])
activivityIndicator.startAnimating()
}
func removeLoading(uponView: UIView) {
// find view with the tag
uponView.viewWithTag(UIViewController.loadingContainerTag)?.removeFromSuperview()
}
}