我试图通过点击按钮来放置可扩展的UITableViewCell
。
我正在使用约束来强制动态UITextView
告诉UITableViewCell
它的新高度。 (使用自动布局和UITableViewAutomaticDimension
)
没有按钮,这可以正常工作:UITableViewCell
的高度取决于UITextView
的高度。
在UITextView
上有一个约束来最大化单元格的大小,当点击按钮(单元格被折叠)时,我想删除UITextView
的高度约束(这限制了单元格高度)并相应地更新单元格。这是扩展方法:
-(void)extendCellWasTapped:(UITableViewCell*)senderCell{
MAFollowingPostTableViewCell *cell = (MAFollowingPostTableViewCell*)senderCell;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
if (![self.arrayExtendedTitlesAtIndexPaths containsObject:indexPath]) {
[self.arrayExtendedTitlesAtIndexPaths addObject:indexPath];
}
if ([self.tableView.indexPathsForVisibleRows containsObject:indexPath] ) {
dispatch_async(dispatch_get_main_queue(), ^(void){
[NSLayoutConstraint deactivateConstraints:@[cell.constraintTextViewHeight]];
// CGPoint offset = self.tableView.contentOffset;
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
// I would like to minimize the animations as well here.. but thats another //problem
// [self.tableView.layer removeAllAnimations];
// [self.tableView setContentOffset:offset animated:NO];
// [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
});
}
}
如果我点击按钮然后滚动到类似的单元格,它已经展开。所以我在这里遗漏了一些东西。在停用约束后我已经尝试[cell updateConstraints]
,但它不起作用。
更新
首先,该按钮由于某种原因不显示。我注意到(使用相同的代码)如果我向下滚动然后向上,按钮会显示,如果我尝试扩展它,它就会起作用。
更新
这是我的UIViewController:
http://www.gfycat.com/FairBossyAfricanporcupine
请注意,延伸按钮不在那里,但是一旦我向下/向上滚动它就显示出来,一旦我点击延伸按钮它就会扩展单元格。
更新
我注意到在计算textSize时(查看单元格是否可扩展),首先,textView比其最终状态更宽。我正在对cellForRowAtIndexPath执行此检查:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MAPostTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier forIndexPath:indexPath];
cell.delegate = self;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
MAPostFollowing *post = (MAPostFollowing*)[self.arrayPosts objectAtIndex:indexPath.section];
cell.textViewTitle.textContainer.lineBreakMode = NSLineBreakByWordWrapping;
NSString *title = [post.post title];
[cell.textViewTitle setText:title];
UIButton * buttonExtend = [cell buttonExtend];
if ([self.arrayExtendedTitlesAtIndexPaths containsObject:indexPath]) {
cell.constraintTextViewHeight.active = NO;
if (![buttonExtend isHidden]) {
buttonExtend.hidden = YES;
buttonExtend.userInteractionEnabled = NO;
}
}else{
cell.constraintTextViewHeight.active = YES;
NSLog(@"index %li", (long)indexPath.row);
BOOL b = ![self isTitleExtendable:title forTextView:cell.textViewTitle]; // Checks if the current text view is able to fit the title. If not, it will show the buttonExtend
buttonExtend.hidden = b;
buttonExtend.userInteractionEnabled = !b;
}
}
...
所以在第一次运行时(滚动之前)[self isTitleExtendable:title forTextView:cell.textViewTitle];不会返回所需的值,因为textView在计算textSize时没有正确的宽度。
所以我相信有以下选择: - 强制textViewTitle在更改布局后刷新(从而正确计算可扩展的UI状态) - 一旦textViewTitle改变宽度
,重新检查可扩展的UI状态更新
在方法prepareForReuse上,textViewTitle仍然有一个更宽的框架。在layoutSubviews方法上,它实际上有一个小框架。这里面临的挑战是被更频繁地调用,它会让我感到虚假(不应该显示按钮)
这就是我正在尝试的:
-(void)layoutSubviews{
[super layoutSubviews];
BOOL b = [self isTitleExtendable:self.textViewTitle.text forTextView:self.textViewTitle];
self.buttonExtend.hidden = !b;
self.buttonExtend.userInteractionEnabled = b;
if (!b) {
NSLog(@"Button hidden YES UserInteraction NO");
}else{
NSLog(@"Button hidden NO UserInteraction YES");
}
NSLog(@"textViewTitle layout %f",self.textViewTitle.frame.size.width);
}
答案 0 :(得分:4)
要做这样的事情,你不应该依赖约束,但是在tableView(_:heightForRowAtIndexPath:)
你必须根据上下文给出正确的高度。
按下按钮会触发更改,因此tableView(_:heightForRowAtIndexPath:)
会为您延伸的单元格返回不同的值。
在执行此触发后,只需执行以下操作:
[self.tableView beginUpdates];
[self.tableView endUpdates];
它们之间没有任何东西,它会触发UITableView
的“自然动画”并完全按你想要的那样做
答案 1 :(得分:0)
忘记从 self.arrayExtendedTitlesAtIndexPaths 中删除indexpath ?
if (![self.arrayExtendedTitlesAtIndexPaths containsObject:indexPath]) {
[self.arrayExtendedTitlesAtIndexPaths addObject:indexPath];
}
else
{
[self.arrayExtendedTitlesAtIndexPaths removeObject:indexPath];
}
答案 2 :(得分:0)
如果按钮不在那里,当你滚动它时再次显示肯定你有可重用性的问题。
您可能决定在cellForRowAtIndexPath:
中显示或隐藏按钮。如果你有一个条件,那么总是尝试显示这个按钮,如果这个按预期工作,那么只要有或没有这个约束,就会在单元格内隐藏一个按钮。正确的方法是prepareForReuse
子类内的UITableViewCell
。
答案 3 :(得分:0)
完成更改后,请致电[cell layoutSubviews];
。