how to begin moving cell with long press gesture? - iphone

I have a UITableView with several UITableViewCells in it. I'd like to long press on a cell to begin move it and keep holding on it and drag to move it. But i don't know how.
I added a long press gesture on table view, when user long pressed , set tableview's editing to YES:
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleTableViewLongPress:)];
[_tableView addGestureRecognizer:longPressRecognizer];
- (void)handleTableViewLongPress:(UILongPressGestureRecognizer *)gesture
{
if (gesture.state != UIGestureRecognizerStateBegan)
return;
[_tableView setEditing:YES];
}
And the tableview could move cell with two methods:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
//update datasource
}
But with these code user must use two touch to move a cell: one is to set the tableview to editing state, another is to move cell. What i want is to allow user use one touch to do this.
Any suggestions? thanks!

I have found this UITableView subclass: Move table view

Related

iPhone:How to change default delete button's frame in UITableViewCell

I have facing problem is that Is there any way to change default frame
of delete button in UITableView and one more thing is that delete button is always display in center of cell of UITableViewcell so any way to change frame of delete button.
// Update the data model according to edit actions delete or insert.
- (void)tableView:(UITableView *)aTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[appDelegate.categories removeObjectAtIndex:indexPath.row];
[categoryTableView reloadData];
}
}
#pragma mark Row reordering
// Determine whether a given row is eligible for reordering or not.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
// Process the row move. This means updating the data model to correct the item indices.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath
toIndexPath:(NSIndexPath *)toIndexPath
{
NSString *item = [[appDelegate.categories objectAtIndex:fromIndexPath.row] retain];
[appDelegate.categories removeObject:item];
[appDelegate.categories insertObject:item atIndex:toIndexPath.row];
[item release];
}
Thanks in advance.
in ios 6.1 i was not able to use the above code. I've seen several answers that suggests subclassing the cell class and providing a custom -willTransitionToState. Changing the subview/buttonview frame does not affectively change it's displayed position.
However if you override the layoutSubviews method it will work. Here is the code:
//below i moved the delete button to the left by 10 points. This is because my custom tableview has lef
- (void)layoutSubviews
{
[super layoutSubviews];
for(UIView *subview in self.subviews)
{
if([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"])
{
CGPoint o = subview.center;
subview.center = CGPointMake(o.x - 10, o.y);
}
}
}
You can use your own view by setting the cell's editingAccessoryView property. This can have whatever frame you like, though you'll need to supply a gradient if you want it to look like the standard delete button.
In the xib file of your custom cell, add a new button of whatever size you like (as long as it is smaller than the cell!). This button should not be a subview of your cell, but a separate item in the file.
Connect this button to the editingAccessoryView outlet of your cell and it will replace the standard delete button.

How get rid of reorderControl while still using reorder?

Not long ago I asked about how to move reorderControl view close to the center of my custom cell, so this reorderControl break custom design. As I can't move this view and my cell always in editing mode - I just draw this reorderControl in right place of my cell background. But now I have two reorderControls ) one from my background in right place and one from iOS. If I set return value of - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath to NO, iOS reorderControl disappear but I can't reorder rows anymore.
How can I remove iOS reorderControl from screen and still be able to reorder my custom UITableViewCell?
ps cell.showsReorderControl=NO; is not working
It's kind of a hack but the following does work
for(UIView* view in self.subviews)
{
if([[[view class] description] isEqualToString:#"UITableViewCellReorderControl"])
{
for(UIImageView* cellGrip in view.subviews)
{
if([cellGrip isKindOfClass:[UIImageView class]])
[cellGrip setImage:nil];
}
}
}
The solution I got it work in iOS7 is to add another method to find reorder control. Since the tableview structure has changed in iOS7 It was a little bit hard to track UITableViewCellReorderControl. It is now in UITableViewCellScrollView.
The solution is like below
- (void)changeReorderControl:(UITableViewCell *)cell subviewCell:(UIView *)subviewCell
{
if([[[subviewCell class] description] isEqualToString:#"UITableViewCellReorderControl"]) {
[subviewCell.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
UIImageView *imageView= [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"hand"]];
imageView.center = CGPointMake(subviewCell.frame.size.width/2 , subviewCell.frame.size.height/2);
[subviewCell addSubview:imageView];
}
}
- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
for(UIView* subviewCell in cell.subviews)
{
if([[[subviewCell class] description] isEqualToString:#"UITableViewCellScrollView"]) {
for(UIView* subSubviewCell in subviewCell.subviews) {
[self changeReorderControl:cell subviewCell:subSubviewCell];
}
}
}
}
Hope you will get the idea.

Edit & delete multiple rows in UITableView simultaneously

In my app I need to delete multiple rows in a table, edit the table and get a check box beside the table. When checked then the table cells are deleted. It is like the iPhone message app. How can I do this, please help me.
If I understand your question correctly, you essentially want to mark UITableViewCells in some way (a checkmark); then, when the user taps a master "Delete" button, all marked UITableViewCells are deleted from the UITableView along with their corresponding data source objects.
To implement the checkmark portion, you might consider toggling between UITableViewCellAccessoryCheckmark and UITableViewCellAccessoryNone for the UITableViewCell's accessory property. Handle touches in the following UITableViewController delegate method:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *c = [tableView cellForRowAtIndexPath:indexPath];
if (c.accessoryType == UITableViewCellAccessoryCheckmark) {
[c setAccessoryType:UITableViewCellAccessoryNone];
}
//else do the opposite
}
You might also look at this post regarding custom UITableViewCells if you're wanting a more complex checkmark.
You can set up a master "Delete" button two ways:
The IB approach
The programmatic approach
In either case, eventually a method must be called when the master "Delete" button is pressed. That method just needs to loop through the UITableViewCells in the UITableView and determined which ones are marked. If marked, delete them. Assuming just one section:
NSMutableArray *cellIndicesToBeDeleted = [[NSMutableArray alloc] init];
for (int i = 0; i < [tableView numberOfRowsInSection:0]; i++) {
NSIndexPath *p = [NSIndexPath indexPathWithIndex:i];
if ([[tableView cellForRowAtIndexPath:p] accessoryType] ==
UITableViewCellAccessoryCheckmark) {
[cellIndicesToBeDeleted addObject:p];
/*
perform deletion on data source
object here with i as the index
for whatever array-like structure
you're using to house the data
objects behind your UITableViewCells
*/
}
}
[tableView deleteRowsAtIndexPaths:cellIndicesToBeDeleted
withRowAnimation:UITableViewRowAnimationLeft];
[cellIndicesToBeDeleted release];
Assuming by "edit" you mean "delete a single UITableViewCell" or "move a single UITableViewCell," you can implement the following methods in the UITableViewController:
- (void)viewDidLoad {
[super viewDidLoad];
// This line gives you the Edit button that automatically comes with a UITableView
// You'll need to make sure you are showing the UINavigationBar for this button to appear
// Of course, you could use other buttons/#selectors to handle this too
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//perform similar delete action as above but for one cell
}
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
//handle movement of UITableViewCells here
//UITableView cells don't just swap places; one moves directly to an index, others shift by 1 position.
}
You can put 1 UIButton lets call it "EDIT" and wire up it to IBAction. In IBAction write so you will be able to do as per your requirement.
-(IBAction)editTableForDeletingRow
{
[yourUITableViewNmae setEditing:editing animated:YES];
}
This will add round red buttons on the left hand corner and you can click on that Delete button will appear click on that and row will be deleted.
You can implement delegate method of UITableView as following.
-(UITableViewCellEditingStyle)tableView: (UITableView *)tableView editingStyleForRowAtIndexPath: (NSIndexPath *)indexPath
{
//Do needed stuff here. Like removing values from stored NSMutableArray or UITableView datasource
}
Hope it helps.
you want to be looking for deleteRowsAtIndexPath, with all your code squeezed between [yourTable beginUpdates] & [yourTable endUpdates];

how to detect touch event in table cells for iphone

how to detect touch event for table cells
i tried this
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//<my stuff>
[super touchesBegan:touches withEvent:event];
}
but its not working actuallly i have aUIimage view in table cell and i want to chnage imgae based on tap so my touch event is not working for that cell
If you want to detect a touch on the UITableViewCell you don't really need to detect touch events. In your UITableViewController subclass, you need to implement the following delegate method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
Then you modify the image of the table cell for the selected index path.
You probably need to set myImageView.userInteractionEnabled = YES;.
In one of my projects I needed any tap on the tableView to dismiss the keyboard so the underlying tableView would show. Since a UITableView is really a UIScrollView, it will respond to the scrollView delegate methods. Using these 2 methods will dismiss if either the user taps on a cell or scrolls the tableView at all:
IMPORTANT: Make sure you implement the UIScrollViewDelegate in your .h file as well as the UITableViewDelegate and UITableViewDataSourceDelegate!!!
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//remove keyboard if table row is clicked
if ([self.firstName isFirstResponder] || [self.lastName isFirstResponder]) {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
[self.firstName resignFirstResponder];
[self.lastName resignFirstResponder];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
//remove keyboard if table scrolls
if ([self.firstName isFirstResponder] || [self.lastName isFirstResponder]) {
[self.firstName resignFirstResponder];
[self.lastName resignFirstResponder];
}
}

Table View scroll when text field begin editing iphone

I have table view controller in iphone application. Table view has two sections. First section has two rows and second section has one row. Second section has a custom table view cell.
Second section has a textfield which hides when text field begin editing and keyboard pops up. I want this table view to scroll when keyboard pops up.
I tried the following code which I came across on different websites but in vain.
Thanks in advance.
-(void) textFieldDidBeginEditing:(UITextField *)textField {
CGRect textFieldRect = [textField frame];
[self.tableView scrollRectToVisible:textFieldRect animated:YES];
}
atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
-(void) textFieldDidBeginEditing:(UITextField *)textField {
UITableViewCell *cell = (UITableViewCell*) [[textField superview] superview];
[self.tableView scrollToRowAtIndexPath:[tableView indexPathForCell:cell]
atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
I have run into this on Static Cell TVC's. There is an issue when overriding viewWillAppear and NOT calling its Super. So if you are doing that, make sure to call
[super viewWillAppear:animated];
at the top of viewWillAppear
You want to use the setContentOffset method of the table view. Determine the magnitude of the vertical scroll (in pixels), and then:
CGFloat verticalScroll = ... your code here ...
[self.tableView setContentOffset:CGPointMake(0, verticalScroll) animated:YES];
My problem was I was adding the table cell containing the UITextField in the
- (UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
function. If you do this the automatic UITableView scrolling doesn't work.
So, you have to do some arithmetic to work out when your last row is showing and put your special UITableViewCell in here along with all the others.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {