InputAccessoryView 设置约束时的奇怪行为 - swift - 以编程方式

问题描述

我真的对 inputAccessoryView 的使用感到困惑。 我在 Stack 和 Apple 文档上都在网上搜索了很多,但似乎没有回答我的问题:

-首先,没有说明如何将它与 auto-layout 一起使用,这是我见过的唯一使用 CGRect 框架的教程。

这就是我如何使用这个 help 设置 UIView 的子类。

class CustomView: UIView {

let sendButton = UIButton(image: #imageLiteral(resourceName: "sendImage").withRenderingMode(.alwaysOriginal))

let textField = FlexibleTextView()

override var intrinsicContentSize: CGSize {
    return CGSize.zero
}


override init(frame: CGRect) {
    super.init(frame: .zero)
    
    setupUI()
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}


fileprivate func setupUI(){
    self.backgroundColor = .white
    
    
    self.setupShadow(opacity: 0.3,radius: 3,offset: .init(width: 0,height: -3),color: .lightGray)
    
    textField.placeholder = "Send message here..."
    textField.font = UIFont(name: "avenir-heavy",size: 17)
    textField.layer.cornerRadius = 5
    textField.backgroundColor = .white
    textField.textColor = .black
    
    autoresizingMask = .flexibleHeight
    
    addSubview(textField)
    addSubview(sendButton)
    
    textField.translatesAutoresizingMaskIntoConstraints = false
    sendButton.translatesAutoresizingMaskIntoConstraints = false
    
    sendButton.setContentHuggingPriority(UILayoutPriority(rawValue: 1000),for: NSLayoutConstraint.Axis.horizontal)
    sendButton.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 1000),for: NSLayoutConstraint.Axis.horizontal)

    textField.maxHeight = 80
    
    textField.leadingAnchor.constraint(equalTo: leadingAnchor,constant: 12).isActive = true
    textField.trailingAnchor.constraint(equalTo: sendButton.leadingAnchor,constant: -8).isActive = true
    textField.topAnchor.constraint(equalTo: topAnchor,constant: 8).isActive = true
    textField.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor,constant: -8).isActive = true
    
    
    sendButton.leadingAnchor.constraint(equalTo: textField.trailingAnchor,constant: 8).isActive = true
    sendButton.trailingAnchor.constraint(equalTo: trailingAnchor,constant: -12).isActive = true
    sendButton.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor,constant: -8).isActive = true
    sendButton.heightAnchor.constraint(equalToConstant: 40).isActive = true
    sendButton.widthAnchor.constraint(equalToConstant: 40).isActive = true
    
    let borderView = UIView(backgroundColor: .lightGray)
    addSubview(borderView)
    borderView.anchor(top: topAnchor,leading: leadingAnchor,bottom: nil,trailing: trailingAnchor,size: .init(width: 0,height: 0.5))
    
}

}



  class FlexibleTextView: UITextView {
// limit the height of expansion per intrinsicContentSize
var maxHeight: CGFloat = 0.0

private let placeholderTextView: UITextView = {
    let tv = UITextView()
    tv.translatesAutoresizingMaskIntoConstraints = false
    tv.backgroundColor = .clear
    tv.isScrollEnabled = false
    tv.font = UIFont(name: "avenir-heavy",size: 17)
    tv.isUserInteractionEnabled = false
    tv.textColor = UIColor.gray
    
    return tv
}()
var placeholder: String? {
    get {
        return placeholderTextView.text
    }
    set {
        placeholderTextView.text = newValue
    }
}

override init(frame: CGRect,textContainer: NSTextContainer?) {
    super.init(frame: frame,textContainer: textContainer)
    isScrollEnabled = false
    autoresizingMask = [.flexibleWidth,.flexibleHeight]
    NotificationCenter.default.addobserver(self,selector: #selector(UITextInputDelegate.textDidChange(_:)),name: UITextView.textDidChangeNotification,object: self)
    placeholderTextView.font = font
    addSubview(placeholderTextView)
    
    
    placeholderTextView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
    placeholderTextView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
    placeholderTextView.topAnchor.constraint(equalTo: topAnchor).isActive = true
    placeholderTextView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
        
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override var text: String! {
    didSet {
        invalidateIntrinsicContentSize()
        placeholderTextView.isHidden = !text.isEmpty
    }
}

override var font: UIFont? {
    didSet {
        placeholderTextView.font = font
        invalidateIntrinsicContentSize()
    }
}

override var contentInset: UIEdgeInsets {
    didSet {
        placeholderTextView.contentInset = contentInset
    }
}

override var intrinsicContentSize: CGSize {
    var size = super.intrinsicContentSize
    
    if size.height == UIView.noIntrinsicmetric {
        // force layout
        layoutManager.glyphRange(for: textContainer)
        size.height = layoutManager.usedRect(for: textContainer).height + textContainerInset.top + textContainerInset.bottom
    }
    
    if maxHeight > 0.0 && size.height > maxHeight {
        size.height = maxHeight
        
        if !isScrollEnabled {
            isScrollEnabled = true
        }
    } else if isScrollEnabled {
        isScrollEnabled = false
    }
    
    return size
}

deinit {
    NotificationCenter.default.removeObserver(self)
}
@objc private func textDidChange(_ note: Notification) {
    // needed incase isScrollEnabled is set to true which stops automatically calling invalidateIntrinsicContentSize()
    invalidateIntrinsicContentSize()
    placeholderTextView.isHidden = !text.isEmpty
}
}

我的意思是它有效,这就是我想在这里附上它的原因(也许可以帮助某人), 但我还有一个问题:

我像这样设置了 sendButton topAnchor:

sendButton.topAnchor.constraint(equalTo: topAnchor,constant: -8).isActive = true

而不是使用 heightwidth 约束,我得到的结果是当文本增加时 textview 无法增加高度。我怎样才能做到这一点?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)