Multiple UIGestureRecognizers in Xcode/Swift - ios

Right now, I have two different UILabels each with their own long press and pan UIGestureRecognizers (setup through the storyboard). My final goal is to have each UILabel change color when long pressed, and without lifting their finger to end the long press, to change the value of the UILabel itself when the user pans up and down or side to side.
Right now, each UILabel has its own pan gesture method and long press gesture method. Is there any way to have a single long press/pan method for both UILabels but also have the ability to do something for one label and something else for another?
Also, is there a better approach to doing this? Eventually, I would also like to implement visual feedback when changing the value of the labels, such as in the form of animations.
I am new to iOS programming and programming in general and detailed answers are greatly appreciated. Thanks.

You can have a single function.No need to have seperate gestures for seperate Label.Example
//First add tag value to ur labels
label_one.tag=1;
label_two.tag=2;
UIPanGestureRecognizer * _panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self
action:#selector(handlePanGesture:)];
_panGestureRecognizer.delegate = self;
[label_one addGestureRecognizer:_panGestureRecognizer];
UIPanGestureRecognizer * _panGestureRecognizer_two = [[UIPanGestureRecognizer alloc] initWithTarget:self
action:#selector(handlePanGesture:)];
_panGestureRecognizer_two.delegate = self;
[label_two addGestureRecognizer:_panGestureRecognizer_two];
-(void)handlePanGesture:(UIPanGestureRecognizer*)sender{
if(sender.tag==1){
}
else if(sender.tag==2){
}
}
Same goes for other gesture as well

Related

Single Finger Swipe Gesture only working with Pinch Gesture

I'm trying to add a very simple swipe up gesture to one of my views. The gesture does not work at all unless I apply an outward/opposite pinch gesture with two of my fingers. I am creating the gesture connections via IB. I have set up the gesture properties to Swipe: Down and Touches: 1. However it will only work with a 2 finger outward pinching motion? What is going on? Thanks.
Edit:
Ok, I've tried coding it out rather than using interface builder and I'm getting the same results. Here is the code I'm using
UISwipeGestureRecognizer *swipeUpOnVideoView = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(SwipeUp:)];
swipeUpOnVideoView.direction = UISwipeGestureRecognizerDirectionUp;
swipeUpOnVideoView.numberOfTouchesRequired = 1;
[self.playerView addGestureRecognizer:swipeUpOnVideoView];
As you can see I am specifically designating only 1 touch, however my SwipeUp: method will only execute if I use an outward pinching motion with two fingers???
check this it working proper in my application:
UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeUp:)];
[swipeUp setDirection:UISwipeGestureRecognizerDirectionUp ];
[self.view addGestureRecognizer:swipeUp];
- (IBAction)swipeUp:(UISwipeGestureRecognizer *)recognizer
{
// do you stuff here
}
May be it will help you.
Happy coding...:)
It turned out I had a number of other UITapGestureRecognizers that were on my Xib file. Even though I wasn't calling them in the code anywhere they were associated with views on my page via the connections inspector. For some reason this interference made it so that my single finger swipeGesture would only register if I used a two finger pinching motion.
Deleting multiple UITapGestureRecognizers from my xib and then writing the code for the UISwipeGestureRecognizer programmatically fixed the problem for me.

Strikethrough Text with Animation iOS

What is the best way to display a strikethrough animation? When a user swipes their finger across a UITableViewCell, I would like to animate a thin line across cell.textlabel.text
The two ways I've thought of so far would be using Animation or somehow displaying a custom image and revealing it slowly from left to right? Does anybody have any advice on this?
I already have the swipe gestures working, I now just need to know how to make the animation happen:
Add Gesture Recognizer:
//Add a left swipe gesture recognizer
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSwipeLeft:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[self.tableView addGestureRecognizer:recognizer];
//Add a right swipe gesture recognizer
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSwipeRight:)];
recognizer.delegate = self;
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[self.tableView addGestureRecognizer:recognizer];
Delegate Methods for Gestures:
- (void)handleSwipeLeft:(UISwipeGestureRecognizer *)gestureRecognizer
{
NSLog(#"uncompleted");
}
// Cross Item off of the list
- (void)handleSwipeRight:(UISwipeGestureRecognizer *)gestureRecognizer
{
NSLog(#"completed");
}
Based on what you have so far the following should work:
when handleSwipeLeft (or right) fires, place a new UIView with a black background color over the textfield at the textfield's x point and around halfway to the y point with a width of 0 and height of 1
then, call [UIView animationWithDuration....] changing the UIView's width property to be roughly the width of the textfield.
This should be close to what you want with some tweaking. I don't think it will be possible to animate the strikethrough from using the properties of the font alone but this technique should simulate it just fine.
Good job on getting half way there.

iOS: Can I intercept swipes on top of a UIWebView?

I want the user to be able to swipe left, right, upward and downward on a UIWebview, but I don't want the HTML/Javascript to process those swipes-- I want to do that myself.
Is that possible: To intercept just the swipes? I want the taps still to go through to the UIWebview.
Thanks.
Sure thing.Just attach UIGestureRecognizer subclass to that view and hold on for calls...
UISwipeGestureRecognizer* leftSwipeRecognizer = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(someAction)];
leftSwipeRecognizer.numberOfTouchesRequired = 1;
leftSwipeRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
leftSwipeRecognizer.cancelsTouchesInView = YES;
[self.webView addGestureRecognizer:leftSwipeRecognizer];
there is some sample for left swipe gesture. You can set more with very similar approach...Hope that helps.
If you add a UISwipeGestureRecognizer onto the UIWebview with
addGestureRecognizer:
it will allow you to get those events. I believe the default is to only allow one recognizer at a time, but I'm not sure if that applies to individual gesture types or across all gesture types, so this may only be the first step in solving your problem.

How do I subclass UISegmentedControl so that individual segments recognize a UILongPressGestureRecognizer?

First off this question has been helpful in my understanding of how to subclass UIButton for long presses. I would like to do the same for UISegmentedControl, however I don't see how I would be able to identify which segment was held down since UISegmentedControl does allow direct access to it's segments (UISegmentedControl.h shows them as private). I could just customize a few UIButtons to look like an UISegmentedControl however I would also have to implement the momentary switch logic. Which wouldn't be a big deal but subclassing UISegmentedControl seems cleaner to me.
BTW, I'm using this control to imitate a radio's preset controls: tap to go to a saved station and hold to assign the current station to that segment.
I tried this without subclassing and it seems to work.
UILongPressGestureRecognizer* recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(pressGesture:)];
recognizer.delegate = self;
[mySegCtrl addGestureRecognizer:recognizer];
[recognizer release];
...
-(void)pressGesture:(UILongPressGestureRecognizer*)gesture
{
NSLog(#"pressGesture %#", gesture);
}
Long press first selects the segment then fires the gesture. If you aren't getting the callback check my code - I got stuck for a while because I wasn't setting recognizer.delegate=self.

How can I detect the touch event of an UIImageView?

I have placed an image (UIImageView) on the navigation bar. Now I want to detect the touch event and want to handle the event. How can I do that?
In practical terms, don't do that.
Instead add a button with Custom style (no button graphics unless you specify images) over the UIImageView. Then attach whatever methods you want called to that.
You can use that technique for many cases where you really want some area of the screen to act as a button instead of messing with the Touch stuff.
A UIImageView is derived from a UIView which is derived from UIResponder so it's ready to handle touch events. You'll want to provide the touchesBegan, touchesMoved, and touchesEnded methods and they'll get called if the user taps the image. If all you want is a tap event, it's easier to just use a custom button with the image set as the button image. But if you want finer-grain control over taps, moves, etc. this is the way to go.
You'll also want to look at a few more things:
Override canBecomeFirstResponder and return YES to indicate that the view can become the focus of touch events (the default is NO).
Set the userInteractionEnabled property to YES. The default for UIViews is YES, but for UIImageViews is NO so you have to explicitly turn it on.
If you want to respond to multi-touch events (i.e. pinch, zoom, etc) you'll want to set multipleTouchEnabled to YES.
To add a touch event to a UIImageView, use the following in your .m file:
UITapGestureRecognizer *newTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(myTapMethod)];
[myImageView setUserInteractionEnabled:YES];
[myImageView addGestureRecognizer:newTap];
-(void)myTapMethod{
// Treat image tap
}
You can also add a UIGestureRecognizer. It does not require you to add an additional element in your view hierarchy, but still provides you will all the nicely written code for handling touch events with a fairly simple interface:
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:#selector(handleSwipe:)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[imgView_ addGestureRecognizer:swipeRight];
[swipeRight release];
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:#selector(handleSwipe:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[imgView_ addGestureRecognizer:swipeLeft];
[swipeLeft release];
I've been on different threads on the past few hours trying to find a solution for my problem, to no avail. I see that many developers share this problem, and I think people here know about this. I have multiple images inside a UIScrollView, trying to get tap events on them.
I am not getting any events from an UIImangeView, but I do get an event from a similar UILable with very similar parameters I am setting to it. Under iOS 5.1.
I have already done the following:
set setUserInteractionEnabled to YES for both `UIImageView and parent
view .
set setMultipleTouchEnabled to YES for UIImageView.
Tried subclassing UIImageView, didn't help any.
Attaching some code below, in this code I initialize both a UIImageView and UILabel, the label works fine in terms of firing events. I tried keeping out irrelevant code.
UIImageView *single_view = [[UIImageView alloc]initWithFrame:CGRectMake(200, 200, 100, 100)];
single_view.image = img;
single_view.layer.zPosition = 4;
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
[single_view addGestureRecognizer:singleTap];
[single_view setMultipleTouchEnabled:YES];
[single_view setUserInteractionEnabled:YES];
[self.myScrollView addSubview:single_view];
self.myScrollView.userInteractionEnabled = YES;
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
testLabel.backgroundColor = [UIColor redColor];
[self.myScrollView addSubview:testLabel];
[testLabel addGestureRecognizer:singleTap];
[testLabel setMultipleTouchEnabled:YES];
[testLabel setUserInteractionEnabled:YES];
testLabel.layer.zPosition = 4;
And the method which handles the event:
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
UIView *tappedView = [gesture.view hitTest:[gesture locationInView:gesture.view] withEvent:nil];
NSLog(#"Touch event on view: %#", [tappedView class]);
}
As said, the label tap is received.
Instead of making a touchable UIImageView then placing it on the navbar, you should just create a UIBarButtonItem, which you make out of a UIImageView.
First make the image view:
UIImageView *yourImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"nameOfYourImage.png"]];
Then make the barbutton item out of your image view:
UIBarButtonItem *yourBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:yourImageView];
Then add the bar button item to your navigation bar:
self.navigationItem.rightBarButtonItem = yourBarButtonItem;
Remember that this code goes into the view controller which is inside a navigation controller viewcontroller array. So basically, this "touchable image-looking bar button item" will only appear in the navigation bar when this view controller when it's being shown. When you push another view controller, this navigation bar button item will disappear.
You might want to override the touchesBegan:withEvent: method of the UIView (or subclass) that contains your UIImageView subview.
Within this method, test if any of the UITouch touches fall inside the bounds of the UIImageView instance (let's say it is called imageView).
That is, does the CGPoint element [touch locationInView] intersect with with the CGRect element [imageView bounds]? Look into the function CGRectContainsPoint to run this test.
First, you should place an UIButton and then either you can add a background image for this button, or you need to place an UIImageView over the button.
Or:
You can add the tap gesture to a UIImageView so that get the click action when tap on the UIImageView.
For those of you looking for a Swift 4 solution to this answer, you can use the following to detect a touch event on a UIImageView.
let gestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageViewTapped))
imageView.addGestureRecognizer(gestureRecognizer)
imageView.isUserInteractionEnabled = true
You will then need to define your selector as follows:
#objc func imageViewTapped() {
// Image has been tapped
}
Add gesture on that view. Add an image into that view, and then it would be detecting a gesture on the image too. You could try with the delegate method of the touch event. Then in that case it also might be detecting.

Resources