Currently I have a UITableView
with a resizing UITextView
in it. The cell is resizing automatically using beginUpdates
/endUpdates
, but when it does it the table view stutters (See the gif below).
The end result is a UITableViewCell
that has a textview in it that resizes based on it's content. Here is the code within the custom UITableViewCell
class that causes the UITableView
to update itself.
- (void)textViewDidChange:(UITextView *)textView {
// This is a category on UITableViewCell to get the [self superView] as the UITableView
UITableView *tableView = [self tableView];
if (tableView){
[tableView beginUpdates];
[tableView endUpdates];
}
}
Here are the things that I have already tried:
Get the current contentOffset
and resetting it after the endUpdates
but didn't work
Disabling scrolling on the UITableView
before updates and then enabling afterwards
I tried returning NO
always from - (BOOL)textViewShouldEndEditing:(UITextView *)textView
My UITableView
cell height is using UITableViewAutomaticDimension
. Any other ideas or thoughts are welcome.
Here is a sample of what it looks like:
I am not looking to use any libraries so please no suggestions for that.
Thanks
Edit: Solution
Found Here: I do not want animation in the begin updates, end updates block for uitableview?
Credit to @JeffBowen for a great find (although hacky it is workable and allows me to still implement the UITableViewDelegate
methods for supporting iOS 7). Turn animations off prior to performing update and then enable after update to prevent the UITableView
from stuttering.
[UIView setAnimationsEnabled:NO];
[tableView beginUpdates];
[tableView endUpdates];
[UIView setAnimationsEnabled:YES];
If you don't need to use the Delegate methods and want a less hacky solution for iOS 8+ only then go with @Massmaker's answer below.
Just disable animation before calling beginUpdates
and re-enable it after calling endUpdates
.
[UIView setAnimationsEnabled:NO];
[tableView beginUpdates];
[tableView endUpdates];
[UIView setAnimationsEnabled:YES];
Definitely a hack but works for now. Credit to my friend Beau who pointed me to this.
My solution (for iOS 8) was first set in my viewController viewDidLoad
self.tableView.rowHeight = UITableViewAutomaticDimension;
// this line is needed to cell`s textview change cause resize the tableview`s cell
self.tableView.estimatedRowHeight = 50.0;
then, combining this article solution in Swift and some dirty thoughts I`ve set in my cell a property, called
@property (nonatomic, strong) UITableView *hostTableView;
and in cell-s -(void) textViewDidChange:(UITextView *)textView
CGFloat currentTextViewHeight = _textContainer.bounds.size.height;
CGFloat toConstant = ceilf([_textContainer sizeThatFits:CGSizeMake(_textContainer.frame.size.width, FLT_MAX)].height);
if (toConstant > currentTextViewHeight)
{
[_hostTableView beginUpdates];
[_hostTableView endUpdates];
}
then in viewController
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
textCell.hostTableView = self.tableView;
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