0

我需要移动一种在扩展中添加和删除日志视图的方法,以便将其提供给每个控制器。为此,我在原始方法中添加了一个 inout UIVew 参数,在该方法中我为视图使用了一个全局变量。不,我有这个错误

'UIViewController' 类型的值没有成员 'containerForLoading'

从中删除 selfself.containerForLoading将给出错误:

转义闭包捕获“inout”参数“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()
           
       }
    
}

这是原始视图控制器中的代码

使用这个变量

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()

    }
    
    
}
4

1 回答 1

0

您可以创建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参数是非常奇怪的。它不应该分配给调用者提供的特殊属性。它应该只显示加载指示器!

您的属性的目的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()
    }
}
于 2020-09-18T08:53:50.560 回答