实例成员“....”不能用于类型 'CustomTextField';您的意思是改用这种类型的值吗?

Instance member '....' cannot be used on type 'CustomTextField'; did you mean to use a value of this type instead?

我想从 ViewController 更改 CustomTextField class 中的 'leftIcon' 变量。 但是,我在 CustomTextField class.

中收到以下错误

自定义文本字段

class CustomTextField: UITextField, UITextFieldDelegate {
    //"person"
    private var showPassword: Bool = false
    var leftIcon: String = ""
    
    private let leftIconView: UIImageView = {
        let icon = UIImage(systemName: leftIcon)
        let imageView = UIImageView(image: icon)
        imageView.contentMode = .scaleAspectFit
        imageView.tintColor = .white
        return imageView
    }()
}

错误:

Instance member 'leftIcon' cannot be used on type 'CustomTextField'; did you mean to use a value of this type instead?

ViewController

class ViewController: UIViewController {
    
    var textfield = CustomTextField()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.textfield.leftIcon = "person"
    }
}

我对问题进行了一些提炼并重新创建了它,因此您需要重新添加我删除的代码。此代码产生相同的错误:

class CustomTextField {
    var leftIcon: String = ""
    
    private let leftIconView: UIImageView = {
        let icon = UIImage(systemName: leftIcon) // <--- Error here
        let imageView = UIImageView(image: icon)
        return imageView
    }()
}

并追踪到问题所在。

问题是初始化 leftIconView 实际上发生在调用初始化程序之前的 static 上下文中,因此您不能引用实例属性。我找到了两个简单的解决方案,第一个是使 leftIconView 成为 lazy var 而不是 let:

class CustomTextField {
    var leftIcon: String = ""
    
    private lazy var leftIconView: UIImageView = {
        let icon = UIImage(systemName: leftIcon)
        let imageView = UIImageView(image: icon)
        return imageView
    }()
}

第二种解决方案是在初始化器中初始化 leftIconView

class CustomTextField {
    var leftIcon: String = ""
    
    private let leftIconView: UIImageView
    
    override init()
    {
        let icon = UIImage(systemName: leftIcon)
        self.leftIconView = UIImageView(image: icon)
    }
}

第二个解决方案可能需要您在添加继承后还为 UIView 实现一些其他初始化程序,当然您需要在结束时调用 super.init初始值设定项。

附录

上述解决方案确实修复了编译错误,但实际上使图标出现在 CustomTextField 中需要在 leftIcon

上使用 属性 观察器
class CustomTextField: UITextField, UITextFieldDelegate {
    //"person"
    private var showPassword: Bool = false
    var leftIcon: String = ""
    {
        didSet
        {
            leftIconView = makeImageView(for: leftIcon)

            // leftView is the view that is actually displayed.  It's set
            // once in the initializer, so now that we're updating 
            // leftIconView, we have to update leftView as well
            leftView = leftIconView
            
            // Maybe also do this
            leftView?.setNeedsDisplay()
        }
    }
    
    private lazy var leftIconView: UIImageView = {
        makeImageView(for: leftIcon)
    }()
    
    private func makeImageView(for imageName: String) -> UIImageView {
        let icon = UIImage(systemName: imageName )
        let imageView = UIImageView(image: icon)
        imageView.contentMode = .scaleAspectFit
        imageView.tintColor = .white
        return imageView
    }
    
    ...
}

备选方案

对于像你这样的情况,我们也可以使用静态变量。

class CustomTextField {
    static var leftIcon: String = ""
    
    private let leftIconView: UIImageView = {
        let icon = UIImage(systemName: CustomTextField.leftIcon)
        let imageView = UIImageView(image: icon)
        return imageView
    }()
}

只是更简洁、更短。除了这个调用语句:

CustomTextField.leftIcon