Изменить высоту проблемы inputAccessoryView
Когда я меняю высоту inputAccessoryView
в iOS 8 inputAccessoryView не идет в правильное начало, но покрывает клавиатуру.
Вот некоторые фрагменты кода:
в контроллере табличного представления
- (UIView *)inputAccessoryView {
if (!_commentInputView) {
_commentInputView = [[CommentInputView alloc] initWithFrame:CGRectMake(0, 0, [self width], 41)];
[_commentInputView setPlaceholder:NSLocalizedString(@"Comment", nil) andButtonTitle:NSLocalizedString(@"Send", nil)];
[_commentInputView setBackgroundColor:[UIColor whiteColor]];
_commentInputView.hidden = YES;
_commentInputView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;
}
return _commentInputView;
}
в CommentInputView
#when the textview change height
- (void)growingTextView:(HPGrowingTextView *)growingTextView willChangeHeight:(float)height {
if (height > _textView_height) {
[self setHeight:(CGRectGetHeight(self.frame) + height - _textView_height)];
[self reloadInputViews];
}
}
в категории UIView от ios-помощников
- (void)setHeight: (CGFloat)heigth {
CGRect frame = self.frame;
frame.size.height = heigth;
self.frame = frame;
}
5 ответов
Наконец-то я нашел ответ. В ios8 яблоко добавляет NSContentSizeLayoutConstraints к inputAccessoryView и устанавливает константу с 44. Вы не можете удалить этот containt, потому что ios8 использует его для вычисления высоты inputAccessoryView. Итак, единственное решение - изменить значение этой константы.
пример
в ViewDidAppear
- (void)viewDidAppear:(BOOL)animated {
if ([self.inputAccessoryView constraints].count > 0) {
NSLayoutConstraint *constraint = [[self.inputAccessoryView constraints] objectAtIndex:0];
constraint.constant = CommentInputViewBeginHeight;
}
}
изменить inputAccessoryView высоту при изменении высоты просмотра текста
- (void)growingTextView:(HPGrowingTextView *)growingTextView willChangeHeight:(float)height {
NSLayoutConstraint *constraint = [[self constraints] objectAtIndex:0];
float new_height = height + _textView_vertical_gap*2;
[UIView animateWithDuration:0.2 animations:^{
constraint.constant = new_height;
} completion:^(BOOL finished) {
[self setHeight:new_height];
[self reloadInputViews];
}];
}
То есть.
Одним из способов обновления ограничения, упомянутого в ответе Ицзюня при изменении высоты inputAccessoryView, является перезапись setFrame: на свой inputAccessoryView. Это не зависит от ограничения высоты, являющегося первым в массиве.
- (void)setFrame:(CGRect)frame {
[super setFrame:frame];
for (NSLayoutConstraint *constraint in self.constraints) {
if (constraint.firstAttribute == NSLayoutAttributeHeight) {
constraint.constant = frame.size.height;
break;
}
}
}
Первый ответ не полностью решил мою проблему, но дал мне огромный намек. Apple добавила частное ограничение в дополнительное представление, но вы не можете найти его в списке ограничений дополнительного представления. Вы должны искать это из его суперпредставления. Это убило меня на несколько часов.
Прочитав ответ выше, который является отличной находкой, я был обеспокоен тем, что полагаясь на ограничение, которое нужно изменить [0]
или же firstObject
это деталь реализации, которая может измениться под нами в будущем.
После небольшой отладки я обнаружил, что добавленные Apple ограничения на представление ввода аксессуаров, кажется, имеют приоритет 76. Это сумасшедшее низкое значение, и оно не входит в перечисленные в документации перечисления для priority
,
Учитывая этот низкий priority
оцените, что это кажется более чистым решением - просто условно добавить / удалить другое ограничение с высоким уровнем приоритета, скажем, UILayoutPriorityDefaultHigh
когда вы хотите изменить размер представления?
Для Xcode 11.2 и swift 5 эта функция обновит ограничения inputAccessoryView даже в блоке анимации
func updateInputContainerConstraints() {
if let accessoryView = inputAccessoryView,
let constraint = accessoryView.superview?.constraints.first(where: { $0.identifier == "accessoryHeight" }) {
constraint.isActive = false
accessoryView.layoutIfNeeded()
constraint.constant = accessoryView.bounds.height
constraint.isActive = true
accessoryView.superview?.addConstraint(constraint)
accessoryView.superview?.superview?.layoutIfNeeded()
}
}
Попробуйте это: _vwForSendChat - представление аксессуара ввода _txtViewChatMessage - представление текста внутри представления аксессуара ввода
-(void)textViewDidChange:(UITextView *)textView {
CGFloat fixedWidth = textView.frame.size.width;
CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = textView.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
if (newFrame.size.height < 40) {
_vwForSendChat.frame = CGRectMake(0, 0, self.view.frame.size.width, 40);
} else {
if (newFrame.size.height > 200) {
_vwForSendChat.frame = CGRectMake(0, 0, self.view.frame.size.width, 200);
} else {
_vwForSendChat.frame = CGRectMake(0, 0, self.view.frame.size.width, newFrame.size.height);
}
}
[self.txtViewChatMessage reloadInputViews];
}