ios - Cambiar altura de entrada Problema de AccessoryView
ios8 inputaccessoryview (5)
Cuando cambio la altura de inputAccessoryView
en iOS 8, inputAccessoryView no va al origen correcto, sino que cubre el teclado.
Aquí hay algunos fragmentos de código:
en el controlador de vista de tabla
- (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;
}
en 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];
}
}
en la categoría UIView de ios-helpers
- (void)setHeight: (CGFloat)heigth {
CGRect frame = self.frame;
frame.size.height = heigth;
self.frame = frame;
}
La primera respuesta no resolvió totalmente mi problema, pero me dio una gran pista. Apple agregó una restricción privada a la vista de accesorios, pero no puede encontrarla en la lista de restricciones de la vista de accesorios. Tienes que buscarlo desde su supervista. Me mató unas pocas horas.
Después de leer la respuesta anterior, que es un gran hallazgo, me preocupaba que confiando en la restricción que necesitas para cambiar sea [0]
o firstObject
sea un detalle de implementación que probablemente cambie en el futuro.
Después de hacer un poco de depuración, descubrí que las restricciones añadidas por Apple en la vista de entrada de accesorios parecen tener una prioridad de 76. Este es un valor bajo loco y no una de las enumeraciones enumeradas en la documentación para priority
.
Dado este valor de baja priority
, parece una solución más limpia para agregar / eliminar condicionalmente otra restricción con un nivel de prioridad alto, por ejemplo UILayoutPriorityDefaultHigh
cuando desea cambiar el tamaño de la vista.
Finalmente, encontré la respuesta. En ios8, Apple agrega un NSContentSizeLayoutConstraints para ingresar a AccessoryView y establecer una constante con 44. No se puede eliminar esta constante, porque ios8 la usa para calcular la altura de inputAccessoryView. Entonces, la única solución es cambiar el valor de esta constante.
Ejemplo
en ViewDidAppear
- (void)viewDidAppear:(BOOL)animated {
if ([self.inputAccessoryView constraints].count > 0) {
NSLayoutConstraint *constraint = [[self.inputAccessoryView constraints] objectAtIndex:0];
constraint.constant = CommentInputViewBeginHeight;
}
}
cambie la altura de AccessAccessoryView cuando la altura de la vista de texto ha cambiado
- (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];
}];
}
Es decir.
Una forma de actualizar la restricción mencionada en la respuesta de Yijun cuando se cambia la altura de la entrada AccessView es sobrescribiendo setFrame: en su inputAccessoryView. Esto no depende de que la restricción de altura sea la primera en la matriz.
- (void)setFrame:(CGRect)frame {
[super setFrame:frame];
for (NSLayoutConstraint *constraint in self.constraints) {
if (constraint.firstAttribute == NSLayoutAttributeHeight) {
constraint.constant = frame.size.height;
break;
}
}
}
Pruebe esto: _vwForSendChat es la vista de accesorios de entrada _txtViewChatMessage es la vista de texto dentro de la vista de accesorios de entrada
-(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];
}