UITableView reorder with tap within table - ios

A question for those who have used a UITableView in the past
I am currently using a UITableView in edit mode and I have the following data source / delegate methods implemented
(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
//which tells me where the cell has been moved to
(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
//which tells me where it may be moved
What I want to achieve:
when I pick a cell and reorder it, the cell should move up and down in the table view only while the finger is within the table view. Which means if I start from within the table view and move outside it, the cell should snap back in position and not let me reorder the cell.
The problem is that there is no way to find out (that I know of) where my finger is while the reorder is being performed. If I can find out where the finger is then it might be possible to achieve this.
Any ideas?

Take a look at the (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath function. HTH.

Related

iOS11 Drag behavior not working in UITableView

I am facing a problem while developing Drag&Drop iOS11 feature to allow send and receive data between apps.
In the tableView of a view controller, with it's dragDelegate and dropDelegate assigned on viewDidLoad to the view controller itself, I implement the
- (NSArray<UIDragItem *> *)tableView:(UITableView *)tableView itemsForBeginningDragSession:(id<UIDragSession>)session atIndexPath:(NSIndexPath *)indexPath method, but it is never being called.
The drop behavior is working correctly and the table view can consume items from other apps such Photos or Notes. But when I tap a table view row for a couple of seconds, nothing happens. The lift animation doesn't occur and the drag delegate isn't fired.
Any thoughts? Am I missing anything required?
On iPhone, besides setting the dragDelegate you must also set dragInteractionEnabled on the UITableView to true. On iPad, this property is set to true by default.
Please try below delegate methods for re-ordering of cell.
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleNone;
}
Implement the following UITableView datasource method in your project.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
[dataArray exchangeObjectAtIndex:sourceIndexPath.row withObjectAtIndex:destinationIndexPath.row];
[self.tableView reloadData];
}

How to Save UITableViewController cells after rearrange to NSUserDefaults

I've an iOS application developed using Objective-C & Xcode 6.4
Right know I'm working on manually rearranging the UITableViewController cells, everything working great. But after I press the bar button EDIT and the "3 underlines" appear to drag the cell anywhere I want in the UITableViewController, (( I can't save what I did )). So how could I do a Persistent save the changes done to the table cells location ?? I mean, How to save The new rearranged NSMutableArray to a Property list -NSUserDefaults-.
I'm using a Mutable Array to display the table's cells and these methods below:
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleNone;
}
-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
FileWML *fileWML = [self.filesWML objectAtIndex:sourceIndexPath.row];
[self.filesWML removeObjectAtIndex:sourceIndexPath.row];
[self.filesWML insertObject:fileWML atIndex:destinationIndexPath.row];
}
PLUS would someone tell me how I can make the edit button display the word Done, while editing ?
(( I can't save what I did )) means: after I do the rearranging order I want, and then I go to the home view then I get back to the table view I edit and rearrange, the rearranging order I did get back to the default order. So, all the rearranging I did is gone.
Thanks and every help is appreciated.
You have to load your datas from your file in an array. This array will be your tableView dataSource.
When a row is moved, in the delegate method you have to change the object's place in the array. Your array should always be the same as your tableview !
Once the editing of the tableview is done you save the array in the file. The previous content in file should be erased. Then you reload your datas ([tableView reloadData].

UITableView not detecting the the accurate tapped row

I have just added a UITableView in to my storyboard and the suggested constraints to it like that.. Now i have written very simple code with some delegate and datasource methods implemented like this. . Now when i tap the first row it detects nothing and check the console in the below image, when i press the second row it tells me that the indexPath.row is 0.. can some body point out that what i am doing wrong here.
You are calling -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath which is called when you deselect row , instead call
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
It's because you are using didDeSelectRowAtIndexPath: instead of didSelectRowAtIndexPath: method.
You have to call "didSelectRowAtIndexPath" Delegate method.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
This method only return which row we have selected.

How to add submenu's in table view in ios

i don no whether this question asked or not but i still searching for an answer.Am working in tableview concept and i am creating a table view like with some set of menu's like inbox, sent,setting etc.Now what i want is i want to create sub menu's inside every menu, for example if i click inbox it should show new,replied,deleted etc like this for every main menu i want to create sub menu. Using array we can load by checking section but with out using array i want to create directly and notable one i have used custom cell i also want to show images as per the menu if it is inbox i have to show inbox image. Could any one help me??
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 8;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 8;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellidentifier=#"ViewProfileCell";
MyHomeViewCell *cell= [[MyHomeViewCell alloc] init];
cell=(MyHomeViewCell*)[tableView dequeueReusableCellWithIdentifier:cellidentifier];
if(!cell)
{
NSArray *nibofMyHomeCell=[[NSBundle mainBundle]loadNibNamed:#"MyHomeViewCell" owner:self options:Nil];
cell=[nibofMyHomeCell objectAtIndex:0];
}
if(indexPath.section==0)
{
cell.MyHomeMenuLabel.text=#"Inbox";
}
}
Here ara a good tuts it could help you:
Expanding/Collapsing TableView Sections
Expandable UITableView
And this github awesome code here by Oliver Letterer.
You can create a UITableview which will contain cells on it as you said inbox, sent, setting etc.
After you need to create another UITableView which will contain your submenu buttons or labels like new,replied, deleted when click on inbox.
Simillarly you will do for rest of the cells in your main UITableView.
And don't get confuse on how will i identify which tableview will get called.
You will check for tableview name like below:
if(tableView==main)
{
///Code for main menu tableview.
}
else if(tableView==sub)
{
////Code for submenu tableview.
}
This you will do in all UITableView Delegate and Datasource methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
There are many ways you can do this. You could for example show each item as a section header and if the section header is tapped you show (or hide) all of the rows in that section. The rows being the 'sub menu' items (new, replied, deleted). Or you could use different sections for each part and how or hide the sections. Or show and hide rows. This is pretty much all controlled by changing the section and row counts.

Reorder/move UITableViewCell but moves back

I want to implement a method to be able to reorder the rows of a tableview.
In each section i only have one row. When the editing-state of the tableview is enabled, the move indicators appear as expacted. But when i drag one of the cell to another position, the cell immediatly (after approximatly 1 s) pops back to the original position. This is weired to me, because i implemented such a reorder functionality already. The difference between those two projects are that the new project implements a bunch of gesture recognizers (eg UILongPressGestureRecognizer, UIPanGestureRecognizer, UIPinchGestureRecognizer,..). I already thought about the possibility that one of the gesture recognizers is blocking the drag action of the tableviewcell but its not.
You can see the code below:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {
//return [NSIndexPath indexPathForRow:0 inSection:3];
return nil;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
NSLog(#"%#", destinationIndexPath);
}
Can anyone help me pls?
UPDATE:
I found out that the moved tableviewcell is beeing moved to the original destination index path. Does that indicate, that a reloadData on the table view has happened?
2nd UPDATE:
Because it was menthioned by Andrei Shender why i return nil in the tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath: method you can find my updated code below.
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {
return proposedDestinationIndexPath;
//for testing purpose only
//return nil;
}
Btw when changing my code, i found out, that this method never gets called. Regarding to Apples documents about reordering tableviewcells it should get called.
Thanks to this posting I figured out, what the problem was. Combining a UIPanGestureRecognizer and a UITableView with the reorder/move funcationality is a tricky thing.
When i edit the tableview, i remove the gesture recognizer (of the viewcontroller's view) and when the editing is disabled again, i add the gesture recognizer again.
Be sure to update your data source in the method :
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath

Resources