Расширения с сохраненными свойствами
Я все еще изучаю Swift и пытаюсь создать расширение для добавления заполнителя в UITextView.
Моя идея заключается в том, чтобы создать 2 UITextViews, один с текстом в качестве заполнителя, и когда пользователь начинает редактировать текст, он фактически скрыт, а пользователь модифицирует другой UITextView.
Однако мой вопрос здесь не в том, чтобы иметь заполнитель в UITextView, а в том, как использовать расширения для решения этой проблемы.
Мой вопрос заключается в том, что я должен изменить в своей реализации, чтобы создать расширение, которое будет выглядеть со стороны вызывающей стороны как:myTextView.placeholder("a placeholder text..")
До сих пор я создал его в своем UIViewController, и мне нужно переместить его в расширение, но у меня много сохраненных свойств, поэтому он не будет работать.
Вот мой код:
import UIKit
class ViewController: UIViewController, UITextViewDelegate {
let myTextView: UITextView = {
let textView = UITextView()
textView.tag = 0
textView.backgroundColor = UIColor.yellow
textView.layer.cornerRadius = 8
textView.translatesAutoresizingMaskIntoConstraints = false
return textView
}()
let textViewPlaceHolder: UITextView = {
let textViewPlaceHolder = UITextView()
textViewPlaceHolder.tag = 1
textViewPlaceHolder.text = "Placeholder text.."
textViewPlaceHolder.textColor = UIColor.lightGray
textViewPlaceHolder.backgroundColor = UIColor.clear
textViewPlaceHolder.translatesAutoresizingMaskIntoConstraints = false
return textViewPlaceHolder
}()
func textViewDidChange(_ textView: UITextView) {
myTextView.becomeFirstResponder()
if textView.tag == 1 && (myTextView.text != nil || myTextView.text != "") {
textView.isHidden = true
textViewPlaceHolder.resignFirstResponder()
} else if textView.tag == 0 {
if myTextView.text == nil || myTextView.text == "" {
textViewPlaceHolder.becomeFirstResponder()
myTextView.resignFirstResponder()
textViewPlaceHolder.isHidden = false
textViewPlaceHolder.text = "Placeholder text.."
}
}
}
func textViewDidBeginEditing(_ textView: UITextView) {
DispatchQueue.main.async {
self.textViewPlaceHolder.selectedRange = NSMakeRange(0, 0)
}
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
view.addSubview(myTextView)
textViewConstraints()
view.addSubview(textViewPlaceHolder)
myTextViewPHConstraints()
myTextView.delegate = self
textViewPlaceHolder.delegate = self
}
func textViewConstraints() {
myTextView.widthAnchor.constraint(equalTo: self.view.widthAnchor, constant: -16).isActive = true
myTextView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
myTextView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
myTextView.heightAnchor.constraint(equalToConstant: 200).isActive = true
}
func myTextViewPHConstraints() {
textViewPlaceHolder.widthAnchor.constraint(equalTo: self.view.widthAnchor, constant: -16).isActive = true
textViewPlaceHolder.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
textViewPlaceHolder.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
textViewPlaceHolder.heightAnchor.constraint(equalToConstant: 200).isActive = true
}
}
Как я уже упоминал выше, я все еще изучаю Swift, и этот вопрос не для решения очень конкретной проблемы, а для того, чтобы научиться решать проблемы в расширениях Swift.
Примечание. Не используйте приведенный выше код для решения проблемы заполнителя, так как она не совсем работает.
1 ответ
Вы можете сделать что-то вроде этого:
extension UITextView {
private struct AssociatedKeys {
struct var placeholder = "placeholder"
}
var placeholder: String! {
get {
guard let placeholder = objc_getAssociatedObject(self, &AssociatedKeys.placeholder) as? String else {
return String()
}
return placeholder
}
set(value) {
objc_setAssociatedObject(self, &AssociatedKeys.placeholder, value, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
Невозможно получить доступ к сохраненным свойствам непосредственно в расширении. Создайте глобальный класс в стороне, вызовите свой глобальный класс в контроллерах просмотра и в своем расширении. Там вы можете увидеть все сохраненные переменные внутри вашего расширения.