UICollectionView Swipe - ios

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?

Related

One custom cell in UICollectionView swift

I have a page in my App with a slider on top and a repeated list on the bottom. now I'm looking for a solution that can be done this entire UI with a single UICollectionView, is that possible to have a single cell with custom design and dataSoruce from other cells?
Here is my design:
Or should I use tow different UICollectionView separately? what is the best solution out there?
Also, I created UI programmatically. is not Storyboard.
As I mentioned in comment you have to take
One collection view
Two Sections
In section one pass items : 1
In Section two pass items: Array count
gallery here is sample code
GalleryCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kGalleryCell forIndexPath:indexPath];
if (cell.gestureRecognizers.count <= 0) {
UISwipeGestureRecognizer *swipeNext = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(cellDidSwipe:)];
swipeNext.direction = UISwipeGestureRecognizerDirectionLeft;
UISwipeGestureRecognizer *swipePrev = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(cellDidSwipe:)];
swipePrev.direction = UISwipeGestureRecognizerDirectionRight;
[cell setGestureRecognizers:#[swipeNext,swipePrev]];
}

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);
}

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!

Swipable Cell in static UITableView

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...
}

UIPanGestureRecognizer on UITableViewCell overrides UITableView's scroll view gesture recognizer

I've subclassed UITableViewCell and in that class I apply a Pan gesture recogniser:
UIPanGestureRecognizer *panning = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(handlePanning:)];
panning.minimumNumberOfTouches = 1;
panning.maximumNumberOfTouches = 1;
[self.contentView addGestureRecognizer:panning];
[panning release];
I then implement the delegate protocol which is supposed to allow simultaneous gestures in the table's view:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
Then I place a log inside the handlePanning method just to see when it's detected:
- (void)handlePanning:(UIPanGestureRecognizer *)sender {
NSLog(#"PAN");
}
My problem is that I'm not able to vertically scroll through the list of cells in the tableview and that handlePanning is called no matter which direction I pan.
What I want is for handlePanning to only be called when there is only horizontal panning and not vertical. Would appreciate some guidance.
Have you tried setting pannings delegate property?
panning.delegate = /* class name with the delegate method in it */;
You'll also need to conform that class to UIGestureRecognizerDelegate.
Subclass the panning gesture recognizer and make it recognize only horizontal panning. There is a great WWDC 2010 video on the issue of custom gesture recognizers available. Actually there are two on that subject, check them out at https://developer.apple.com/videos/archive/:
Simplifying Touch Event Handling with Gesture Recognizers
Advanced Gesture Recognition
Add the gesture recogniser On tableview. From that, you can get the cell object. From there you can handle the cell Functionality. For each gesture, there will be a begin, changed, end state. So, store the begin position.
CGPoint beginLocation = [gesture locationInView:tblView]; // touch begin state.
CGPoint endLocation = [gesture locationInView:tblView]; // touch end state.
Using this point, you can get the IndexPath
NSIndexPath *indexPath = [tblView indexPathForRowAtPoint:beginPoint];
From this indexpath, you can access the cell.
UITableViewCell *cell = [tableview cellForRowAtIndexPath : indexPath];
Using this Cell object, you can handle it.
Have you tried setting the bounces property to NO?

Resources