Swipable Cell in static UITableView - ios

I have a static UITableView (created in storyboard) with a fix amount of sections and cells. Now, I'd like to make one specific cell swipable. I don't want to delete the row, I just want to display a print button where normally is the delete button when swiping a cell in a non-static UITableView .
How do I make exactly one cell in my static UITableView swipable?

U can add UISwipeGestureRecognizer on top the cell:
//The setup code (in viewDidLoad in your view controller)
UISwipeGestureRecognizer *swipeGesture =
[[UISwipeGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[cell addGestureRecognizer:swipeGesture];
//The event handling method
- (void)handleSingleTap:(UISwipeGestureRecognizer *)recognizer {
CGPoint location = [recognizer locationInView:[recognizer.view superview]];
//Do stuff here...
}

Related

didSelectItemAtIndexPath of UICollectionView not getting called when its in uiscrollview

I have taken the UIScrollView inside that
i have taken one UIView with fixed
position and just below it taken UICollectionView which is horizontal scrolling,
then i have again UIView and then again i have taken
UICollectionView with fixed cell 1.
So, on select of item of both collection view's didSelectItemAtIndexPath method not getting called.I have found some solution here but not found exact one.
By using above solution, i am facing problem is on tap anywhere(ex. image gallary) tap of UIScrollview call the tap method but every time didSelectItemAtIndexPath called wheather i click on collection view or not default zero indexpath is called.
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(gestureAction:)];
[recognizer setNumberOfTapsRequired:1];
self.scrollViu.userInteractionEnabled = YES;
[self.scrollViu addGestureRecognizer:recognizer];
-(void)gestureAction:(UITapGestureRecognizer *) sender
{
CGPoint touchLocation = [sender locationOfTouch:0 inView:self.YourCollectionViewName];
NSIndexPath *indexPath = [self.YourCollectionViewName indexPathForRowAtPoint:touchLocation];
NSLog(#"%d", indexPath.item);
}

UICollectionView Swipe

I want to detect when a user swipes left or right in a collectionView in which one cell occupies the entire screen width. Is it possible to do without adding gesture recognizer. I have tried adding gesture recogniser, but it only works when we set scrollEnabled property of collectionView to NO.
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(didSwipeRight:)];
swipeRight.delegate = self;
swipeRight.numberOfTouchesRequired = 1;
[swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(didSwipeLeft:)];
swipeLeft.delegate = self;
swipeLeft.numberOfTouchesRequired = 1;
[swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
[self.collectionView addGestureRecognizer:swipeLeft];
[self.collectionView addGestureRecognizer:swipeRight];
Maybe you have disabled userInteraction. Did you check it? And define gestures as property to the class.
self.collectionView.setUserInteractionEnabled=true;
Try to override scrollViewWillEndDragging:scrollView withVelocity:velocity targetContentOffset:targetContentOffset, since the collection view inherits from a scroll view. This way you should be able to evaluate the velocity parameter to determine the direction. Therefore you'll want to implement the UIScrollViewDelegate protocol.
I add swipe gesture to collectionView.
And it work fine.
So like Stephen Johnson said.
I guess your cell have a scrollView.
So It block gestures.
I am not sure I fully understand the context of your problem. I see that you have a collection view within a collection view. I am going to assume that the outer collection view scrolls vertical and the inner one scrolls horizontal. You will want to set up a fail dependency between the gesture recognizers for both collections.
//Data source for your outer collection view
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
...
UICollectionView* innerCollectionView = ...;
[collectionView. panGestureRecognizer requireGestureRecognizerToFail:innerCollectionView. panGestureRecognizer];
...
}
If there is more going on than this with nested collection views can you give some more details?

Change values of UITableViewCell on tap

I need to change the value inside a UITableViewCell when the user taps on it.
I need to modify the value trough an animation of a value inside a UITableViewCell.
Right now, I've implemented a UITapGestureRecognizer when the user taps on the UILabel, like so:
UITapGestureRecognizer *tapOnAmount = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapOnBalance)];
[cell.amountLabel setUserInteractionEnabled:YES];
[cell.amountLabel addGestureRecognizer:tapOnAmount];
Changing the values in a method didTapOnBalance will crash the app, like so:
-(void)tapOnBalance{
NSString *headerIdentifier = #"HeaderCell";
HeaderTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:headerIdentifier];
cell.amountLabel.text = #"new Value"; // this will crash because at runtime
// the compiler won't recognize cell.amountLabel...
}
Implementing this in the UITableViewCell will cause me to send the values of the HeaderTableViewCell to the subclass and I don't know how to do that either.
You can't just deque a new cell, that will not give you the cell that the user tapped - it will make a new one. But, if you change your tap handler just a little, you can get the index path of the cell tapped from the gesture.
You need a slight change to the initialization of the gesture (look at the selector):
UITapGestureRecognizer *tapOnAmount = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapOnBalance:)];
[cell.amountLabel setUserInteractionEnabled:YES];
[cell.amountLabel addGestureRecognizer:tapOnAmount];
and then another slight change to your handler:
- (void)tapOnBalance:(UITapGestureRecognizer *)sender
{
CGPoint location = [sender locationInView:self.view];
CGPoint locationInTableview = [self.tableView convertPoint:location fromView:self.view];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:locationInTableview];
// then you can either use the index path to call something like configureCell or send a didSelectRowAtIndexPath like this:
[self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
}
Your code is totally wrong.
You're creating a new cell when the user taps on an existing cell, and trying to change the value displayed in that new cell. Don't do that.
Instead, change the data in your table view's data model, then tell your table view to reload that cell (as explained in ZAZ's answer.) If you've changed the data model to reflect new info for your cell, reloading it will cause it to be displayed with the new settings.
you must implement didSelecRowAtIndexPath and write in it the following line of code after the changing the value to animate the tapped row
[self.myTableView reloadRowsAtIndexPaths:indexPath] withRowAnimation:UITableViewRowAnimationNone];
Hope it helps!

How to add tap gesture to UICollectionViewCell subview returned from dequeueReusableCellWithReuseIdentifier

What's the best method for efficiently adding a tap gesture to a subview of a UICollectionViewCell returned from dequeueReusableCellWithReuseIdentifier that already has a bunch of default gesture recognizers attached to it (such as a UIScrollView). Do I need to check and see if my one custom gesture is already attached (scrollView.gestureRecognizers) and if not then add it? I need my app's scrolling to be as smooth as possible so performance of the check and efficient reuse of already created resources is key. This code all takes place inside cellForItemAtIndexPath. Thanks.
I figured out a way to do it that requires only a single, shared, tap gesture recognizer object and moves the setup code from cellForItemAtIndexPath (which gets called very frequently as a user scrolls) to viewDidLoad (which gets called once when the view is loaded). Here's the code:
- (void)myCollectionViewWasTapped:(UITapGestureRecognizer *)tap
{
CGPoint tapLocation = [tap locationInView:self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:tapLocation];
if (indexPath)
{
MyCollectionViewCell *cell = (MyCollectionViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
CGRect mySubviewRectInCollectionViewCoorSys = [self.collectionView convertRect:cell.mySubview.frame fromView:cell];
if (CGRectContainsPoint(mySubviewRectInCollectionViewCoorSys, tapLocation))
{
// Yay! My subview was tapped!
}
}
}
- (void)viewDidLoad
{
// Invoke super
[super viewDidLoad];
// Add tap handler to collection view
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(myCollectionViewWasTapped:)];
[self.collectionView addGestureRecognizer:tap];
}
Here's a rough, very simple outline of a possible design solution: you could subclass UICollectionViewCell and override its initialization methods to add the gesture recognizer to its subviews. Furthermore, if you don't want the cell to "know" about the gesture recognizer, you could create a protocol that the data source object would conform to. The cell object would call a "setup" protocol method at the appropriate time.
Hope this helps!

How can I swipe a row from a TableView to another

I have in one ViewControl two TableViews implemented. Initially one has data and another doesn't.
So, I was wondering how would I implement the gesture event of touching one row in the fulfilled TableView and swipe it to the empty TableView, in order to move that datum.
add the swipe gesture to each cell of your table, this gesture call a Custom method where you pass the indexPath of the cell then in your Custom method write a code for add this object from the array of first table to the second and remove it from first array. Finally you refresh boh table with reloadData method
What I've done so far... (It's slightly different of what #Mirko told)
Added the UISwipeGesture to the table (inside ViewDidLoad method), and defined it to capture the "Swipe Up" event, calling my event handler.
swipeCell = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeUpEvent:)];
swipeCell.direction = UISwipeGestureRecognizerDirectionUp;
[self.tableA addGestureRecognizer:swipeCell];
Implemented the event handler, that get the cell selected by the swipe movement when it starts.
-(IBAction)swipeUpEvent:(UIGestureRecognizer *) sender
{
CGPoint location = [sender locationInView:self.tableA];
NSIndexPath *swipedIndexPath = [self.tableA indexPathForRowAtPoint:location];
NSString *temp = [arrayA objectAtIndex:swipedIndexPath.row];
[arrayB addObject:temp];
[arrayA removeObjectAtIndex:swipedIndexPath.row];
[self.tableB reloadData];
[self.tableA reloadData];
}
It may not be the most elegant solution for the problem, but at least I avoided creating an ActionListener for each cell. I hope it saves me some memory.

Resources