I am trying to put an extendable UITableViewCell
by tapping on a button.
I am using the constraints to force the dynamic UITextView
to tell the UITableViewCell
the its new height. (using autolayout and UITableViewAutomaticDimension
)
This works as expected without the button: The height of the UITableViewCell
depends on the UITextView
's height.
Having a constraint on the UITextView
to maximize the size of the cell, when tapping the button (the cell is collapsed), I want to remove height constraint to the UITextView
(that is limiting the cell height) and update the cell accordingly. Here's the extend method:
-(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];
});
}
}
If I tap the button and then scroll to a similar cell, it is already expanded. So I am missing something here. I already tried to do [cell updateConstraints]
after deactivating the constraint, but it doesn't work.
UPDATE
At first, the button doesn't show up for some reason. And I noticed that (with the same code) if I scroll down and then up, the button shows up and, if I try to extend it, it works.
UPDATE
This is my UIViewController :
http://www.gfycat.com/FairBossyAfricanporcupine
Notice that the extend button is not there, but once I scroll down/up it comes shows up and it extends the cell once I tap on the extend button.
UPDATE
I noticed that when the textSize is being calculated (to see if the cell is extendable or not), at first, the textView is wider than its final state. And I am performing this check on the 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;
}
}
...
So on the first run (before scrolling) the [self isTitleExtendable:title forTextView:cell.textViewTitle]; does not return the desired value as the textView doesn't have the right width when the textSize is being calculated.
So I believe have the following options : - force the textViewTitle to refresh after it has changed the layout (thus calculating correctly the extendable UI state) - recheck the extendable UI state once the textViewTitle changes the width
UPDATE
On the method prepareForReuse the textViewTitle still has a wider frame. On the layoutSubviews method it has in fact a small frame. The challenge here is that is gets called more often, and it gets me false cases (button being shown when it shouldn't)
This is what I was experimenting with :
-(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);
}
To do such a thing, you shouldn't rely on constraint, but on tableView(_:heightForRowAtIndexPath:)
you just have to give the right height depending on the context.
Pushing your button would trigger a change so tableView(_:heightForRowAtIndexPath:)
returns a different value for your cell that you extend.
And just after doing this trigger, just do:
[self.tableView beginUpdates];
[self.tableView endUpdates];
without anything between them, it will trigger the "natural animation" of UITableView
and do exactly what you want
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With