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

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.

Related

Detect touch over TableView and still be able to scroll

I need to be able to detect immediate touch and get its position. (so didSelectRowAtIndexPath can't help us since it does not act immediately when scrolling up and down fast, you need to breathe in and select one by one)
Already tried everything I can think of. Touches began in each cell does not work because it suddenly behaves like didSelectRowIndexPath when implemented in custom cell class. Same result with TableViewController, the nature of touches began (you touch it, respond right away) just won't work.
* I'm not trying to TAP. Need to be able to get TOUCH (TapGesture does not respond when swiping very carefully/slowly but touches began always does) *
Not sure it's what you need, but you can create a TapGestureRecognizer.
You will likely run into conflicts with the UITableView's own gesture recognisers, but there are mechanisms to solve these which should hopefully let you achieve your desired behaviour (look up requireGestureRecognizerToFail and UIGestureRecognizerDelegate's gestureRecognizerShouldBegin and shouldRecognizeSimultaneouslyWithGestureRecognizer).
Try this.
In cellForIndexpath method.
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
singleFingerTap.delegate=self;
cell.contentView.tag=indexPath.row;
[cell.contentView addGestureRecognizer:singleFingerTap];
//The event handling method
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
NSLog(#"%ld",(long)recognizer.view.tag);
}
I think what you need to do, add UILongPressGestureRecognizer to tableview, so normal touch will scroll and long press will do whatever you want to. Set its minimumPressDuration like 0.2 so it won't take much time. Add action for UILongPressGestureRecognizer and in that method get location like:
CGPoint touchPointInView = [sender locationInView: self.view]; //location reespective to view
CGPoint touchPointInView1 = [sender locationInView: tableView]; //location respective to tableview

Multiple UIGestureRecognizers in Xcode/Swift

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

How to create Marquee IOS Clickable

Can you help me in how we can create a marquee for news , but I need that every new be clickable to show the detail page of the selected new.
I know we have many of examples considering marquee but no one was clickable for every item in the marquee.
Please help me
If you use something like this:
https://www.cocoacontrols.com/controls/marqueelabel
I'm assuming you should have NSArray of news. Put first news into marquee label as a text and start animating it.
You may be notified when marquee view reaches end scrolling (animating) then, put second news.
That's how you know which news user's currently viewing.
To be able to click on marquee and get notification:
UITapGestureRecognizer *tap =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(userDidTapOnNews:)];
[marquee addGestureRecognizer: tap];
-(void)userDidTapOnNews:(UITapGestureRecognizer *)gestureRecognizer
{
// Marquee tapped, your turn ...
// Use gestureRecognizer parameter if you need the view tapped
Marquee *marque = gestureRecognizer.View;
...
// Get news from your news `NSArray`
}
Hope it helps

addTarget:action:forControlEvents: ignored when interacting with separate UITapGestureRecognizer

I'm somewhat new to iOS programming
I have some code (abridged) that looks like the following
UIView *someSubView = [[UIView alloc] initWithFrame:...];
[self addSubView:someSubView];
[someSubView addTarget:self action:#selector(_handleTapOnView:) forControlEvents:UIControlEventTouchUpInside];
_tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(_handleTap:)];
_tapGestureRecognizer.delegate = self;
[self.view addGestureRecognizer:_tapGestureRecognizer];
Unfortunately the gesture recognizer triggers and my views addTarget call does not. I've tried commenting out the gesture recognizer code and it works, so I know its not the call to addTarget on the subview.
I solved this initially by using the gestureRecognizer:shouldReceiveTouch: and doing a hit test for the sub view, but I feel like I'm missing some fundamental understanding here that wouldn't require me adding a manual hit test.
Its important to note that I don't want the code in the _handleTap in the _tapGestureRecognizer to execute when I have tapped on my subview.
Any guidance here? Thanks!
Try using:
_tapGestureRecognizer.cancelsTouchesInView = NO;
otherwise the gesture recogniser will intercept the touches and will not forward them further (in other words, the gesture recogniser gets the touch, handles it, and since it cancel it, no other object gets the touch). By not cancelling, the touch is forwarded for any other object (recognisers or views) to handle it.

Homemade tap gesture recognizer for iOS

I'd like to code my own tap gesture recognizer, to detect the number of taps and number of touches (I don't want to use the iOS tap gesture recognizer because I want to extend it later in various other manners) ;
I tried the following : use the first motionBegin number of touches as the numberOfTouches of the tap, increment the numberOfTaps, and start the tap detection timer to detect the tap gesture if no new taps has been seen in a while
The problem is that one quickly realises that when doing a double-touch tap gesture, iOS either correctly detects one motionBegin with a double touch, or two quick one touch events. I guess a correct implementation should try to detect those quick one touch events that happen closely, but I'm wondering if there is a better way to implement the gesture recognizer.
Someone knows how the iOS tap gesture is implemented?
1. Add UIGestureRecognizerDelegate in your .h file. like
#interface finalScreenViewController : UIViewController <UIGestureRecognizerDelegate>
{
// do your stuff
}
2. Create a view in your viewDidLoad method (or any other method) you wanna to add the gesture in your .m file
ex
UIView * myView=[[UIView alloc]init];
myView.frame=CGRectMake(0,0.self.view.frame.size.width,self.view.frame.size.height);
[self.view addSubView: myView];
UITapGestureRecognizer *letterTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapMethod:)];
letterTapRecognizer.numberOfTapsRequired = 1;
[myView addGestureRecognizer:letterTapRecognizer];
3. you can get view by
- (void) tapMethod:(UITapGestureRecognizer*)sender {
UIView *view = sender.view;
NSLog(#"%d", view.tag);//By tag, you can find out where you had tapped.
}

Resources