iOS 8使用UITextView自动调整UITableViewCell的大小

iOS 8使用UITextView自动调整UITableViewCell的大小,uitableview,autolayout,ios8,Uitableview,Autolayout,Ios8,iOS 8为TableView引入了一种根据内容自动调整单元格高度的方法(通过自动布局) 我已经把它和标签、图像等联系起来了 但是,我无法找到一种方法,使表格视图单元格在单元格的文本视图发生变化时自动增长? 有关设置的更多信息: 单元格内的UITextView对表格视图单元格的contentView具有水平和垂直约束。我还禁用了文本视图的滚动 我还尝试手动更改单元格的高度限制,但单元格也不会采用这些更改。在UITextViewDelegate的textViewDidBeginEditing:方法

iOS 8为TableView引入了一种根据内容自动调整单元格高度的方法(通过自动布局)

我已经把它和标签、图像等联系起来了

但是,我无法找到一种方法,使表格视图单元格在单元格的文本视图发生变化时自动增长?

有关设置的更多信息: 单元格内的UITextView对表格视图单元格的contentView具有水平和垂直约束。我还禁用了文本视图的滚动


我还尝试手动更改单元格的高度限制,但单元格也不会采用这些更改。

UITextViewDelegate的
textViewDidBeginEditing:
方法中重新加载单元格

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForItem:0 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];

显然,您应该为您的单元格将indexpath更改为正确的。这将使单元格更新其约束并调整自身大小。

这是我使用的函数,它解决了每次击键后表格视图反弹的问题

 - (void)textViewDidChange:(UITextView *)textView {

    CGFloat fixedWidth = textView.frame.size.width;
    CGSize oldSize = textView.frame.size;
    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
        // Resize cell only when cell's size changes, to prevent bouncing back and forth.
        if (oldSize.height != newSize.height) {
        [UIView setAnimationsEnabled:NO];
        CGRect newFrame = textView.frame;
        newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
        textView.frame = newFrame;
        [self.tableView beginUpdates];
        [self.tableView endUpdates];
        [UIView setAnimationsEnabled:YES];
        }
    }

如果一切都设置正确(自动布局约束),您不必自己计算任何内容

您所要做的就是禁用UITextView的滚动启用属性,然后打开
textViewDidChange
调用
tableView.beginUpdate()
tableView.endUpdate()


有关详细说明,请查看一个包含工作示例项目的解决方案。

Swift 4解决方案

func textViewDidChange(_ textView: UITextView) {
    let fixedWidth = textView.frame.size.width
    let oldSize = textView.frame.size
    let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT)))
    if oldSize.height != newSize.height {
        UIView.setAnimationsEnabled(false)
        var newFrame = textView.frame
        newFrame.size = CGSize(width: fmax(newSize.width, fixedWidth), height: newSize.height)
        textView.frame = newFrame
        self.tableView.beginUpdates()
        self.tableView.endUpdates()
        UIView.setAnimationsEnabled(true)
    }
}

您应该禁用UITextView中的滚动功能,
tableView
必须被告知
textView
已更改。其他帖子通常回答“静态”问题。但是,如果您在表格中键入,则单元格需要随着
textView
的增长而增长。
textView
通过禁用滚动而增长。通过将
textView
的顶部和底部约束设置为单元格的
contentView
约束,单元格将增长。一旦表格加载,这将工作一次。但是,要让
tableView
实时增长,您必须在
textView
didChange
委托调用中执行此操作

func textViewChanged(onCell cell: YourCustomCell) {
    UIView.setAnimationsEnabled(false)
    tableView.beginUpdates()
    tableView.endUpdates()
    UIView.setAnimationsEnabled(true)
}

这将如您所期望的那样工作。单元格将随着您的键入而增长,不会出现“反弹”。

这方面有进展吗?我期待着做同样的事。。。当用户键入时,您是否尝试让它工作?或者您正在使用的UITextView不是用户可编辑的吗?它似乎可以工作,即使没有
重新加载rowsatindexpaths:
,它有一个键盘的好处,可以让我停留在这里。这种方法会导致表视图在每次按键时都会滚动回顶部,这使得文本视图基本上无法使用-其他人有这个问题吗?(iOS 8.1.2)我应该补充一点,我已经将此代码放入
textViewDidChange:
,而不是
textViewDidBeginEditing:
(在开始编辑时只设置高度有什么用?)@James,如果你在开始编辑行之前禁用动画,然后在之后重新启用动画,你可以摆脱恼人的反弹。如果单元格位于底部,并且你需要滚动到此点才能看到,会发生什么?是的,不幸的是,我也有这个问题。不知道如何修复它。它是否也适用于UIWebView而不是UIExtView?我不确定,UIWebView可能有不同的布局过程,但值得一试!只需删除滚动功能就可以了。谢谢:)UITableViewController中的静态单元格如何?我在“shouldChangeTextIn”中添加了此代码,效果很好。但不适用于新行,并且在键入字符//textview驻留在tableview单元格中后,它会增长
func textViewChanged(onCell cell: YourCustomCell) {
    UIView.setAnimationsEnabled(false)
    tableView.beginUpdates()
    tableView.endUpdates()
    UIView.setAnimationsEnabled(true)
}