100

I have a UITableView that is using a custom table cell and each cell has a UIWebView.

Because UIWebView took along time to load, i want to avoid reloading them at all cost. In some situations, I have all cells loaded, but their heights are messed up. Therefore, I need to "relayout" the table without triggering the "cellForRow" function.

  1. I definitely cannot use reloadData... as it will reload the cells again.
  2. I tried tableView.setNeedDisplay, setNeedsLayout etc, none of them is able to rearrange the table cells
  3. The only way it worked, is to call beginupdates/endupdates block, this block is able to relayout my table without firing cellForRow! BUT, I didnt want the animation! This block produces an animation effect but i do not want it...

How can I solve my problem?

9 Answers 9

223
[UIView setAnimationsEnabled:NO];
[tableView beginUpdates];
[tableView endUpdates];
[UIView setAnimationsEnabled:YES];
1
  • 1
    This is great! I find it has some most interesting applications. I found that reload sections method will always animate even if you pass in UITableViewRowAnimationNone, but with this the animation can be easily bypassed! Commented Apr 21, 2015 at 15:11
83

One more way to do it using blocks

Obj-C

[UIView performWithoutAnimation:^{
   [self.tableView beginUpdates];
   [self.tableView endUpdates];
}];

Swift

UIView.performWithoutAnimation {
    tableView.beginUpdates()
    tableView.endUpdates()   
}
5

Swifties I had to do the following for this to work:

// Sadly, this is not as simple as calling:
//      UIView.setAnimationsEnabled(false)
//      self.tableView.beginUpdates()
//      self.tableView.endUpdates()
//      UIView.setAnimationsEnabled(true)

// We need to disable the animations.
UIView.setAnimationsEnabled(false)
CATransaction.begin()

// And we also need to set the completion block,
CATransaction.setCompletionBlock { () -> Void in
    // of the animation.
    UIView.setAnimationsEnabled(true)
}

// Call the stuff we need to.
self.tableView.beginUpdates()
self.tableView.endUpdates()

// Commit the animation.
CATransaction.commit()
5
  • Helped me. Thanks. Important to put setAnimationsEnabled(true) inside the completion block. Commented May 25, 2016 at 15:02
  • But this does not update Footer until you scroll the tableview. Commented Nov 30, 2017 at 5:46
  • @Mr.Bean what's the full case? (i.e. does your tableview always have a footer, are you trying to insert one or remove one?) Commented Dec 4, 2017 at 11:25
  • Always have a Footer, just need to update the footer (i.e. There are 2 views inside the footer, need to hide/unhide the views depending on the condition.) Commented Dec 4, 2017 at 15:24
  • @Mr.Bean what does your update block contain? The most extendable method here would be to reload the section. Commented Dec 4, 2017 at 18:07
5

working on my project, but not a common solution.

let loc = tableView.contentOffset
UIView.performWithoutAnimation {

    tableView.reloadData()

    tableView.layoutIfNeeded()
    tableView.beginUpdates()
    tableView.endUpdates()

    tableView.layer.removeAllAnimations()
}
tableView.setContentOffset(loc, animated: true)//animation true may perform better
2

iOS disable animations in UITableView

From iOS v11 you should use the performBatchUpdates method instead of beginUpdates/endUpdates

UIView.performWithoutAnimation {
    self.tableView.performBatchUpdates {
        //table view updates
    }
}
1

I prefer to have a smooth transition:

CGPoint offset = self.tableView.contentOffset;
[UIView transitionWithView:self.tableView duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
        [self.tableView reloadData];
        self.tableView.contentOffset = offset;
    } completion:nil];

give it a try.

0

I wanted to updated the cell height for section 5 and following code worked for me:

UiView.setAnimationsEnabled(False)
self.productTableView.reloadSections(NSIndexSet(index: SectionType.ProductDescription.hashValue), withRowAnimation: UITableViewRowAnimation.None)
self.productTableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 5), atScrollPosition: UITableViewScrollPosition.Bottom, animated: false)
UIView.setAnimationsEnabled(true)
0

for OBJ-C

[UIView setAnimationsEnabled:NO];
[tableView beginUpdates];
[tableView endUpdates];
[UIView setAnimationsEnabled:YES];

for swift

UIView.setAnimationsEnabled(false)
tableView.beginUpdates()
tableView.endUpdates()
UIView.setAnimationsEnabled(true)
-1

In my case worked this:

func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
    tableView.beginUpdates()
    tableView.endUpdates()
    return true
}

func textViewDidChange(_ textView: UITextView) {
    DispatchQueue.main.async {
        self.tableView.beginUpdates()
        self.tableView.endUpdates()
    }
}

Your Answer

By clicking โ€œPost Your Answerโ€, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.