0

In a tableview’s section. I have some selectable rows. Inside the section’s header I have a Deselect All button.

The deselect all button needs to get enabled if a row is selected and disabled if no row is selected. The button is enabled/disabled by reading a boolean value. I have a didSet on that boolean:

var shouldEnableDeselectButton = false
    {
        didSet{
            if oldValue != shouldEnableDeselectButton{
                DispatchQueue.main.async {
                    self.notesTable.reloadSections([self.indexofFilter], with: .none)
                }
            }
        }
    }
  • If I do absolutely nothing in the didSet then it only gets updated by being dequeued/scrolling up or down and getting off the screen. See below:

enter image description here

  • If I do self.notesTable.reloadSections([someSection], with: .none) then it longer requires the section header to get dequeued. Yet if I select one of the last rows, then it jitters badly: See below:

enter image description here

I looked online and found solutions mentioned Reload tableview section without scroll or animation but they both still jitter

mfaani
  • 33,269
  • 19
  • 164
  • 293
  • why did you add this `DispatchQueue.main.async`? Do you refresh it from background thread? – Mani Apr 20 '18 at 13:52
  • No good reason. It was just a futile attemp at resolving this – mfaani Apr 20 '18 at 14:05
  • Why do you need reload table section, on checking/unchecking? And why don't you call just reloadData() ? It cause reload just visible rows, so it is very quick and without animations. – Lukáš Mareda Apr 20 '18 at 14:11
  • 1
    So you are doing `self.notesTable.reloadSections` just so that Deselect all button gets enabled/disabled? What I would do is hold a strong reference to the header section view where I could just set a property on that view to enabled/disabled without the need to refresh the whole section... – Ladislav Apr 20 '18 at 14:24
  • @Ladislav Thanks. so changing a property of that view, would just change it? I mean it won't need any `layoutIfNeeded()` or any form of `reload()`? And if I may ask you've done this before or you just think it should work? – mfaani Apr 20 '18 at 14:37
  • @LukášMareda still jitters that way – mfaani Apr 20 '18 at 14:37
  • @Honey If this is a regular `UITableView` and you hold a strong reference to the header view then when you change button.isEnabled property it will be changed if it is on screen and change will be visible if it was off screen and later comes on screen. I would make sure that for the header I have strong reference to I don't use the dequeueing methods... – Ladislav Apr 20 '18 at 14:43
  • It will be good to post your cellForRow and maybe headerForSection if it exists. This can be caused by multiple calls of reloadSection and with changing data source. Also at the end of the second animation, you tap(click) on row with number 11 and it scrolls, or it removes something from table view? And if the "de/select All"button is in header view, how it is possible that is scrolling with table View? Header View should stay at top edge until the next section come during scrolling. – Lukáš Mareda Apr 20 '18 at 14:52
  • @LukášMareda I don't have multiple calls. I validated it by placing a breakpoint on every reload of the table. FWIW upon clicking I first reload the cell (to change the checkbox) and then reload the section(to enable/disable the deselect button) without animation. But to have only 1 reload and disabled the checkbox reloading (I still updated the datasource), and upon emptying the selections or selecting the first item I reload the section. It still jitters. It still jitters when it's the only reload. – mfaani Apr 20 '18 at 20:10
  • @LukášMareda _Also at the end of the second animation, you tap(click) on row with number 11 and it scrolls, or it removes something from table view_ . I remove nothing. I only enable/disable the button. – mfaani Apr 20 '18 at 20:14
  • In your animation, as soon as you tap on 11 then you reloadSection and it scrolls itself? And do you know how is possible why the tableView Header with deselect button scrolling with table? It should stay pinned at top edge - it is standard tableView behaviour. – Lukáš Mareda Apr 23 '18 at 10:09

1 Answers1

0

2 things were needed:

  1. Get a reference/pointer to the headerView. E.g. this answer.

  2. Have your button as a property. I was originally having it just as a subview. That wasn't enough! To do such I made my sectionHeader a UITableViewHeaderFooterView subclass and then added the button as a property.

Then I was simply able to change the isEnabled property of the button.

mfaani
  • 33,269
  • 19
  • 164
  • 293