How to get row order info in multivalued section? - ios

I am using MultivaluedSection with an option .Reorder to reorder my cells, for which I need to know the exact order.
I tried with section.allRows, form.allRows, form.values() but seems like they all do not keep the information about order, even though they return an Array.
Note: I was trying to catch this data in overridden:
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)

Actually I realized that after overriding that method I was "killing" that update, of course.
Still, I don't know how to "catch" when a change happens.

Related

Reordering a UITableView: notification when user first starts dragging with the handles

I have a UITableView with cells that I want the user to be able to reorder by dragging them up & down, using the "handles" on the right side of each cell. I do NOT want to implement "drag & drop" functionality, because the data behind these cells makes no sense outside of this table (and implementing NSItemProvider looks to be an ugly process, given the data behind the table view & its cells). So far, everything is implemented & works fine. Looks somewhat like the results of this article.
The next step is, I'd like to know when the user has "lifted" or started to move a cell -- similar to the dragStateDidChange ability when one IS using drag & drop. I want to get this notification even before the cell has been moved out of its place -- as the UI turns the cell background white & "raises" it above the table.
How can I get this notification, without implementing "drag & drop"?
Things I've tried that don't accomplish what I want:
Recognizing a long-press gesture: I do use Gesture Recognizers on these cells for taps & such; it seems that when the user touches the drag handles to reorder the cells, this action does NOT fire a long-press Gesture. Tried that, no success.
Will-select-row-at: I implement the function func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? within the UITableViewDelegate code; it isn't called when the user touches the drag handles.
targetIndexPathForMoveFromRowAt: The func func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath fires when the dragged cell changes position, but not until then; it does NOT catch the start of the lift/drag process that I'm looking for.
Likewise, willBeginEditingRowAt and shouldHighlightRowAt aren't called either.
Various scrollView functions: they all get called when the user is scrolling the whole table, not when the user is reordering it.
Watching for "set editing": the drag handles need to always be present, so "editing" is always set to true.
Somewhat similar question, unfortunately without an answer that I can use (and also not in Swift).
I suspect that there must be a simple notification that the cell has been lifted and is being dragged using the handles, even if it hasn't been moved far enough to be above or below its old place yet. After all, the OS "knows" about this because it changes the background and adds shadows & so forth. Any help accessing that notification so that other code can respond to it as well would be most appreciated!
It's a little strange that these are not documented, but you can define the following functions in your UITableViewController (or in the UITableViewDelegate) which will be called when cell dragging starts or ends, respectively:
#objc func tableView(_ tableView: UITableView, willBeginReorderingRowAtIndexPath indexPath: IndexPath) {
// Dragging started
}
#objc func tableView(_ tableView: UITableView, didEndReorderingRowAtIndexPath indexPath: IndexPath) {
// Dragging ended
}

UITableViewCell content is sometimes overlapped by delete button (on swipe)

I've implemented swipe to delete in UITableView a lot of times before, but never faced this problem before. In my last app delete button sometimes (not always) doesn't shift cell's content, but just overlaps it. See attached screenshot.
I use standard iOS functionality for this:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
Probably, somebody already faced with this issue and know how to fix it?

Can't Swipe Due to editingStyleForRowAt

There seems to be an error that's impossible to avoid, but I'm hoping someone can do the impossible.
In a UITableView editMode there's a lefthand delete indicator (red circle with a white line):
I just want the drag / drop grip on the right, so I get rid of the indicator by calling:
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .none
}
However, it also seems pretty clear that if you want the ability to swipe for actions...
You CANNOT call the above "editingStyleForRowAt" method. So it seems like I'm forced to choose only one of the above features... oddly you can only return ".none", ".insert", or ".delete".
Anyone know of a solution?
In your case you should try with custom cell.
Please check below link.
I just assume, it is work for you, I am not sure.
https://www.cocoacontrols.com/controls/eecellswipegesturerecognizer

Naming Convention in tableView functions

So I am just getting into the whole tableView thing but I came across a curious observations and have a question:
Why is it that overriding this function in my UITableViewController class
override func numberOfSections(in tableView: UITableView) -> Int
has a descriptive name but the number of rows in the section is determined this way
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
I find the former much more logical and wonder why it is not used consequently for other tableView parameters.
Why are different versions of the function tableView called for most tableView properties, instead of different functions with descriptive names?
I am sure there is a very good reason and would be thankful if someone wiser than me could shed some light on the issue.
So to put it frankly: Compatibility with Objective-C seems to be the reason for this inconsistency.

cellForRowAtIndexPath is called but without stacktrace

Using Swift 3, the UITableView's func tableView(_ tableView: UITableView, cellForRowAt indexPath: #autoclosure #escaping IndexPath) -> UITableViewCell is being called. I want to track who's calling this function. As far as I know, this will only be called if there's a need for a cell to display. However, in stacktrace override internal func tableView(_ tableView: UITableView, numberOfRowsInSection section: #autoclosure #escaping Int) -> Int is not called and there is no stacktrace. Could someone advice to where to start digging up? Thanks!
See attached screenshot
By default, you only see the stack trace that contains debug symbols. So you won't see many framework internals here.
To see everything, there is a small button at the bottom of the stack trace window, third position from the right, that will enable also methods without debug symbols:
(In fact, it depends on your Xcode version; in older versions there is some sort of slider which will display more or less details in the stack trace).
As #AndreasOetjen mentioned, this is a normal behavior because the method get's called from a UIKit Framework class. The call-stack in this Framework is hidden by default and can be opt-io by the mentioned buttons.

Resources