Man*_*lla 27 objective-c ios inputaccessoryview ios8
很长一段时间潜伏 - 第一次海报!
我在重建UITextView像WhatsApp这样的酒吧时遇到了问题.
我正在使用自定义UIView子类,并懒惰地实例化它:
- (UIView *)inputAccessoryView
并返回YES:
- (BOOL)canBecomeFirstResponder
现在,我想改变的大小inputAccessoryView时,UITextView在规模的增长.在iOS 7上,我只是改变所述视图框架的大小 - 而不是它的原点 - 然后调用reloadInputViews它会起作用:视图将向上移动,使其在键盘上方完全可见.
但是,在iOS 8上,这不起作用.使其工作的唯一方法是还将帧的原点更改为负值.这样会很好,除了它会产生一些奇怪的错误:例如,UIView在输入任何文本时返回到"原始"框架.
有什么我想念的吗?我非常肯定WhatsApp使用它inputAccessoryView是因为它们在拖动时解除键盘的方式 - 仅在最新版本的应用程序中.
如果你能帮助我,请告诉我!或者,如果有任何测试,您希望我运行!
谢谢!:)
顺便说一下,这是我用来更新自定义UIView高度的代码composeBar:
// ComposeBar frame size
CGRect frame = self.composeBar.frame;
frame.size.height += heightDifference;
frame.origin.y -= heightDifference;
self.composeBar.frame = frame;
[self.composeBar.textView reloadInputViews]; // Tried with this
[self reloadInputViews]; // and this
Run Code Online (Sandbox Code Playgroud)
编辑:完整源代码可在@ https://github.com/manuelmenzella/SocketChat-iOS获得
Joh*_*nyC 33
由于行为已经从iOS 7改为iOS 8,我已经在这个问题上一直撞到了墙上.我尝试了一切,直到最明显的解决方案为我工作:
inputAccessoryView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
Run Code Online (Sandbox Code Playgroud)
咄!
max*_*lov 17
总结一下JohnnyC的答案:将你的inpitAccessoryView设置autoresizingMask为.flexibleHeight,计算它intrinsicContentSize并让框架完成剩下的工作.
完整代码,针对Swift 3进行了更新:
class InputAccessoryView: UIView, UITextViewDelegate {
let textView = UITextView()
override var intrinsicContentSize: CGSize {
// Calculate intrinsicContentSize that will fit all the text
let textSize = textView.sizeThatFits(CGSize(width: textView.bounds.width, height: CGFloat.greatestFiniteMagnitude))
return CGSize(width: bounds.width, height: textSize.height)
}
override init(frame: CGRect) {
super.init(frame: frame)
// This is required to make the view grow vertically
autoresizingMask = .flexibleHeight
// Setup textView as needed
addSubview(textView)
textView.translatesAutoresizingMaskIntoConstraints = false
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[textView]|", options: [], metrics: nil, views: ["textView": textView]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[textView]|", options: [], metrics: nil, views: ["textView": textView]))
textView.delegate = self
// Disabling textView scrolling prevents some undesired effects,
// like incorrect contentOffset when adding new line,
// and makes the textView behave similar to Apple's Messages app
textView.isScrollEnabled = false
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: UITextViewDelegate
func textViewDidChange(_ textView: UITextView) {
// Re-calculate intrinsicContentSize when text changes
invalidateIntrinsicContentSize()
}
}
Run Code Online (Sandbox Code Playgroud)
问题是在iOS 8中,自动安装了一个NSLayoutConstraint,它将inputAccessoryView的高度设置为等于其初始帧高.为了解决布局问题,您需要将该约束更新为所需的高度,然后指示您的inputAccessoryView自行布局.
- (void)changeInputAccessoryView:(UIView *)inputAccessoryView toHeight:(CGFloat)height {
for (NSLayoutConstraint *constraint in [inputAccessoryView constraints]) {
if (constraint.firstAttribute == NSLayoutAttributeHeight) {
constraint.constant = height;
[inputAccessoryView layoutIfNeeded];
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
下面是一个完整,独立的解决方案(感谢@JohnnyC和@JoãoNunes指着我在正确的方向,@stigi用于解释如何制作动画intrinsicContent的变化):
class InputAccessoryView: UIView {
// InputAccessoryView is instantiated from nib, but it's not a requirement
override func awakeFromNib() {
super.awakeFromNib()
autoresizingMask = .FlexibleHeight
}
override func intrinsicContentSize() -> CGSize {
let exactHeight = // calculate exact height of your view here
return CGSize(width: UIViewNoIntrinsicMetric, height: exactHeight)
}
func somethingDidHappen() {
// invalidate intrinsic content size, animate superview layout
UIView.animateWithDuration(0.2) {
self.invalidateIntrinsicContentSize()
self.superview?.setNeedsLayout()
self.superview?.layoutIfNeeded()
}
}
}
Run Code Online (Sandbox Code Playgroud)