ExpyTableView
ExpyTableView copied to clipboard
Support UITableView moveSection:toSection:
Visible sections is not updated when using moveSection:toSection:. So, if you try to move a section that is expanded to a location of a section that is not expanded, it will crash. I wrote an override for moveSection:toSection which works, but only for single moves. It will not work when moving multiple sections using performBatchUpdates:completion: or beginUpdates() and endUpdates().
override open func moveSection(_ section: Int, toSection newSection: Int) {
let sectionIsVisible = visibleSections[section] ?? false
visibleSections.removeValue(forKey: section)
if (newSection < section) {
for i in stride(from:section - 1, through:newSection, by:-1){
visibleSections[i+1] = visibleSections[i] ?? false
}
}else if (section < newSection){
for i in stride(from:section + 1, through:newSection, by:1){
visibleSections[i-1] = visibleSections[i] ?? false
}
}
visibleSections[newSection] = sectionIsVisible
super.moveSection(section, toSection: newSection)
}
Sorry for the late answer. What is the crash please? @rholstad
The crash is the dreaded UITableView Invalid update. Here is the stack trace:
ExpyTableView_Example[1501:53913] *** Assertion failure in -[ExpyTableView.ExpyTableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3698.33.6/UITableView.m:2011
2018-02-06 13:02:19.171764-0500 ExpyTableView_Example[1501:53913] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (4) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
*** First throw call stack:
(
0 CoreFoundation 0x0000000109cc712b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x0000000109363f41 objc_exception_throw + 48
2 CoreFoundation 0x0000000109ccc2f2 +[NSException raise:format:arguments:] + 98
3 Foundation 0x0000000108e04d69 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193
4 UIKit 0x000000010a97c209 -[UITableView _endCellAnimationsWithContext:] + 19416
5 UIKit 0x000000010a997f98 -[UITableView _moveSection:toSection:usingPresentationValues:] + 381
6 UIKit 0x000000010a99802d -[UITableView moveSection:toSection:] + 107
7 ExpyTableView_Example 0x000000010865a6cb _T021ExpyTableView_Example05BasicdC10ControllerC13buttonPressedySo8UIButtonCF + 155
8 ExpyTableView_Example 0x000000010865a72c _T021ExpyTableView_Example05BasicdC10ControllerC13buttonPressedySo8UIButtonCFTo + 60
9 UIKit 0x000000010a859972 -[UIApplication sendAction:to:from:forEvent:] + 83
10 UIKit 0x000000010a9d8c3c -[UIControl sendAction:to:forEvent:] + 67
11 UIKit 0x000000010a9d8f59 -[UIControl _sendActionsForEvents:withEvent:] + 450
12 UIKit 0x000000010a9d7e86 -[UIControl touchesEnded:withEvent:] + 618
13 UIKit 0x000000010a8cf807 -[UIWindow _sendTouchesForEvent:] + 2807
14 UIKit 0x000000010a8d0f2a -[UIWindow sendEvent:] + 4124
15 UIKit 0x000000010a874365 -[UIApplication sendEvent:] + 352
16 UIKit 0x000000010b1c0a1d __dispatchPreprocessedEventFromEventQueue + 2809
17 UIKit 0x000000010b1c3672 __handleEventQueueInternal + 5957
18 CoreFoundation 0x0000000109c6a101 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
19 CoreFoundation 0x0000000109d09f71 __CFRunLoopDoSource0 + 81
20 CoreFoundation 0x0000000109c4ea19 __CFRunLoopDoSources0 + 185
21 CoreFoundation 0x0000000109c4dfff __CFRunLoopRun + 1279
22 CoreFoundation 0x0000000109c4d889 CFRunLoopRunSpecific + 409
23 GraphicsServices 0x0000000110bbe9c6 GSEventRunModal + 62
24 UIKit 0x000000010a8585d6 UIApplicationMain + 159
25 ExpyTableView_Example 0x000000010865fed7 main + 55
26 libdyld.dylib 0x000000010e8a5d81 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
I reproduced in the provided sample application by adding a button on top of the Basic Example View Controller
that would move section 2 to the top.
@IBAction func buttonPressed(_ sender: UIButton) {
expandableTableView .moveSection(2, toSection: 0)
}
If all sections from 0 to 2 are not expanded, there are no problems. If all sections from 0 to 2 are expanded, there are no problems. But any other combination of section expansion from 0 to 2 exists, it crashes. Since visibleSections
is handled internally by ExpyTableView
, it would be helpful if it would manage the data source rearrangement that is necessary to make the move work.
Thanks! Will look into this soon.