在iOS 8中动态调整inputAccessoryView的大小

基本上我试图在inputAccessoryView属性中创建一个resize的UITextView。

我有一个viewController,方法canBecomeFirstResponder返回true,一个视图我通过自定义类(从XIB获取)实例化。 在这个视图中是一个UITextView。

我尝试从该类内部调整完整的inputAccessoryView。 我试过几个方面:直接设置框架,尝试使用高度约束。 它似乎只调整了一半:

这基本上就是我想要的(有或没有自动布局,但在iOS 7/8 +中工作):

class MessageInputAccessory: UIView, UITextViewDelegate { @IBOutlet weak var textView: UITextView! func textViewDidChange(textView: UITextView) { var contentSize = textView.sizeThatFits(CGSizeMake(textView.frame.size.width, CGFloat.max)) self.frame.size.height = contentSize.height + 20 self.textView.reloadInputViews() } } 

我发现这篇文章: 在iOS 8中更改inputAccessoryView的框架 。 声明正在创建自动创建的约束。 问题是,它不会为我创造约束。 禁止或启用autolayout(也通过setTranslatesAutoresizingMaskIntoConstraints())。

它适用于iOS7 / iOS8:

 class MessageInputAccessory: UIView, UITextViewDelegate { private var textView: UITextView! private var heightConstraint: NSLayoutConstraint? override init(frame: CGRect) { super.init(frame: frame) commonInit() } required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) commonInit() } func commonInit() { self.userInteractionEnabled = true textView = UITextView() textView.delegate = self textView.bounces = false textView.scrollEnabled = false textView.layer.cornerRadius = 5 textView.layer.borderWidth = 1 textView.layer.borderColor = UIColor.blueColor().CGColor self.addSubview(textView) } override func layoutSubviews() { super.layoutSubviews() textView.frame = self.bounds } override func addConstraint(constraint: NSLayoutConstraint) { self.heightConstraint = constraint super.addConstraint(constraint) } func textViewDidChange(textView: UITextView) { var contentSize = textView.sizeThatFits(CGSizeMake(textView.frame.size.width, CGFloat.max)) self.frame.size.height = contentSize.height if let heightConstraint = self.heightConstraint { heightConstraint.constant = self.frame.size.height } self.textView.reloadInputViews() } } 

编辑:这也适用于xib (iOS7 / iOS8):

 class MessageInputAccessory: UIView, UITextViewDelegate { @IBOutlet var textView: UITextView! @IBOutlet var textViewHeightConstraint: NSLayoutConstraint! private var heightConstraint: NSLayoutConstraint? override func awakeFromNib() { textView.layer.cornerRadius = 5 textView.layer.borderWidth = 1 textView.layer.borderColor = UIColor.blueColor().CGColor } override func layoutSubviews() { textViewHeightConstraint.constant = self.bounds.size.height super.layoutSubviews() } override func addConstraint(constraint: NSLayoutConstraint) { if constraint.firstItem === self { self.heightConstraint = constraint } super.addConstraint(constraint) } override func addConstraints(constraints: [AnyObject]) { super.addConstraints(constraints) } func textViewDidChange(textView: UITextView) { var contentSize = textView.sizeThatFits(CGSizeMake(textView.frame.size.width, CGFloat.max)) self.frame.size.height = contentSize.height if let heightConstraint = self.heightConstraint { heightConstraint.constant = self.frame.size.height } self.textView.reloadInputViews() } override func intrinsicContentSize() -> CGSize { return self.bounds.size; } } 

有我的xib: 在此处输入图像描述

这不是一个很好的解决方案,但它的工作原理..请告诉我你是否知道更好的方法。

一个相当简单的解决方法是不要让实际的inputAccessoryViewresize – 如果你知道它需要的最大高度,你可以在最大高度创建它,使它透明,并添加一个resize的子视图但是你喜欢。

使其工作所需的细节是inputAccessoryView需要是包含以下内容的UIView子类:

 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { point = [self.innerView convertPoint:point fromView:self]; return [self.innerView pointInside:point withEvent:event]; } 

(其中self.innerView是您动态resize的子视图)。

这使得它声称在子视图中点击,但传递任何落在它外面的。

要注意的主要缺点是键盘通知会为您提供包含整个最大高度inputAccessoryView的帧。 因此,如果你使用它们(例如)调整插图,你需要在那里做一些额外的数学运算。