【发布时间】:2016-02-22 21:25:36
【问题描述】:
我正在尝试通过点击一个按钮来放置一个可扩展的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];不返回所需的值,因为在计算 textSize 时 textView 没有正确的宽度。
所以我相信有以下选择: - 更改布局后强制 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);
}
【问题讨论】:
-
如果您尝试删除约束而不是停用它会发生什么
[cell removeConstraints:cell.constraintTextViewHeight]? -
同样的事情。不确定一旦单元被重用它是否会起作用(这就是我停用而不是删除的原因)
-
我对这个问题有点困惑。通过查看您的 GIF,听起来问题在于首次呈现单元格时按钮不存在。在您似乎暗示的问题中,按钮在那里并且不起作用。请耐心等待,也许只是我误解了这个问题。
-
你是对的。按钮一开始就不在那里,所以我想要的行为不适用于那些。
-
您是否已经为视图/按钮/控件尝试了 [tableView reloadData] 和 [view setNeedsDisplay]?
标签: ios uitableview autolayout nslayoutconstraint