XCode iOS7 - 带 UITextView 的动态单元格,如 Reminder App
XCode iOS7 - Dynamic cell with UITextView like Reminder App
我需要创建一个与内置提醒应用程序具有相同行为的应用程序。创建这个有一些问题:
- 具有动态高度和 "grow" 作为 UITextView 内容的单元格
- 选择触摸的单元格
- 当用户编辑内容时刷新单元格的高度(动态)
我已经使用一些技巧解决了动态高度问题。
剩下的问题是:
如果单元格是 "fully" with UITextView,如何知道用户选择了哪个单元格?
现在我已经使用方法 textViewDidBeginEditing 来了解单元格并将 UITableView 滚动到它:
- (void)textViewDidBeginEditing:(UITextView*)textView
{
MemoViewCell* cell = (MemoViewCell *)[self parentCellFor:textView];
if (cell)
{
NSIndexPath* indexPath = [self.tableView indexPathForCell:cell];
currentIndexPath = indexPath;
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
}
- (UITableViewCell*)parentCellFor:(UIView*)view
{
if (!view)
return nil;
if ([view isMemberOfClass:[MemoViewCell class]])
return (UITableViewCell*)view;
return [self parentCellFor:view.superview];
}
如何在不失去焦点的情况下刷新cell高度?
为此,我使用了这个方法:
-(void)textViewDidChange:(UITextView *)textView
{
NSMutableDictionary *dataSourceItem = [self.model.dataSource objectAtIndex:currentIndexPath.row];
[dataSourceItem setObject:textView.text forKeyedSubscript:@"body"];
[self.model.dataSource setObject:dataSourceItem atIndexedSubscript:currentIndexPath.row];
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
当文本更改时,我得到新文本,我在模型中更改它并调用 beginUpdated 和 endUpdates。
当然,这行得通,但一切都非常慢...您是否有一些想法以更优雅的方式实现这一点并且也许...高效?
如果我调用 reloadRowsAtIndexPaths:我失去了对单元格的关注。
首先,如果您在动态高度技巧中使用了委托方法- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
,请记得沿- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;
实现此方法,这对性能有很大帮助。
然后专注于您的特定项目,如果我正确理解您的目标,您真正想要的是仅在修改文本视图时更新 table 视图的布局。当前,您在每次文本更改时更新它。您可以考虑在 -(void)textViewDidChange:(UITextView *)textView
中使用条件,例如:
if ([textView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height !=
textView.frame.size.height) {
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
仅当您现有的单元格布局符合文本视图的固有内容大小时,作为示例给出的条件才有效,否则您将需要调整该条件。
我需要创建一个与内置提醒应用程序具有相同行为的应用程序。创建这个有一些问题:
- 具有动态高度和 "grow" 作为 UITextView 内容的单元格
- 选择触摸的单元格
- 当用户编辑内容时刷新单元格的高度(动态)
我已经使用一些技巧解决了动态高度问题。
剩下的问题是:
如果单元格是 "fully" with UITextView,如何知道用户选择了哪个单元格?
现在我已经使用方法 textViewDidBeginEditing 来了解单元格并将 UITableView 滚动到它:
- (void)textViewDidBeginEditing:(UITextView*)textView
{
MemoViewCell* cell = (MemoViewCell *)[self parentCellFor:textView];
if (cell)
{
NSIndexPath* indexPath = [self.tableView indexPathForCell:cell];
currentIndexPath = indexPath;
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
}
- (UITableViewCell*)parentCellFor:(UIView*)view
{
if (!view)
return nil;
if ([view isMemberOfClass:[MemoViewCell class]])
return (UITableViewCell*)view;
return [self parentCellFor:view.superview];
}
如何在不失去焦点的情况下刷新cell高度?
为此,我使用了这个方法:
-(void)textViewDidChange:(UITextView *)textView
{
NSMutableDictionary *dataSourceItem = [self.model.dataSource objectAtIndex:currentIndexPath.row];
[dataSourceItem setObject:textView.text forKeyedSubscript:@"body"];
[self.model.dataSource setObject:dataSourceItem atIndexedSubscript:currentIndexPath.row];
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
当文本更改时,我得到新文本,我在模型中更改它并调用 beginUpdated 和 endUpdates。
当然,这行得通,但一切都非常慢...您是否有一些想法以更优雅的方式实现这一点并且也许...高效?
如果我调用 reloadRowsAtIndexPaths:我失去了对单元格的关注。
首先,如果您在动态高度技巧中使用了委托方法- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
,请记得沿- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;
实现此方法,这对性能有很大帮助。
然后专注于您的特定项目,如果我正确理解您的目标,您真正想要的是仅在修改文本视图时更新 table 视图的布局。当前,您在每次文本更改时更新它。您可以考虑在 -(void)textViewDidChange:(UITextView *)textView
中使用条件,例如:
if ([textView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height !=
textView.frame.size.height) {
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
仅当您现有的单元格布局符合文本视图的固有内容大小时,作为示例给出的条件才有效,否则您将需要调整该条件。