在我的cell.xib中,我有一个标签,其所有方面都有约束.我已将该标签设置为lines = 0和line-break = word wrap.然后,我对我的TableView执行此操作:
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 100.0
Run Code Online (Sandbox Code Playgroud)
一切都很好,我的UITableViewCell是自动高度.如果文本很长,那么我的tableView会智能地计算大小.
问题是 - 一旦内容在单元格中发生变化,如何告诉我的UITableView"重新计算"大小?
我的单元格可以调用它的委托,在这个委托中,我希望TableView重新绘制高度.
现在,我的细胞中的内容不断变化,但细胞高度永远不会改变.
所以,似乎heightForRowAtIndexPath之前被称为cellForRowAtIndexPath.我目前正在使用cellForRowAtIndexPath计算每个单元格的高度(它们是可变高度,使用其中UILabel包含不同数量的文本.
如果在计算它的方法之前调用设置高度的方法,我对如何正确设置单元格的高度感到困惑.
我已经创建了一个类别NSString,另一个UILabel,它们共同构成UILabel了合适的大小.问题是UITableViewCell包含这些标签的实例没有调整大小,因此标签悬挂在每个标签的末尾,与下面的标签重叠.
我知道我需要做的是让单元格的高度等于标签的高度,再加上一些额外的边距空间,但是我很困惑如何在计算标签高度之前设置高度.我可以在不使用的情况下设置身高heightForRowAtIndexPath吗?或者如果没有,我可以在其他地方计算出细胞的高度吗?我目前正在indexPath.row尝试实现这一目标,所以事先做这件事会很棘手.这是代码我的cellForRowAtIndexPath:
的cellForRowAtIndexPath
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath
{
FQCustomCell *_customCell = [tableView dequeueReusableCellWithIdentifier: @"CustomCell"];
if (_customCell == nil) {
_customCell = [[FQCustomCell alloc] initWithStyle: UITableViewCellStyleValue1 reuseIdentifier: @"CustomCell"];
}
_customCell.myLabel.text = [[_loadedNames objectAtIndex: indexPath.row] name];
_customCell.myLabel.font = [UIFont fontWithName: @"FontA" size: 15.0f];
UIView *backView = [[UIView alloc] initWithFrame: …Run Code Online (Sandbox Code Playgroud) 我有点困惑于这个......任何帮助都非常感激.我已经花了很多时间调试这个.
我有UITableView数据源提供NSFetchedResultsController.在单独的视图控制器中,我使用新的记录向CoreData插入[NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:],保存托管对象上下文并关闭该控制器.很标准的东西.
然后通过NSFetchedResultsController以下方式接收托管对象上下文中的更改:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
switch (type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
case NSFetchedResultsChangeUpdate:
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
}
}
Run Code Online (Sandbox Code Playgroud)
这就是出现问题的地方 - 这需要太长时间(在iPhone 4上大约3-4秒).似乎花费时间计算细胞的布局.
我从单元格中删除了所有内容(包括自定义子类)并将其保留UILabel,但没有任何改变.然后我将单元格的样式更改为Basic(或除Custom之外的任何内容)并且问题消失了 - 即时添加新单元格.
我加倍检查,NSFetchedResultsControllerDelegate回调只被调用一次.如果我忽略它们并做 …
我用来创建矩形的代码(至少在iOS7之前)是
CGRect rect = [cTableView frame];
rect.origin.y += [cTableView rowHeight];
searchOverlayView = [[BecomeFirstResponderControl alloc] initWithFrame:rect];
Run Code Online (Sandbox Code Playgroud)
在iOS7上,cTableView(一个实例UITableView)返回44.使用iPhone 5s在iOS8中进行测试-1.
为什么会这样?为了使我的应用程序向后兼容iOS7,需要使用哪些正确的代码?
我想做一个UITableViewCell更大的.我怎么能这样做,我试过调整它的框架,但没有任何反应.我能做什么?
我正在以编程方式使用自动布局约束,并且我经常在我的应用程序中看到同样的错误,通常与看起来像这样的约束相关:
"<NSAutoresizingMaskLayoutConstraint:0x82da910 h=--& v=--& V:[UITableViewCellContentView:0x82d9fb0(99)]>"
Run Code Online (Sandbox Code Playgroud)
我在https://github.com/nicolasccit/AutoLayoutCellWarning上放了一些示例代码来重现
在这个例子中,我创建了一个包含2个UI元素的非常简单的视图:一个名为imageThumbnail的图像视图和一个名为labelName的标签,带有一些约束:
"H:|-padding-[_imageThumbnail(==imageWidth)]-[_labelName]";
"V:|-padding-[_imageThumbnail(==imageHeight)]-padding-|";
"V:|-padding-[_labelName]";
Run Code Online (Sandbox Code Playgroud)
在这两个元素上,我将AutoresizingMaskIntoConstraints设置为NO.
我得到以下例外:
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0xa6e4f90 …Run Code Online (Sandbox Code Playgroud) 我在UITableView中使用自动布局和大小类,单元格根据其内容自行调整大小.为此,我使用的方法对于每种类型的单元格,您保留该单元格的屏幕外实例并使用systemLayoutSizeFittingSize它来确定正确的行高 - 此方法在此StackOverflow帖子和其他地方进行了很好的解释.
这很有效,直到我开始使用大小类.具体来说,我在常规宽度布局中为文本的边距约束定义了不同的常量,因此iPad上的文本周围有更多的空白.这给了我以下结果.

似乎新的约束集合得到了尊重(存在更多的空白),但行高度计算仍然返回与不应用特定于大小类的约束的单元格相同的值.屏幕外单元格中的部分布局过程不考虑窗口的大小等级.
现在我想,这可能是因为离屏幕视图有没有上海华盈或窗口,因此它不具有任何尺寸类性状是指在点systemLayoutSizeFittingSize调用时(即使它似乎使用的调整限制边距).我现在通过在创建UIWindow后添加屏幕外的大小调整单元作为子视图来解决这个问题,从而得到所需的结果:

这是我在代码中所做的事情:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let contentItem = content[indexPath.item]
if let contentType = contentItem["type"] {
// Get or create the cached layout cell for this cell type.
if layoutCellCache.indexForKey(contentType) == nil {
if let cellIdentifier = CellIdentifiers[contentType] {
if var cachedLayoutCell = dequeueReusableCellWithIdentifier(cellIdentifier) as? UITableViewCell {
UIApplication.sharedApplication().keyWindow?.addSubview(cachedLayoutCell)
cachedLayoutCell.hidden = true
layoutCellCache[contentType] = cachedLayoutCell
}
}
}
if …Run Code Online (Sandbox Code Playgroud) 为什么需要preferredMaxLayoutWidth?
preferredMaxLayoutWidth
多行标签的首选最大宽度(以磅为单位).
应用布局约束时,此属性会影响标签的大小.在布局期间,如果文本超出此属性指定的宽度,则附加文本将流向一个或多个新行,从而增加标签的高度.
注意这个:
如果文本超出此属性指定的宽度,则附加文本将流向一个或多个新行
因此,一个多标签上,如果preferredMaxLayoutWidth没有设置属性,将文本只是去超越bounds的UILabel?
为什么我们希望在我们明确设置为多线的标签上发生这种情况?
这个属性存在的真正原因是什么?它是自动布局的东西吗?请解释一下,我真的很想了解这一点.
我正在使用xib和auto布局来构建我的自定义单元格,在我的单元格中,有一个多行标签.在tableview的heightForRowAtIndexPath中,我将使用

1 dequeueReusableCellWithIdentifier获取一个单元格
2然后调用[cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]以获得正确的高度.
但是在调试中,我发现当调用heightForRowAtIndexPath时,我的单元格宽度不是tableview的宽度,单元格的宽度与xib文件的宽度相同(因为在xcode6中,你可以将xib大小设置为any).所以从systemLayoutSizeFittingSize得到的高度是不正确的.如何解决此问题以获得正确的单元格高度
从systemLayoutSizeFittingSize得到的大小:不正确,这个大小的宽度可以是340+(而设备是宽度为320的iPhone5),而340+则是单元格的xib文件的宽度
最后,我得到了解决方案,感谢Ashish Gabani的帮助,实际上,解决方案包括2步:1在调用systemLayoutSizeFittingSize之前将单元格框重置为tableView size 2调用单元格的layoutSubViews,并且在自定义单元格中,需要重写layoutSubViews方法.这是解决这个问题的代码,我使用红色方块来标记它们,享受它

问题总结:当我在有很多细胞经常死机UITableView动画的高度时UITableViewCell从UITextView编辑它的文本.使用iOS 8自定义单元格.
长问题:我已经成功实现了所以我可以动态地使用iOS 8自定义单元格将文本输入到单元格UITextView中并更改单元格高度而不会失去焦点(firstReponder).但是,如果tableView太大(行太多),它会崩溃.这是我的堆栈跟踪:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(
0 CoreFoundation 0x000000010b3b3d85 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010b9cbdeb objc_exception_throw + 48
2 CoreFoundation 0x000000010b274cc5 -[__NSArrayM insertObject:atIndex:] + 901
3 UIKit 0x0000000108b05439 __46-[UITableView _updateWithItems:updateSupport:]_block_invoke1029 + 180
4 UIKit 0x0000000108a7e838 +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 582
5 UIKit 0x0000000108a7ec6d +[UIView(UIViewAnimationWithBlocks) animateWithDuration:delay:options:animations:completion:] + 105
6 UIKit 0x0000000108b05048 -[UITableView _updateWithItems:updateSupport:] + 4590 …Run Code Online (Sandbox Code Playgroud) ios ×10
uitableview ×7
autolayout ×5
objective-c ×3
uikit ×2
ios7 ×1
iphone ×1
performance ×1
size-classes ×1
swift ×1