委托方法内的代码不在 Xcode 内运行

问题描述

我有一个自定义的 UITextView 类,用于初始化一个新的 TextView。这个类的委托本身就是因为我需要在文本更改时运行代码,委托方法运行。这是那堂课。


protocol TextViewOuterDelegate: class {
    func textViewDidChange(_ textView: UITextView)
}

/// Custom `UITextView`
class TextView: UITextView,UITextViewDelegate {
    
    var hintLabel,smallHintLabel: UILabel!
    var underline: UIView!
    var secondDelegate: TextViewOuterDelegate?
    
    // 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: nil)
        
        self.heightAnchor.constraint(equalToConstant: 57).isActive = true
        self.textContainerInset = UIEdgeInsets(top: 25,left: 0,bottom: 0,right: 0)
        self.delegate = self
        
        let weight: UIFont.Weight = isLight ? .medium : .regular
        let textColor: UIColor = isLight ? .white : .black
        let hintColor = isLight ? UIColor(white: 1.0,alpha: 0.8) : UIColor(white: 0.0,alpha: 0.4)
        let lineColor = isLight ? UIColor(white: 1.0,alpha: 0.3) : UIColor(white: 0.0,alpha: 0.12)
        
        let largeSize = UIFont.preferredFont(forTextStyle: .title3).pointSize
        let smallSize = UIFont.preferredFont(forTextStyle: .subheadline).pointSize
        
        // 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,constant: insets.left
        ).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,constant: insets.left).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
        self.isScrollEnabled = false
        
        // 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)
    }
    
    func textViewDidChange(_ textView: UITextView) {
        /// Adjusts the position of the hint text when text is changed in field
        if self.text?.isEmpty ?? true {
            self.moveHintDown()
        } else {
            self.moveHintUp()
        }

        secondDelegate?.textViewDidChange(self)
        
        /// Adjusts the size of the text view when text is changed in field
        let size = CGSize(width: textView.visibleSize.width,height: 999999)
        let estimatedSize = self.sizeThatFits(size)
        
        self.constraints.forEach { constraint in
            if constraint.firstAttribute == .height {
                //Todo: Max num of lines (prob no restriction),scroll the messages every time that a new line is added,fix this code to make it nicer
                if estimatedSize.height < 57 {
                    constraint.constant = 57
                } else {
                    constraint.constant = estimatedSize.height
                }
            }
        }
    }

为了在每次更改不同文件的文本时运行一个函数,我设置了一个 TextViewOuterDelegate,它应该与我的另一个文件通信以运行另一个函数

class MessageComposeView: UIView,TextViewOuterDelegate {
    private var textField: TextView!
    private var sendButton: SendButton!
    weak var delegate: MessageComposeViewDelegate?
    
    
    init() {
        super.init(frame: .zero)
        // text field
        textField = TextView(hintText: "Type a message")
        let test = TextView()
        test.secondDelegate = 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
        
        // send button
        sendButton = SendButton()
        sendButton.setState(.disabled)
        sendButton.addTarget(self,action: #selector(send),for: .touchUpInside)
        self.addSubview(sendButton)
        
        sendButton.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
        sendButton.leadingAnchor.constraint(equalTo: textField.trailingAnchor,constant: 16).isActive = true
        sendButton.trailingAnchor.constraint(equalTo: self.trailingAnchor,constant: -16).isActive = true
    }
    
    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)
    }
    
    /// Calls `sendMessage(text: String?)` delegate method to send the message and disable the send button
    
    /// Called when message is sent to reset the compose view
    func sent() {
        textField.text = nil
        textViewDidChange(textField)
        
        sendButton.stopLoad()
        sendButton.setState(.disabled)
    }
}

未设置 secondDelegate,因此 TextViewDidChange 函数未运行。我究竟做错了什么?提前致谢。

解决方法

// This is the instance that you should assign secondDelegate for
textField = TextView(hintText: "Type a message")

// Not this one,this one never gets added as a subview
let test = TextView()
test.secondDelegate = self

// The fix is here 
textField.secondDelegate = self
self.addSubview(textField)