Hello I have a UISegmentedControl with two segments. The selected segment is modified programmatically in some case and by the user in some other. I only want to trigger the selector when the change is due to a user action(only when user actually press the segmented control and not when the system do segmentedControl.selectedSegmentIndex = ...). Any idea?
If you do
[self.segment setSelectedSegmentIndex:1];
This will not call the action of valueChanged on the segment, so what is your question?
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents: UIControlEventValueChanged];
- (IBAction)segmentAction:(id)sender {
// valuechanged connected function
UISegmentedControl *segControll = (UISegmentedControl *)sender;
if (segControll.tag == 0) {
}
else {
isProgramaticallyChanged = NO; //important
}
}
Related
I am new to iPhone programming.I have taken one button inside that, I have created another button programmatically with id sender ,I want to use multiple buttons inside that id sender button using tags.Now I did some coding but it is showing some Exception.When i am giving [self somemethodname:(id)sender]; here I am getting problem, actually [self playOrPause] this one I have used in another button.How to slove this please any body tell me.
Thanks
- (void)playOrPause
{
UIButton *aa = [UIButton buttonWithType:UIButtonTypeCustom];
[aa addTarget:self action:#selector(play:)forControlEvents:UIControlEventTouchUpInside];
NSLog(#"hi iam 2");
[self play:(id)sender];
}
-(void)play:(id)sender
{
UIButton *instanceButton = (UIButton*)sender;
instanceButton.tag++;
if (instanceButton.tag == 1)
{
NSLog(#"hi");
} else if (instanceButton.tag == 2)
{
NSLog(#"hi2");
}
}
i created a Drop down class for popup a window on click button , that is work fine but there is a problem is that how can i handle its event that it return index (on popup of tableview which is selected for its own button) what i mistak there ? any one guide me what i will do for it ??
here code for that..
-(IBAction)popupOnClikingButton:(id)sender{
if (sender == button1) {
arrayData = [[NSMutableArray alloc] initWithArray:[NSMutableArray arrayWithObjects:#"Test1",#"Test2",nil]];
dropDownView = [[DropDownView alloc] initWithArrayData:arrayData cellHeight:30 heightTableView:150 paddingTop:-3 paddingLeft:-1 paddingRight:-1 refView:button1 animation:BLENDIN openAnimationDuration:2 closeAnimationDuration:2];
dropDownView.delegate = self;
[dropDownView openAnimation];
[self.view addSubview:dropDownView.view];
return;
}
if (sender == button2) {
[arrayData release];
arrayData = [[NSMutableArray alloc] initWithArray:[NSMutableArray arrayWithObjects:#"Demo1",#"Demo2",nil]];
dropDownView = [[DropDownView alloc] initWithArrayData:arrayData cellHeight:30 heightTableView:150 paddingTop:-3 paddingLeft:-1 paddingRight:-1 refView:button1 animation:BLENDIN openAnimationDuration:2 closeAnimationDuration:2];
dropDownView.delegate = self;
[dropDownView openAnimation];
[self.view addSubview:dropDownView.view];
return;
}
}
return index DropDownDelegate method is.. How Can i handle this event that which button for returnIndex ??
-(void)dropDownCellSelected:(NSInteger)returnIndex{
//set for title that which button is selected here for Ex.
[button1 setTitle:[arrayData objectAtIndex:returnIndex] forState:UIControlStateNormal];
}
try to get button like this:
UIButton* myButton = (UIButton*)sender;
and compare this button with your desired button...........
You can also assign a tag to your buttons. With this, you can use the tag in comparing to your buttons.
I have the need for an UIButton to maintain a pressed state. Basically, if a button is in a normal state, I want to touch the button, it highlight to its standard blue color and then stay blue after lifting my finger.
I made the following UIAction and connected the buttons Touch Up Inside event to it.
-(IBAction) emergencyButtonPress:(id) sender
{
if(emergencyButton.highlighted)
{
emergencyButton.selected = NO;
emergencyButton.highlighted = NO;
}
else
{
emergencyButton.selected = YES;
emergencyButton.highlighted = YES;
}
}
But what happens, after I remove my finger, the button goes back to a white background. For a test I added a UISwitch and have it execute the same code:
-(IBAction) emergencySwitchClick:(id) sender
{
if(emergencyButton.highlighted)
{
emergencyButton.selected = NO;
emergencyButton.highlighted = NO;
}
else
{
emergencyButton.selected = YES;
emergencyButton.highlighted = YES;
}
}
In this case the button toggles to a highlighted and non-highlighted state as I would expect.
Is there another event happening after the Touch Up Inside event that is resetting the state back to 'normal'? How do I maintain the highlighted state?
The highlighted state is applied and removed by iOS when you touch / release the button. So don't depend on it in your action method.
As one of the other answers says, set the highlighted image to be the same as the selected image, and then modify your action method:
-(IBAction) emergencyButtonPress:(id) sender
{
emergencyButton.selected = !emergencyButton.selected;
}
If you want something like a toggle button, customize your "selected" state to be your "pressed" state, and then write something like this:
- (IBAction)buttonTapped:(id)sender {
[(UIButton*)sender setSelected:![sender isSelected]];
}
if you want the above code to work, you should set an image for the state selected and one (even the same) for he state highlighted.
[emergencyButton setBackgroundImage:buttonHighlightImage forState:UIControlStateHighlighted];
[emergencyButton setBackgroundImage:buttonHighlightImage forState:UIControlStateSelected];
hope it helps.
I had this same problem, and this is what worked for me:
-(IBAction)buttonPressed:(id)sender {
if (isSelected) {
[_button setSelected:NO];
[_button setImage:[UIImage imageNamed:#"not_selected.png"] forState:UIControlStateSelected];
isSelected=NO;
}
else {
[_button setSelected:YES];
[_button setImage:[UIImage imageNamed:#"selected.png"] forState:UIControlStateSelected];
isSelected=YES;
}
}
This is not possible unfortunately, as soon as you let go Apple changes the state again.
One option I've used before (but not pretty) is that you use a performSelector with delay 0.1 after the button is pressed to put it again in the selected state. This did work in my case.
EDIT: If you don't want to see the blinking effect, just set the delay to 0.0
This worked for me:
- (void)tapButton:(id)sender{
UIButton *button = sender;
if (!button.selected){
[self performSelector:#selector(highlight:) withObject:button afterDelay:0.0];
}else{
[self performSelector:#selector(removeHighlight:) withObject:button afterDelay:0.0];
}
}
- (void)highlight:(UIButton *)button{
button.selected = !button.selected;
button.highlighted = YES;
}
- (void)removeHighlight:(UIButton *)button{
button.selected = !button.selected;
button.highlighted = NO;
}
Try this simple answer....
- (void)mybutton:(id)sender
{
UIButton *button = (UIButton *)sender;
button.selected = ![button isSelected]; // Important line
if (button.selected)
{
NSLog(#"Selected");
NSLog(#"%i",button.tag);
}
else
{
NSLog(#"Un Selected");
NSLog(#"%i",button.tag);
}
}
I have 2 segmented controls in my viewcontroller view. How can I handle the tap events of both of the segmented controllers?
There are two ways to do so.
Add different actions for every segment control
Add same actions for every segment control & check which control is tapped using its tag.
[yourSegmentedControl addTarget:self action:#selector(segmentSwitch:) forControlEvents:UIControlEventValueChanged];
- (IBAction)segmentSwitch:(id)sender
{
UISegmentedControl *segmentedControl = (UISegmentedControl *) sender;
if(segmentedControl.tag == someTag)
{
if(segmentedControl.selectedSegmentIndex == 1)
{
// your code
}
else if(segmentedControl.selectedSegmentIndex == 2)
{
// your code
}
}
else if(segmentedControl.tag == someTag)
{
if(segmentedControl.selectedSegmentIndex == 1)
{
// your code
}
else if(segmentedControl.selectedSegmentIndex == 2)
{
// your code
}
}
}
Apple docs says:
http://developer.apple.com/library/IOs/#documentation/UIKit/Reference/UISegmentedControl_Class/Reference/UISegmentedControl.html
You register the target-action methods for a segmented control using the UIControlEventValueChanged constant as shown below.
[segmentedControl addTarget:self
action:#selector(action:)
forControlEvents:UIControlEventValueChanged];
So, you just have to register action for every segmented control.
Set the tag property on each segmented control to a different integer. Then in your method you set as the action for when the value changes, check which integer the tag property is set to using [sender tag].
You can use selected mode of segment:
UISegmentedControl *tempSegment = sender;
if ([tempSegment selectedSegmentIndex] == 0){
//first Action
}
else if ([tempSegment selectedSegmentIndex] == 1){
//second Action
}
Assign two different actions to these segmented controls:
[segmentedControl addTarget:self
action:#selector(action:)
forControlEvents:UIControlEventValueChanged];
Swift version:
#IBAction func yourFunctionName(sender: UISegmentedControl) {
if (sender.selectedSegmentIndex == 0){//choice 1
}else{//choice 2
}
}
I'm having a very specific "bug" in my iPhone application. I'm setting two images for the highlighted and normal states of a button. It works as expected when you "press" and then "touch up" at a slow pace, but if you click/tap it quickly, there's a noticeable flicker between states. Is this a known bug or am I setting the states incorrectly?
Here's the code that creates the buttons:
UIImage *normalImage = [[UIImage imageNamed:#"btn-small.png"] stretchableImageWithLeftCapWidth:10.0f topCapHeight:0.0f];
UIImage *highlightedImage = [[UIImage imageNamed:#"btn-small-down.png"] stretchableImageWithLeftCapWidth:10.0f topCapHeight:0.0f];
[self setBackgroundColor:[UIColor clearColor]];
[self setBackgroundImage:normalImage forState:UIControlStateNormal];
[self setBackgroundImage:highlightedImage forState:UIControlStateDisabled];
[self setBackgroundImage:highlightedImage forState:UIControlStateHighlighted];
[self setAdjustsImageWhenDisabled:FALSE];
[self setAdjustsImageWhenHighlighted:FALSE];
When a button is tapped it simply disables itself and enables the other button:
- (IBAction)aboutButtonTouched:(id)sender
{
aboutButton.enabled = FALSE;
rulesButton.enabled = TRUE;
}
- (IBAction)rulesButtonTouched:(id)sender
{
rulesButton.enabled = FALSE;
aboutButton.enabled = TRUE;
}
Any thoughts on this quick-click flicker?
Ok, I resolved this. Took a bit of reverse engineering what I was trying to do, but I thought I'd post what I did in case it helps someone else.
The first thing I did was modify the aboutButtonTouched method to log the button's state property which is a bit-mask NSUInteger:
- (IBAction)aboutButtonTouched:(id)sender
{
rulesButton.enabled = TRUE;
[sender setEnabled:FALSE];
NSLog(#"%d", [sender state]);
}
At this point, the button is disabled through setEnabled, and the log reported that the state was "3". Looking at the bit-mask type for UIControlState:
enum {
UIControlStateNormal = 0, // 0
UIControlStateHighlighted = 1 << 0, // 1
UIControlStateDisabled = 1 << 1, // 2
UIControlStateSelected = 1 << 2, // 4
UIControlStateApplication = 0x00FF0000,
UIControlStateReserved = 0xFF000000
};
(Notes added since I can never remember bitwise). We can see that to get "3" (0011) we should use UIControlStateHighlighted | UIControlStateDisabled (0001|0010 or 1|2), something which I did not have as a state in my original button definition. The key here that there's a brief time when the state is both before just being disabled ("A control enters this state when a touch enters and exits during tracking and and when there is a touch up" -- from the docs). So the final state settings for the button where it does not flicker are:
[self setBackgroundImage:normalImage forState:UIControlStateNormal];
[self setBackgroundImage:highlightedImage forState:UIControlStateDisabled];
[self setBackgroundImage:highlightedImage forState:UIControlStateHighlighted];
[self setBackgroundImage:highlightedImage forState:UIControlStateHighlighted|UIControlStateDisabled];
To be noted that, although not documented, all state combinations that contain UIControlStateHighlighted|UIControlStateDisabled aren't valid: these are equivalent to same without UIControlStateDisabled.
In short:
(UIControlStateHighlighted | UIControlStateDisabled) == UIControlStateHighlighted
and
(UIControlStateSelected | UIControlStateHighlighted | UIControlStateDisabled) == (UIControlStateSelected | UIControlStateHighlighted)
I found that the hard way: was setting some attributes for the Highlighted+Disabled state which was overwriting my settings for the Highlighted state. Spent half a day to track down the issue why button wasn't properly highlighting...
Maybe you should reverse the sequence of changing the buttons
- (IBAction)aboutButtonTouched:(id)sender
{
rulesButton.enabled = TRUE;
aboutButton.enabled = FALSE;
}
When you hide the one button first and then show the other, there's maybe a little gap, which creates the flicker. I think it's better to show the other button first.