UISegmentedControl setSelectedSegmentIndex: without valueChanged Action - iphone

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)

Related

How to handle modifier keys in Cocoa menubar application

So I have a menu bar application that has a slider inside a custom view: I want the ability to press the option key while dragging to make the slider snap to increments.
Right now, everything is working... except I cannot find a single way to notify my menu app that the option key is being pressed. Here's what I've tried:
NSEvent.addGlobalMonitorForEvents
"Note that your handler will not be called for events that are sent to your own application."
NSEvent.addLocalMonitorForEvents
"Your handler will not be called for events that are consumed by nested event-tracking loops such as control tracking, menu tracking, or window dragging"
NSApplication.shared.currentEvent
This dosesn't work because the flagsChanged event isn't handled by the app, so this value is set to another value (mouse button presses).
flagsChanged(with event: NSEvent)
This doesn't get called. I've set the viewController to acceptFirstResponder as well as resigned the first responder of the view. Also, I've subclassed the view and overridden flagsChanged and that hasn't worked.
I've tried creating a menu item that has a key like "s" or "p" to trigger an action. But when the "action" gets triggered, the menu bar hides...
So I'm trying to find how I can be notified when the option key is pressed. Is this possible? I can clarify if you have any questions.
In your custom slider view's mouseDragged method, you'd simply check the NSEvent parameter's modifierFlags to see if it contains the option key.
--
Since it could be interpreted that the slider is an actual NSSlider, if that's the case then the slider's control is really implemented in with an NSSliderCell, and the mouse tracking gets handed off from the view to the cell within mouseDown, so the NSSlider's mouseDragged wouldn't be called, and instead you'd have to do work in the cell's trackMouse:inRect:... method. But if you're using an NSSlider, then you'd probably simply want to use altIncrementValue.

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.

UISlider evaluate the result once they have stopped changing the value

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.

Making Segments start in a state where nothing is selected

I have a UISegmentControl where I'd like if none of the segments are selected when the segment first loads.
Is this possible or do I need to write some custom control?
Many Thanks,
-Code
Just uncheck the 'selected' checkbox for each segment in the Interface Builder Inspector.
EDIT:
If you are doing it through code, this should happen by default. See the discussion for selectedSegmentIndex -
// ignored in momentary mode. returns last segment pressed. default is UISegmentedControlNoSegment until a segment is pressed
// the UIControlEventValueChanged action is invoked when the segment changes via a user event. set to UISegmentedControlNoSegment to turn off selection
#property(nonatomic) NSInteger selectedSegmentIndex;
value of UISegmentedControlNoSegment is -1. So no segment will be selected by default

Detect what's being inputed in a UITextField

I have a UITable View with a textfield that is editable right on the view (like Phone in contacts, etc.). I want to enable/disable my save button conditional up text being present in this field. So, I want the button to start out as disabled (for a new record) and then, as soon as I type the first letter into my text field, I want the button enabled. If I delete again back to zero, I would like the button disabled. You get the point.
Now, for doing this I need some way to detect the text being inputed while the user writes it (and when he finishes editing).
Does anybody know how to do this?
Thanks a lot. Still noob...
Try this: (from the Apple documentation for UITextInputTraits)
enablesReturnKeyAutomatically
A Boolean value indicating whether the return key is automatically enabled when text is entered by the user.
#property(nonatomic) BOOL enablesReturnKeyAutomatically
Discussion
The default value for this property is NO. If you set it to YES, the keyboard disables the return key when the text entry area contains no text. As soon as the user enters any text, the return key is automatically enabled.
Have your view controller adopt the UITextFieldDelegate protocol, and then implement a couple of the protocol's methods:
– textFieldDidBeginEditing:
– textFieldDidEndEditing:
Also, be sure to set the text field's delegate property to point to your view controller. The text field will then automatically send these messages to the controller when editing session begins and ends.