18

当我在 iOS 8 中更改高度时inputAccessoryView,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;
}

在评论输入视图中

#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];
    }
}

ios-helpers的 UIView 类别中

- (void)setHeight: (CGFloat)heigth {
    CGRect frame = self.frame;
    frame.size.height = heigth;
    self.frame = frame;
}
4

6 回答 6

19

最后,我找到了答案。在ios8中,苹果给inputAccessoryView添加了一个NSContentSizeLayoutConstraints,并设置了一个44的常量。这个常量不能去掉,因为ios8用它来计算inputAccessoryView的高度。所以,唯一的解决办法是改变这个常数的值。

例子

在 ViewDidAppear 中

- (void)viewDidAppear:(BOOL)animated {
    if ([self.inputAccessoryView constraints].count > 0) {
        NSLayoutConstraint *constraint = [[self.inputAccessoryView constraints] objectAtIndex:0];
        constraint.constant = CommentInputViewBeginHeight;
    }
}

当 textview 高度改变时改变 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];
    }];
}

那是。

于 2014-12-17T09:43:25.437 回答
7

在更改 inputAccessoryView 的高度时,可以更新 Yijun 的答案中提到的约束的一种方法是在 inputAccessoryView 上覆盖 setFrame:。这不依赖于高度约束是数组中的第一个。

- (void)setFrame:(CGRect)frame {
    [super setFrame:frame];

    for (NSLayoutConstraint *constraint in self.constraints) {
        if (constraint.firstAttribute == NSLayoutAttributeHeight) {
            constraint.constant = frame.size.height;
            break;
        }
    }
}
于 2015-11-29T22:21:50.977 回答
3

第一个答案并没有完全解决我的问题,但给了我一个很大的提示。Apple 确实为附件视图添加了一个私有约束,但您在附件视图的约束列表中找不到它。您必须从其超级视图中搜索它。它杀死了我几个小时。

于 2015-06-18T01:44:12.823 回答
2

在阅读了上面的答案(这是一个很好的发现)之后,我担心依赖于您需要更改的约束[0]或者firstObject是将来可能会在我们之下更改的实现细节。

在做了一些调试之后,我发现 Apple 在附件输入视图上添加的约束似乎具有 76 的优先级。这是一个疯狂的低值,而不是文档中列出的枚举之一priority

鉴于这个低值priority,它似乎是一个更简洁的解决方案,可以简单地有条件地添加/删除另一个具有高优先级的约束,比如UILayoutPriorityDefaultHigh当你想要调整视图大小时?

于 2015-05-21T11:52:34.300 回答
1

对于 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()
    }
}
于 2019-11-05T17:26:45.047 回答
0

试试这个: _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];
}
于 2017-03-27T18:43:49.763 回答