web-dev-qa-db-ja.com

inputAccessoryViewの問題の高さを変更する

IOS8でinputAccessoryViewの高さを変更すると、inputAccessoryViewは正しいOriginに移動しませんが、キーボードを覆います。

enter image description here

コードスニペットは次のとおりです。

テーブルビューコントローラーで

- (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-helpers

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

最後に、私は答えを見つけました。 ios8では、Apple NSContentSizeLayoutConstraintsをinputAccessoryViewに追加し、定数を44に設定します。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];
    }];
}

あれは。

19
Yijun

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;
        }
    }
}
7
stu

最初の答えは私の問題を完全には解決しませんでしたが、私に大きなヒントを与えました。 Appleはアクセサリビューにプライベート制約を追加しましたが、アクセサリビューの制約リストに見つかりません。スーパービューから検索する必要があります。数時間で死亡しました。 。

3
Wizard

上記の回答を読んだ後、これはすばらしい発見です。変更する必要のある制約が[0]またはfirstObjectであることに依存することは、将来変更される可能性のある実装の詳細であると懸念しました。

少しデバッグを行った後、Appleが追加したアクセサリ入力ビューの制約の優先度が76であることがわかりました。これは非常に低い値であり、priorityのドキュメントに記載されている列挙型の1つではありません。

この低いpriority値を考えると、ビューのサイズを変更するときにUILayoutPriorityDefaultHighなど、優先度の高いレベルの別の制約を条件付きで追加/削除する方が簡単な解決策のようです。

2
Cocoadelica

これを試してください:_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];
}
0
Harshit

Xcode11.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()
    }
}
0
Roman Filippov