簡體   English   中英

具有存儲屬性的擴展

[英]Extensions with stored properties

我仍在學習 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 擴展中的問題。

注意:不要使用上面的代碼來解決占位符問題,因為它不是完美的工作。

你可以這樣做:

extension UITextView {

    private struct AssociatedKeys {
        static 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)
        }
    }
}

在擴展中直接訪問存儲的屬性是不可能的。 除了創建一個全局類,在您的視圖控制器和擴展中調用您的全局類。 在那里,您可以在擴展程序中看到所有存儲的變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM