如何强制uitableview调整单元格大小(停用高度约束后)?

jon*_*ypz 11 uitableview ios autolayout nslayoutconstraint

我试图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];

        });
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我点击按钮然后滚动到类似的单元格,它已经扩展.所以我在这里遗漏了一些东西.我[cell updateConstraints]在停用约束后已经尝试过,但它不起作用.

UPDATE

首先,按钮不会出现某些原因.我注意到(使用相同的代码)如果我向下滚动然后向上,按钮会显示,如果我尝试扩展它,它就可以工作.

UPDATE

这是我的UIViewController:

http://www.gfycat.com/FairBossyAfricanporcupine

请注意,延伸按钮不在那里,但是一旦我向下/向上滚动它就显示出来,一旦我点击延伸按钮它就会扩展单元格.

UPDATE

我注意到,当计算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;

}
}
...
Run Code Online (Sandbox Code Playgroud)

所以在第一次运行(滚动之前)[self isTitleExtendable:title forTextView:cell.textViewTitle]; 不会返回所需的值,因为textView在计算textSize时没有正确的宽度.

所以我相信有以下选择: - 在更改布局后强制textViewTitle刷新(从而正确计算可扩展的UI状态) - 一旦textViewTitle改变宽度,重新检查可扩展的UI状态

UPDATE

在方法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);
}
Run Code Online (Sandbox Code Playgroud)

Anc*_*inu 5

要做这样的事情,你不应该依赖于约束,而是tableView(_:heightForRowAtIndexPath:)你只需要根据上下文给出正确的高度。

按下按钮会触发更改,因此tableView(_:heightForRowAtIndexPath:)为您扩展的单元格返回不同的值。

在执行此触发器之后,只需执行以下操作:

[self.tableView beginUpdates];
[self.tableView endUpdates];
Run Code Online (Sandbox Code Playgroud)

它们之间没有任何东西,它将触发“自然动画”UITableView并完全按照您的意愿行事

  • 正如描述所说,我正在使用 UITableViewAutomaticDimension (2认同)

Ami*_*del 0

是否忘记从self.arrayExtendedTitlesAtIndexPaths中删除 indexpath

if (![self.arrayExtendedTitlesAtIndexPaths containsObject:indexPath]) {
    [self.arrayExtendedTitlesAtIndexPaths addObject:indexPath];
}
else
{
   [self.arrayExtendedTitlesAtIndexPaths removeObject:indexPath];
}
Run Code Online (Sandbox Code Playgroud)