UISegmentedControl: how to detect click on current segment? - ios

is there a way to detect second click on a segment in UISegmentedControl? I found:
Detect second click on a segment
however, it is stated that:
If you set a segmented control to have a momentary style, a segment doesn’t show itself as selected (blue background) when the user touches it. The disclosure button is always momentary and doesn’t affect the actual selection.
Is there a way to detect second click as well as trigger the selection action and show the segment as selected?
If there is no straight forward way to do it, what I was thinking, is that I first have the momentary flag set to YES, then upon each click, manually update the selection state, but then I also need to update/deselect other segments.
Thanks

The solution is to have a custom subclass of UISegmentedControl and check it yourself like this.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
current = self.selectedSegmentIndex;
[super touchesBegan:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesEnded:touches withEvent:event];
if (current == self.selectedSegmentIndex)
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
I had an other solution all in touchesBegan, but it's not working anymore in iOS 7. There is also other solution on Stack Overflow that are not working in iOS 6 and greater.

To make a particular segment click-able again is not possible, but you can reset the whole segmentControl using UISegmentedControlNoSegment.
[self.segmentCtrlOutlet setSelectedSegmentIndex:UISegmentedControlNoSegment];
what you have to do is put the above code in the place where that code executes when you click on a particular segment of UISegmentedControl.
for eg. In my project when I click on a segment, UIPopoverController opens up and inside it I have UIPicker, so I use the above code in UIPicker delegate method "didSelectRow"

Related

iOS: Calling Pan Gesture attached to a UIButton programmatically

When a user highlights a button in my horizontal scrollView, an identical looking button (Different draggable subclass) is added right above. What I'm trying to achieve is similar to lifting a card off a stack like Solitaire, and having another card underneath it.
Everything is working except that right now the moment the user highlights, the touch get's canceled as the new view come's into place. The user has to lift their finger off and tap again to register that the dragging event has begin. What I want to do is to automatically pass the touch from the first button to the newly added button without the user having to remove their finger again and touching the new button. I'm not even sure if this is possible.
Maybe I'm thinking about this the wrong way, but the reason I don't make the first button the draggable button is because I reuse it in my horizontal scrollView.
Which I feel you should consider each card as a custom UIView and handle
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
to show selection, dragging and finally placing of a card. So all logic for selection and put card would in one custom UIView class. For all other validation do that in your parent UIViewController

Handling a touch event across multiple subviews

I am new to iOS development. I have a custom drawn view which is composed of multiple subviews covering the target area on screen. Specifically this is a board game like chess where I used a view for each square. The squares are created as subviews on a UIView. There is one UIViewController for this. From what I read, I have to have touchesBegan, touchesEnded etc calls in my UIView to handle these. But none of these functions are getting called. I added these calls on the base view and all the subviews. So -
How do I simulate these touch events in the iOS simulator? A mouse click is not calling the touchesBegan ,touchesEnded calls on any view.
Ideally I would like to handle these in the UIViewController because I want to run the touch through some logic. Is that possible? How do I achieve it?
Please refer THIS
It is tutorial in Apple sample codes it describes how to handle touches very nicely.
Just run the sample code and go through description you will get clear idea how touches work un iOS.
Turns out when I add the view programmatically and not through the storyboard the userInteractionEnabled variable is set to NO by default. After setting it up, I get the touchesEnabled call getting called in the view.
Check this :
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if(![touch.view isKindOfClass:[yourView class]])
{
}
}
Hope this will help.

How are targets getting triggered in UIButton?

I have a UIButton in a View and over that button I have a UILabel (TTTAttributedLabel). (https://github.com/mattt/TTTAttributedLabel) (Though, this is not a direct question related to TTTAttributedLabel custom class)
This UILabel performs some actions with touch and If doesn't like touch coordinates it forwards them to super with the followings in corresponding methods:
[super touchesBegan:touches withEvent:event];
[super touchesMoved:touches withEvent:event];
[super touchesEnded:touches withEvent:event];
[super touchesCancelled:touches withEvent:event];
I see that the button below is being pressed in that case. I also see that all of those methods in UIButton is getting called perfectly. I also log UITouch objects to see if they match.
The problem is, the action set to UIButton is not getting called (even for UIControlEventTouchDown). What does trigger those actions? I thought that a matching touchesBegan with touchesEnded should have called the selector added for target action to that button.
Touches trigger the control events, and I would say your button does not receive touches simply because there is a label over a button.
There are two ways you could go around this. First, and probably the preferred way is to use the atributedTitle proprety of a UIButton instead of mashing an additional label where it's not necessary:
https://developer.apple.com/library/ios/documentation/uikit/reference/UIButton_Class/UIButton/UIButton.html#//apple_ref/occ/instm/UIButton/attributedTitleForState:
The other way is to delve deeper into UIControl, possibly subclass it, and then handle the touch events on a bit of a finer scale, although this is far more complex than the solution above:
https://developer.apple.com/library/ios/documentation/uikit/reference/uicontrol_class/reference/reference.html

Detecting user ended touching screen

in my app i'm able to detect a touch by connecting the view to an action touch down event. However, i want to be able to detect that the user lifted his finger off screen. am i able to do that?
Edit: sorry for the short post. actually i have no hint how to do that or even to try to do that!
Well, that depends on where you're trying to track the touch removal. If for example, you're using a button and you've already linked an action to touchDown, you can simply link another action for the buttons control event touch up inside/outside.
If you're interested in tracking that touches ended on the entire screen, you can use -touchesEnded: withEvent:.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
}

touchesBegan: withEvent: is not called when tapped on a UIButton

What I want to implement is column matching type functionality. I have three buttons on right column and three on left column with some info on them. I want to draw path from one button on right side to any of the button on left side by dragging finger.
I would use UIBezierPath path to draw path, and for that definitely a start and end point is needed.
Now the issue is how can I trigger touchesBegan, touchesMoved and touchesEnded methods by tapping on buttons so that I can get start and end points.
Another option that I am thinking about is to cover all the buttons with an invisible UIView, and somehow check if the point touched of this overlay view lies in any of the button frames.
BTW I can replace these buttons with simple UIImageView as well. I added buttons just for the sake of getting touch points.
Any help.
Create a subclass of UIButton and add this...
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
[self.nextResponder touchesBegan:touches withEvent:event];
}
This will get you your touches within the button.
Uncheck User Interaction Enabled checkbox of UIButton. You will get call for touchesbegan method on that button.

Resources