如何根据文字长度增加 UITextview 高度,如 whatsapp

Posted

技术标签:

【中文标题】如何根据文字长度增加 UITextview 高度,如 whatsapp【英文标题】:How to increase UITextview height according to text length like whatsapp 【发布时间】:2015-09-29 05:24:54 【问题描述】:

我已经使用 websocket 在我的 ios 应用程序中实现了聊天功能,它对我来说工作正常。

问题是我想增加 UITextView 的高度,UITableView 应该根据 UITextView 增加的高度向上移动。谁能帮帮我?

以下是我在应用程序中使用的代码:

- (void)viewDidAppear:(BOOL)animated

    AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication]delegate];

    [super viewDidAppear:animated];


    UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
    [self.messagesTextView addGestureRecognizer:tgr];

    [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillChangeFrameNotification object:nil queue:nil usingBlock:^(NSNotification *note) 
        CGRect endFrame = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
        UIViewAnimationCurve curve = [note.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
        CGFloat duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];

        UIViewAnimationOptions options = curve << 16;

        [UIView animateWithDuration:duration delay:0.0 options:options animations:^

            NSLog(@"frame: %@", NSStringFromCGRect(endFrame));


            CGRect frame = self.txtView.frame;
            if (isMsgLong==TRUE) 
                frame.origin.y = self.view.frame.size.height- CGRectGetHeight(self.txtView.frame)-216;

            
            else 

                frame.origin.y = CGRectGetMinY(endFrame) - CGRectGetHeight(self.txtView.frame);
            
            self.txtView.frame = frame;


            CGRect frame1 = self.sendButton.frame;
            frame1.origin.y = CGRectGetMinY(endFrame) - CGRectGetHeight(self.sendButton.frame);
            self.sendButton.frame = frame1;


            frame = self.messagesTextView.frame;
            frame.size.height = CGRectGetMinY(self.txtView.frame) - CGRectGetMinY(frame);
            self.messagesTextView.frame = frame;

            NSLog(@"did appear: %@", NSStringFromCGRect(self.txtView.frame));

         completion:nil];
    ];



- (void)keyboardWillShow:(NSNotification *)note


    [UIView animateWithDuration:0.3 animations:^
        NSDictionary *info = note.userInfo;
        NSValue *value = info[UIKeyboardFrameEndUserInfoKey];
        CGRect rawFrame = [value CGRectValue];
        CGRect keyboardFrame = [self.view convertRect:rawFrame fromView:nil];

        NSLog(@"frame: %@", NSStringFromCGRect(self.txtView.frame));

        self.txtView.transform = CGAffineTransformMakeTranslation(0, -keyboardFrame.size.height);

        self.sendButton.transform = CGAffineTransformMakeTranslation(0, -keyboardFrame.size.height);
        self.messagesTableView.contentInset=UIEdgeInsetsMake(0, 0,keyboardFrame.size.height,0);
        //keyboardFrame.size.height

        NSLog(@"frame1: %@", NSStringFromCGRect(self.txtView.frame));

        isMsgLong = FALSE;

    ];


- (void)keyboardWillHide:(NSNotification *)note

    [UIView animateWithDuration:0.3 animations:^

        NSLog(@"frame2: %@", NSStringFromCGRect(self.txtView.frame));
        self.txtView.transform = CGAffineTransformIdentity;


        NSLog(@"frame3: %@", NSStringFromCGRect(self.txtView.frame));

        self.sendButton.transform = CGAffineTransformIdentity;
        self.messagesTableView.transform = CGAffineTransformIdentity;

        isMsgLong = TRUE;
    ];


-(void)textViewDidEndEditing:(UITextView *)textView

    self.messagesTableView.contentInset=UIEdgeInsetsMake(0, 0, 0, 0);

    self.txtView.transform = CGAffineTransformMakeTranslation(0, -216);
    self.sendButton.transform = CGAffineTransformMakeTranslation(0, -216);


    NSLog(@"frame5: %@", NSStringFromCGRect(self.txtView.frame));


    NSInteger lastSectionIndex = [self.messagesTableView numberOfSections] - 1;
    NSInteger lastRowIndex = [self.messagesTableView numberOfRowsInSection:lastSectionIndex] - 1;
    if (lastRowIndex==-1) 
        lastRowIndex=0;
    
    NSIndexPath *pathToLastRow = [NSIndexPath indexPathForRow:lastRowIndex inSection:lastSectionIndex];

    if (lastRowIndex==0) 

    
    else 
        [self.messagesTableView scrollToRowAtIndexPath:pathToLastRow atScrollPosition:UITableViewScrollPositionBottom animated:NO];
    //UITableViewScrollPositionMiddle
    

【问题讨论】:

请阅读***.com/help/how-to-ask 【参考方案1】:

这适用于 iOS 6.1 和 iOS 7,如果您使用的是 Objective C,则可以使用以下代码:

- (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);
    textView.frame = newFrame;

或者,如果您使用的是 Swift,请使用:

let fixedWidth = textView.frame.size.width
textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
var newFrame = textView.frame
newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
textView.frame = newFrame;

如果您想要支持 iOS 6.1,那么您也应该这样做:

textview.scrollEnabled = NO;

【讨论】:

如果您使用自动布局,请不要使用sizeThatFits:

以上是关于如何根据文字长度增加 UITextview 高度,如 whatsapp的主要内容,如果未能解决你的问题,请参考以下文章

UITextView 文字在高度达到 8192.0 后变得不可见

UITextView 内容在增加高度时改变位置

UITextView 根据内容动态改变高度?

如何使用 NSLayoutConstraint 限制 UIButton 的高度

iOS Swift - 动态增加 UITextView 和父 UIView 的高度

动态调整 UITextView 的宽度和高度