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)
要做这样的事情,你不应该依赖于约束,而是tableView(_:heightForRowAtIndexPath:)你只需要根据上下文给出正确的高度。
按下按钮会触发更改,因此tableView(_:heightForRowAtIndexPath:)为您扩展的单元格返回不同的值。
在执行此触发器之后,只需执行以下操作:
[self.tableView beginUpdates];
[self.tableView endUpdates];
Run Code Online (Sandbox Code Playgroud)
它们之间没有任何东西,它将触发“自然动画”UITableView并完全按照您的意愿行事
是否忘记从self.arrayExtendedTitlesAtIndexPaths中删除 indexpath?
if (![self.arrayExtendedTitlesAtIndexPaths containsObject:indexPath]) {
[self.arrayExtendedTitlesAtIndexPaths addObject:indexPath];
}
else
{
[self.arrayExtendedTitlesAtIndexPaths removeObject:indexPath];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3304 次 |
| 最近记录: |