Член экземпляра '' нельзя использовать для типа 'CustomTextField'; Вы хотели вместо этого использовать значение этого типа?

Я хочу изменить переменную 'leftIcon' в классе CustomTextField из ViewController. однако я получаю следующую ошибку в классе CustomTextField.

Пользовательское текстовое поле

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?

Вьюконтроллер

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

person Ufuk Köşker    schedule 02.04.2021    source источник
comment
Извините, я удалил свой ответ, потому что он не может быть правильным. Я не уверен, что происходит, но я подумаю об этом. Ошибка имела бы смысл, если бы в вашем ViewController параметр строки textfield был var textfield = CustomTextField без вызова инициализатора, но вы вызываете его, поэтому, если нет других ошибок, которые были бы важны, для меня это загадка.   -  person Chip Jarred    schedule 02.04.2021
comment
Итак, ошибка возникает на let icon = UIImage(systemName: leftIcon) ?   -  person Chip Jarred    schedule 02.04.2021
comment
@ChipJarred да   -  person Ufuk Köşker    schedule 02.04.2021
comment
Извините, если вы попытались прочитать мой ответ, пока я его безумно редактировал. Я получил дистиллированный код для работы в Xcode, поэтому я думаю, что он решит вашу проблему, когда вы вернете код, который я удалил.   -  person Chip Jarred    schedule 02.04.2021
comment
Я попробовал оба решения, но не смог изменить значение leftIcon в CustomTextField из viewDidLoad. @ChipJarred   -  person Ufuk Köşker    schedule 02.04.2021
comment
Вы получаете новую ошибку, когда находитесь в viewDidLoad()?   -  person Chip Jarred    schedule 02.04.2021
comment
Я не получил новую ошибку.   -  person Ufuk Köşker    schedule 02.04.2021
comment
Если вы можете опубликовать текущее состояние вашего кода, я посмотрю. Если не здесь, может быть, в GitHub.   -  person Chip Jarred    schedule 02.04.2021
comment
github.com/ufukkosker/CustomTextField Вам необходимо установить модуль, потому что я использую SnapKit.   -  person Ufuk Köşker    schedule 02.04.2021
comment
ХОРОШО. Я не думаю, что мне нужен весь код. Просто обновленная версия того, что вы разместили здесь, но тоже все в порядке.   -  person Chip Jarred    schedule 02.04.2021
comment
Это демонстрационный проект без проблем. :)   -  person Ufuk Köşker    schedule 02.04.2021
comment
Я на самом деле могу скомпилировать его без проблем. Вы пробовали очистить свой проект? (команда-шифт-К)? Иногда у меня остаются остатки старых ошибок после их исправления. Обычно это решает проблему, но иногда мне приходится чистить, затем выходить из Xcode и перезапускать.   -  person Chip Jarred    schedule 02.04.2021
comment
Значок человека в левой части текстового поля не виден. Этот значок появляется на вас? Я пробовал много раз, но это не работает.   -  person Ufuk Köşker    schedule 02.04.2021
comment
На самом деле оказалось, что я строил не ту цель. Я сейчас получаю какую-то ошибку в журнале, поэтому я разбираюсь с этим.   -  person Chip Jarred    schedule 02.04.2021
comment
Давайте продолжим обсуждение в чате.   -  person Chip Jarred    schedule 02.04.2021


Ответы (1)


Я немного упростил проблему и воссоздал ее, так что вы захотите добавить код, который я удалил. Этот код выдает ту же ошибку:

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
    }
    
    ...
}
person Chip Jarred    schedule 02.04.2021