I have a UITableView with prototype cells. If you swipe any cell to their left, two options are displayed on the cell correctly. This has been done with
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]?
Now, I want to also allow users to delete a cell. I understand the best way would be to make a complete on a cell swipe in order to remove it. This means, if there swipe is not complete, options will be displayed (as it is done now), but if the swipe is complete, the cell would be removed.
What code should I add to keep the actual behavior, but also enable to remove a cell by swiping it completely?
This repo has what you want. Have a look.
https://github.com/MortimerGoro/MGSwipeTableCell
Related
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
}
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?
I use for my app UITableview and I got a problem.
Method tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) called only by sliding finger from left to right or from right to left the item. But when I do normal click by this item, this method doesn't called
What is supposed to do the cell when you click on it?. As a first impression, the line tableView.deselectRowAtIndexPath(indexPath, animated: false) is not animating the select of the cell, and that can cause the impression that nothing is happening.
Second, the implementation of the cellForRowAtIndexPath: and didSelectRowAtIndexPath: methods look almost the same. I mean, in both methods your are getting the same data from the categories array and not changing anything, at least that's what I can see with the code you provided.
Third, may the implementation of the code inside your subclass, to which item belongs to in let item = categories[indexPath.row], be wrong.
Fourth, why your code have semicolons?.
You can review all of these to start discarding.
I've been searching a lot, but I don't find a clear way to create an Scroll to top load more, or infinite scroll, just like you see on chats, e.g whatsapp.
I was trying using scrollViewDidScroll method, load data again based on current page
if self.tableView.contentOffset.y == 0 {
loadData(++currentPage, itemsPerPage: pageSize)
}
But the way to handle new data and scroll position it's a little weird for me, so the main problem is adding content in an efficient way, at the top of my UITableView
//Update
In ScrollViewDidScroll method:
After contentOffset.y reaches 0 position, I'm trying to prepend new messages, since it must appear at top of UITableView, so inserting messages at index 0 is the only way I find to do this. But there is one thing, after pulling new data, and reloading UITableView, scroll position remains displaying at visible screen, last pulled message on top. This is not the expected behaviour, look this slack channel pic
when scroll reached proper offset, new data was pulled, and screen it's on the same message, but looks now the scroll position
so, I think reloading entire table view in this case is the problem, but how could you pull the data in the tableView properly to get this expected scroll behaviour?
e.g in whatsapp it's the same
I recommend make prefetching in UITableView delegate's method
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
//your code ()
if indexPath.row == datasource.count - 3 {
loadMore()
}
}
This allows you to avoid weird behaviour of scroll view.
I have one UITableView, two arrays and segmented control. When segmented control index is "1", UITableView display data from first array, when index is "2" - second array. I want to swipe to delete function only in second segment. How can I do that? I am thinking of some "if statements" in
tableView(tableView: UITableView, commitEditingStyle editingStyle:
UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
but i don't know where to put them.
If you use commitEditingstyle, then your cells will still display the Delete button when you swipe. Use editingStyleForRowAtIndexPath: instead. Put an if statement in to test which segment is selected, and return UITableViewCellEditingStyle.None (to disable swipe to delete) or .Delete (to enable swipe to delete) accordingly. If you want to be able to delete the cells by putting the table view into editing mode, then also test tableView.editing to determine whether to use .Delete or .None.