【问题标题】:Setting the delegate of a custom UITextView Delegate in Xcode在 Xcode 中设置自定义 UITextView 委托的委托
【发布时间】:2021-08-29 21:47:17
【问题描述】:

我有一个创建自定义 UITextView 并使用提示文本对其进行初始化的类。我遇到的问题是,当我尝试在初始化程序中设置 UITextView 的委托时,不会调用委托函数。我也不完全确定 textView 类是否应该是委托。 下面是自定义的 UITextView 类:

class TextView: UITextView, UITextViewDelegate {
    var test: TextView?
    var hintLabel, smallHintLabel: UILabel!
    var underline: UIView!

    // MARK: - Init
    
    /// Initialize text field
    /// - Parameters:
    ///   - text: Text field text
    ///   - hintText: Text field hint text (a.k.a. placeholder/description)
    ///   - isLight: Whether text field is light style
    convenience init(text: String? = nil, hintText: String, isLight: Bool = false) {
        self.init(frame: .zero, textContainer: .none)
        
        self.heightAnchor.constraint(equalToConstant: 57).isActive = true
        //setting the delegate
        test = TextView()
        self.delegate = test
        
        // hint
        hintLabel = UILabel()
        hintLabel.text = hintText
        hintLabel.font = UIFont.systemFont(ofSize: largeSize, weight: weight)
        hintLabel.textColor = hintColor
        hintLabel.alpha = text == nil || text!.isBlank ? 1 : 0
        self.addSubview(hintLabel)
        
        hintLabel.translatesAutoresizingMaskIntoConstraints = false
        hintLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: insets.top / 2).isActive = true
        hintLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
        hintLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
        
        // small hint
        smallHintLabel = UILabel()
        self.smallHintLabel.text = hintText
        self.smallHintLabel.font = UIFont.systemFont(ofSize: smallSize, weight: weight)
        self.smallHintLabel.textColor = hintColor
        self.smallHintLabel.alpha = text == nil || text!.isBlank ? 0 : 1
        self.addSubview(smallHintLabel)
        
        smallHintLabel.translatesAutoresizingMaskIntoConstraints = false
        smallHintLabel.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        smallHintLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
        smallHintLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
        
        // text
        self.text = text
        self.font = UIFont.systemFont(ofSize: largeSize, weight: weight)
        self.textColor = textColor
        self.tintColor = isLight ? .white : Color.blue
        self.keyboardAppearance = isLight ? .dark : .light
        
        // underline
        underline = UIView()
        underline.backgroundColor = lineColor
        self.addSubview(underline)
        
        underline.translatesAutoresizingMaskIntoConstraints = false
        underline.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        underline.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
        underline.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
        underline.heightAnchor.constraint(equalToConstant: 1).isActive = true
        
    }
    
    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

/// Adjusts the position of the hint text when text is changed in field
    func textViewDidChange(_ textView: UITextView) {
        print(textView.text)
        if self.text?.isEmpty ?? true {
            moveHintUp()
        } else {
            moveHintUp()
        }
    }

我正在创建此函数的一个实例并将其添加到视图中。


class MessageComposeView: UIView, UITextViewDelegate {
    
    var textField: TextView!
    private var sendButton: SendButton!
    
    weak var delegate: MessageComposeViewDelegate?

    init() {
        super.init(frame: .zero)
        
        // background
        
        // text field
        textField = TextView(hintText: "Type a message")
        textField.delegate = self
        self.addSubview(textField)
        
        textField.translatesAutoresizingMaskIntoConstraints = false
        textField.topAnchor.constraint(equalTo: self.topAnchor, constant: 30).isActive = true
        textField.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -30).isActive = true
        textField.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 16).isActive = true
        textField.heightAnchor.constraint(equalToConstant: 50).isActive = true
        textField.sizeToFit()
        
        // send button
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    
    // MARK: - Actions
    
    /// Called when the message text changes
    func textViewDidChange(_ textView: UITextView) {
        sendButton.setState(textField.text?.isBlank == true ? .disabled : .normal)
        
        let size = CGSize(width: 200, height: 999999)
        let estimatedSize = textField.sizeThatFits(size)

        textField.constraints.forEach { constraint in
            if constraint.firstAttribute == .height {
                constraint.constant = estimatedSize.height
            }
        }
    }

【问题讨论】:

    标签: xcode delegates uitextview init


    【解决方案1】:

    我的猜测是你实际上并没有调用你想要的初始化器。

    例如,如果您调用TextView(),您的convenience init 不会被调用。但是,如果您调用 TextView(hintText: "") 或您创建的初始化程序的任何其他变体,它就会出现。

    其次,虽然它与上述问题没有直接关系,但我质疑您为什么要创建 another TextView 并将其指定为代表。为什么不直接将代理分配给self

    【讨论】:

    • 当我创建这个类的一个实例时,我在另一个文件中调用了便利初始化。至于我为什么要为 TextView() 创建一个变量,这是因为如果我只是将它分配给 TextView(),它会给我一个警告,即内存将被立即释放,因为它是一个弱引用。
    • 请显示您调用它的代码——我已经对其进行了测试,当我使用我给您的格式显式调用初始化程序时它工作正常。至于第二部分,我不是建议你将TextView()分配给代表,我建议你分配self,例如self.delegate = self
    • 当您在便利初始化中设置 self.delegate = self 时,func textViewDidChange(_ textView: UITextView) 会执行吗?我还更新了原始问题以显示其名称
    • 是的,我只添加了TextView,并在init 中设置了delegate = self。通过MessageComposeView 中设置委托,您使事情变得有些复杂。只有 one 代表可以被调用,所以MessageComposeView 中的那个应该被调用。是你吗?
    • 您的建议会奏效。或者,您可以声明一个额外的委托属性(它必须有另一个名称,例如outerDelegate)并在TextView 内部的textViewDidChange 实现中调用它......还有更多选项 - 只是一个架构决策。如果您需要其中一个,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多