UISlider evaluate the result once they have stopped changing the value - uislider

I have a UI slider that is continuous. I take the value as it changes and use it to calculate a value that i put into a textfield.
I have the value changed outlet linked to the method that does the calculation and that works ok but i also want a method to fire once the user lifts off the slider that effectively gives a once time evaluation of the final set value.
I have tried connecting the the did end on exit method and others available .

Use the UISlider's UIControlEventTouchUpInside event and, if necessary the UIControlEventTouchUpOutside event. These events will be triggered when the user lifts their finger off the UISlider. Which one is called will depend on whether the finger is inside or outside the bounds of the UISlider when it is lifted.

Related

How to dynamically change UIButton title during Touch and Hold

I am following this answer to change title of my UIButton. To sum up, here is what I have to do:
When user touches down, title of the button starts changing.
While touch is held, it should change every 1 second, and user
should be able to see it.
When user touches up (stops touching), button title should be fixed to the last value held.
I handle 1 using setTitle:forState:
I handle 2 using setTitle:forState:. This keeps happening as far as the timer keeps firing following user's touch, every 1 second.
I handle 3 using titleForState. However here I don't get the value set in 2.
Sometimes when I get correct value, there is still one problem: After touch is over, I still see in UI the same old title on that custom UIButton, not the one that I read using titleForState. (for that matter, even UIButton.textLabel.text gives wrong value)
1 - Am I following the right approach for touch and hold? (I mean using the timer approach depicted to set and read UIButton titles)
2 - If yes, what should I change in my code to read correct UIButton title value?
EDIT:
I got rid of the issue I get in 3 above. The reason for the issue was: I wasn't supplying same UIControlState combination while reading and writing. I was assuming that if you supply UIControlStateNormal | UIControlStateHighlighted for writing title and then use UIControlStateNormal for reading it back, it should give back the currect title value, and vice versa. Unfortunately that's not the case. I changed my app logic so that I only have to use one of these states at both times.
However the main issue still remains (2 above) - how to show title while the UIButton is still in highlighted state. Title is completely invisible while the touch is held.
how to show title while the UIButton is still in highlighted state. Title is completely invisible while the touch is held.
Is your button configured such that the title disappears during a touch event, without your code changing the title text? That is with no code changing the title does it still disappear?
I think your button needs to be redrawn, try calling [button setNeedsDisplay] after changing the title text.

UISegmentedControl setSelectedSegmentIndex: without valueChanged Action

I'm setting the selectedSegmentIndex of an UISegmentedControl via code.
Whenever I do this the valueChanged action gets called. This sounds logical for me, but is there a way to set the selected segment without invoking the action? It should just update the display.
I've used UISegmentedControl more than once, and until now I didn't even noticed that behavior. But this time I need to present an alert if a special segment is selected. So I can't live with the invoked action if the view appears and I want to show the previous selected value.
I could disconnect the action, change the selectedValue and reconnect the action. But maybe there is a better way.
Your question is a sensible one; I can only suggest that you've found a bug, since this is so unusual. Usually, changing a control in code doesn't cause any control events to be emitted. Setting a UIDatePicker's date doesn't emit a Value Changed event. Setting a UIPageControl's currentPage doesn't emit a Value Changed event. Setting a UISlider's value doesn't emit a Value Changed event. Setting a UISwitch's on doesn't emit a Value Changed event. Similarly, setting a UITextField's text doesn't emit an Editing Changed event. So, the fact that changing a UISegmentedControl's selectedSegmentIndex emits a Value Changed event feels wrong. I'm going to file a bug and I think you should too.
I don't see an obvious way to determine whether the Value Changed event was triggered by the user tapping or programmatically. You'll have to raise and lower a BOOL flag or something.
EDIT: This is fixed in iOS 5.
I still have this issue in iOS 7.1.
I was reloading table and setting segment index but it was calling 'value changed' delegate.
To avoid that I nilled 'segment control's' delegate first and then set value programatically, and again reset the delegate to current class. This won't call 'value change' delegate.
As per Apple
The selectedSegmentIndex property is generally used to determine:
the index number for identifying the selected segment (that is, the last segment touched).
The default value is UISegmentedControlNoSegment (no segment selected) until the user touches a segment. Set this property to -1 to turn off the current selection.
You can also change it to different value depend upon your requirement.
UISegmentedControl ignores this property when the control is in momentary mode. When the user touches a segment to change the selection, the control event UIControlEventValueChanged is generated; if the segmented control is set up to respond to this control event, it sends a action message to its target.
(ref)

UISwitch force drag to change setting

Is there a way to stop a UISwitch from toggling state when you tap on the inactive side? I would like a control that forces a deliberate 'swipe' action to prevent the user accidentally clicking it. I've had a look around but haven't found any setting that removes the instant toggle on tap.
UISwitch is a child of UIResponder. So you can try to use methods like touchesBegan:withEvent:, touchesMoved:withEvent: and touchesEnded:withEvent: to detect user actions.
The idea is to set some flag to 'changes are not allowed' state, when user began touches. Change it, depending on touch coordinates - for example, change state to 'changes are allowed', if user moved touch more than 25 pixels right. And make real changes when touches ended, depending on final flag's state.

iphone - forcing button to acknowledge touch programmatically

When you touch a UIButton it hides for a fraction of second and then it executes its action. This fast "blink" is the feedback the user needs to know that the button has been clicked.
In the project I am doing, I need to select the button programmatically, as if the user had clicked it. In other words, the same behavior has the button had been clicked by the user... a fast blink and execution of its action.
Is this possible to do?
thanks for any help.
The change in the appearance of the button is effected by setting the button's highlighted property. The property is automatically set to YES when the user touches down on the button, and back to NO when she releases.
The highlighted property is writable, so you can set it YES yourself to simulate a touch down. You'll probably want to use +[NSTimer scheduledTimerWithTimeInterval:invocation:repeats:] to set it back to NO after a short interval.
It is pretty simple, and probably there is a better solution.
First, use images to your button, and when you have to fire the button, you just change the button's image in the normal state to the pressed image, and after that, replace it back to the original. You can simply do it with a timer.

Where's the difference between UIControlEventTouchDragOutside and UIControlEventTouchDragExit?

Both appear to have the exact same effect. They come both when the finger is far enough away from the control. The "bounds" is not really the criteria for UIControlEventTouchDragExit. It gets fired only if it's far away enough...
I came here looking for the same thing and the answer from eOgas did not seem accurate. I did my own test case and here are my results for those who want a detailed answer without having to test it for themselves:
UIControlEventTouchDragExit
gets called only once as the user leaves the control they pressed. Once the user breaks the 'magical boundary'* outside a UIButton (for instance) this event gets called once. If, while still dragging, the user drags back into the control and back out again, this event gets called once again. The reverse can apply to UIControlEventTouchDragEnter.
UIControlEventTouchDragOutside
gets called after UIControlEventTouchDragExit and gets called repeatedly every time the user drags their finger while still holding down the original touch that was used to enter the control. For those familiar with the touchesMoved method of UIView, it works similarly. The reverse can apply to UIControlEventTouchDragInside however this can obviously get called without having to leave the control first.
To understand or remember better, you can compare these events to a person leaving (and coming to) their house wherein they only exit the house once but then proceed to move outside repeatedly. Also, a person only enters their house once but then proceeds to move inside repeatedly.
*the extra space around a UIControl object that takes into consideration the user's potential for imprecise touches.
UIControlEventTouchDragOutside
An event where a finger is dragged just outside the bounds of the control.
UIControlEventTouchDragExit
An event where a finger is dragged from within a control to outside its bounds.
It sounds like with UIControlEventTouchDragOutside is fired when the user touches just outside the bounds, regardless of whether or not the finger was ever within the bounds. UIControlEventTouchDragExit is only fired when the finger is dragged from within the bounds to outside the bounds.
So, UIControlEventTouchDragOutside would be used when resizing a control (an edge tap, then drag), whereas UIControlEventTouchDragExit would be used to move the control around (tap inside and drag).
.touchDragOutside is continous, while .touchDragExit is not.
.touchDragOutside gets called on every drag movement that happens outside bounds (similar to DragGesture.onChanged(_:)), while
.touchDragExit gets called once as the drag leaves the bounds.
They both (!) get called only when the drag is initiated within the view.
In addition, they are only fired when the finger is "far away" (~70 pt) from the control. They won't get fired as soon as the finger leaves the bounds (same goes .touchUpOutside). They seem to be designed for the users to deliberately cancel ongoing touches.