I'm trying to implement an analog of segmented control with two buttons. In default state they have no images, only labels, in selected one they have background image. I want to activate control with TouchDown event.
here is the code (I removed all unnecessary things):
-(IBAction) onButton1
{
button1.selected = YES;
button2.selected = NO;
}
-(IBAction) onButton2
{
button1.selected = NO;
button2.selected = YES;
}
the problem is: assume button1 is selected. When I touch button2 it does not change its image to "selected" image (there is no default image, as I've said), but when I release finger it changes. Also, if I touch already selected button it removes "selected" image and return it when I release it.
I've set highlighted state of buttons, so they have "selected" image in that state, but it did not help (not only in IB, but also with [button setBackgroundImage:[UIImage imageNamed:#"selected.png"] forState:UIControlStateHighlighted];). I've set adjustsImageWhenHighlighted = NO, that did not help too, again, in both program way and IB.
I've seen a lot of similar (but not identical) questions here, but they did not work for me.
Thanks in advance
Since, you wanted to activate the action at touch down event, I assume that you dont need highlighting. Try the following code
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
button1 = [UIButton buttonWithType:UIButtonTypeCustom];
button1.frame = CGRectMake(10.0f, 10.0f, 50.0f, 50.0f);
[button1 setBackgroundImage:[UIImage imageNamed:#"btn.jpeg"] forState:UIControlStateNormal];
[button1 setBackgroundImage:[UIImage imageNamed:#"btnsel.jpeg"] forState:UIControlStateSelected];
[button1 addTarget:self action:#selector(button1Action:) forControlEvents:UIControlEventTouchDown];
[button1 addTarget:self action:#selector(button1TouchUp:) forControlEvents:UIControlEventTouchUpInside|UIControlEventTouchUpOutside];
[self.view addSubview:button1];
button1.selected = YES;
button2 = [UIButton buttonWithType:UIButtonTypeCustom];
button2.frame = CGRectMake(80.0f, 10.0f, 50.0f, 50.0f);
[button2 setBackgroundImage:[UIImage imageNamed:#"btn.jpeg"] forState:UIControlStateNormal];
[button2 setBackgroundImage:[UIImage imageNamed:#"btnsel.jpeg"] forState:UIControlStateSelected];
[button2 addTarget:self action:#selector(button2Action:) forControlEvents:UIControlEventTouchDown];
[button2 addTarget:self action:#selector(button2TouchUp:) forControlEvents:UIControlEventTouchUpInside|UIControlEventTouchUpOutside];
[self.view addSubview:button2];
}
- (void)button1Action:(UIButton*)sender
{
button1.highlighted = NO;
button1.selected = YES;
button2.selected = NO;
}
- (void)button2Action:(UIButton*)sender
{
button2.highlighted = NO;
button2.selected = YES;
button1.selected = NO;
}
- (void)button1TouchUp:(id)sender
{
button1.highlighted = NO;
}
- (void)button2TouchUp:(id)sender
{
button2.highlighted = NO;
}
Related
I had an application in which I am adding some dynamic number of buttons to a scrollview. I had set a normal background and selected background for the UIButton. For some reasons I need to call the UIButton sender method programmatically by:
[self buttontapped:nil];
as this but it is not changing the background of the button by using the code:
button.selected = YES;
I had set the background like this initially of the button:
btn = [UIButton buttonWithType:UIButtonTypeCustom];
int j = i+1;
btn.frame = CGRectMake((j-1)*77, 0, 77, 44);
[btn setBackgroundImage:[UIImage imageNamed:#"bar.png"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:#"bar_hvr.png"] forState:UIControlStateSelected];
btn.selected = NO;
btn.backgroundColor = [UIColor clearColor];
btn.titleLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:14];
btn.titleLabel.textColor = [UIColor whiteColor];
[btn setTitle:head forState:UIControlStateNormal];
btn.tag = i;
[tabBarS addSubview:btn];
-(void)buttonTapped:(id)sender {
if(sender==nil)
{
btn.tag=0;
}
for(int i=0;i<[sarray count];i++)
{
btn.selected=NO;
}
btn = (UIButton *)sender;
NSLog(#"Tab bar %d is clicked",btn.tag);
[self tabCall:btn.tag];
btn.selected = YES;
}
But everything except change of background only working. Where am I going wrong?
i done with bellow method call your UIButton method like:-
btn= [UIButton buttonWithType:UIButtonTypeCustom];
int j=i+1;
btn.frame = CGRectMake((j-1)*77, 0, 77, 44);
[btn setBackgroundImage:[UIImage imageNamed:#"bar.png"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:#"bar_hvr.png"] forState:UIControlStateSelected];
btn.selected=NO;
[btn addTarget:self action:#selector(yourButtonAction:) forControlEvents:UIControlEventTouchUpInside];
btn.backgroundColor = [UIColor clearColor];
btn.titleLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:14];
btn.titleLabel.textColor = [UIColor whiteColor];
btn.tag = i;
[tabBarS addSubview:btn];
and it's Action Method should like with sender
-(IBAction)yourButtonAction:(id)sender
{
UIButton *btn = (UIButton*)sender;
if (![btn isSelected])
{
[btn setImage:[UIImage imageNamed:#"selected_fb_btn.png"] forState:UIControlStateNormal];
[btn setSelected:YES];
[self login];
}
else{
[btn setImage:[UIImage imageNamed:#"facebook.png"] forState:UIControlStateNormal];
[btn setSelected:NO];
}
}
EDIT
You can call button action event programeticuly using bellow trik:-
[btn sendActionsForControlEvents:UIControlEventTouchUpInside];
write this bellow line first and also change the method type from void to IBAction...
btn = (UIButton *)sender;
like bellow...
-(IBAction)buttonTapped:(id)sender {
btn = (UIButton *)sender;
if(sender==nil)
{
btn.tag=0;
}
for(int i=0;i<[sarray count];i++)
{
[btn setSelected:NO];
}
NSLog(#"Tab bar %d is clicked",btn.tag);
[self tabCall:btn.tag];
[btn setSelected:YES];
}
You need to set image property rather than backgroundImage property of UIButton.
Use default Image property and selected property.
[btn setSelected:TRUE];
is the log that you are printing, prints the button.tag correctly?
NSLog(#"Tab bar %d is clicked",btn.tag);
In your button action
btn.selected=YES;
in last line makes the button in selected state always
also get the correct instance as
btn=(UIButton *)sender;
I am created two buttons that are right next to each other to mimic a segmented control. I am doing this to customize the appearance beyond what the UIKit allows. I decided to use the selected property to keep a button pressed. I have two images that one for each state normal and selected.
The problem is that when I select a button, the button highlights and turns dark, because of the hightlight state. I decided to use the selected image for the highlight state too, but it flashes, any ideas or suggestions.
- (void)leftSegmentPressed:(id)sender
{
if ([sender isSelected]) {
[sender setSelected:NO];
}
else {
[sender setSelected:YES];
}
}
For the "selected" button, disable it and manually switch the image for the state.
- (void) viewDidLoad
{
[rightSegmentButton setImage:[UIImage imageNamed:#"unselected.png"] forState:UIControlStateNormal];
[rightSegmentButton setImage:[UIImage imageNamed:#"selected.png"] forState:UIControlStateDisabled];
[leftSegmentButton setImage:[UIImage imageNamed:#"unselected.png"] forState:UIControlStateNormal];
[leftSegmentButton setImage:[UIImage imageNamed:#"selected.png"] forState:UIControlStateDisabled];
}
- (void)leftSegmentPressed:(id)sender
{
sender.enabled = NO;
rightSegmentButton.enabled = YES;
}
- (void)rightSegmentPressed:(id)sender
{
sender.enabled = NO;
leftSegmentButton.enabled = YES;
}
Check whether the image you given is in your Bundle or check image name you given is in lower case or not. Then write like
[button1 setImage:[UIImage imageNamed:#"normal1.png"] forState:UIControlStateNormal];
[button1 setImage:[UIImage imageNamed:#"selected1.png"] forState:UIControlStateSelected];
[button2 setImage:[UIImage imageNamed:#"normal2.png"] forState:UIControlStateNormal];
[button2 setImage:[UIImage imageNamed:#"selected2.png"] forState:UIControlStateSelected];
button1.tag = 1;
button2.tag = 2;
[button1 addTarget:self action:#selector(buttonSelected:) forControlEvents:UIControlEventTouchUpInside]
[button2 addTarget:self action:#selector(buttonSelected:) forControlEvents:UIControlEventTouchUpInside]
in your button event method
-(void)buttonSelected:(id)sender {
if([sender tag] == 1) {
button1.selected = YES;
button2.selected = NO;
} else {
button1.selected = NO;
button2.selected = YES;
}
}
[button setAdjustsImageWhenHighlighted:NO];
This will prevent the flicker.
UIButton *yourButton1 = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
yourButton1.frame = CGRectMake(110.0, 360.0, 100.0, 30.0);
[yourButton1 setTitle:#"Left" forState:UIControlStateNormal];
yourButton.backgroundColor = [UIColor clearColor];
yourButton1.tag = 1;
[yourButton1 setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal ];
UIImage *buttonImageNormal = [UIImage imageNamed:#"yourNormalImage.png"];// set normal image
UIImage *strechableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];
[yourButton1 setBackgroundImage:strechableButtonImageNormal forState:UIControlStateNormal];
UIImage *buttonImagePressed = [UIImage imageNamed:#"yourSelectedImage.png"];// set selected image
UIImage *strechableButtonImagePressed = [buttonImagePressed stretchableImageWithLeftCapWidth:12 topCapHeight:0];
[yourButton1 setBackgroundImage:strechableButtonImagePressed forState:UIControlStateHighlighted];
[yourButton1 addTarget:self action:#selector(leftSegmentPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:yourButton1];
do same for another second button.
and in action method set bellow code..
- (void)leftSegmentPressed:(id)sender
{
UIButton *btnTemp = (UIBUtton *)sender;
if (btnTemp.tag == 1) {
[yourButton1 setSelected:YES];
[yourButton2 setSelected:NO];
}
else {
[yourButton1 setSelected:NO];
[yourButton2 setSelected:YES];
}
}
I know how to set the enable = YES/NO, a button created using a property and xib. However, how do you do the same thing to a programmatically created button from another method in the same class?
For example here is my button in the viewDidLoad:
UIButton *AllList = [UIButton buttonWithType:UIButtonTypeCustom];
AllList.frame = CGRectMake(40, 80, 107.f, 53.5f); //set frame for button
UIImage *buttonImageFull = [UIImage imageNamed:#"allModsBtn.png"];
[AllList setBackgroundImage:buttonImageFull forState:UIControlStateNormal];
[self.view addSubview:AllList];
// add targets and actions
[AllList addTarget:self action:#selector(getButtons:) forControlEvents:UIControlEventTouchUpInside];
AllList.tag = 0;
I would like to set the enable of this button to YES or NO in another method.
#implementation {
UIButton *myButton;
}
- (void)viewDidLoad {
myButton = [UIButton buttonWithType:UIButtonTypeCustom];
myButton.tag = 121;
myButton.frame = CGRectMake(40, 80, 107.f, 53.5f); //set frame for button
UIImage *buttonImageFull = [UIImage imageNamed:#"allModsBtn.png"];
[myButton setBackgroundImage:buttonImageFull forState:UIControlStateNormal];
[self.view addSubview:myButton];
// add targets and actions
[myButton addTarget:self action:#selector(getButtons:)
forControlEvents:UIControlEventTouchUpInside];
myButton.tag = 0;
}
- (void)someOtherMethod {
myButton.enabled = YES;
OR
//In this case you dont need to define uibutton to globaly
UIButton *button = (UIButton*)[[self view] viewWithTag:121];
[button setEnabled:YES];
}
You have to make that button an ivar of your view controller.
#implementation {
UIButton *myButton;
}
- (void)viewDidLoad {
myButton = [UIButton buttonWithType:UIButtonTypeCustom];
myButton.frame = CGRectMake(40, 80, 107.f, 53.5f); //set frame for button
UIImage *buttonImageFull = [UIImage imageNamed:#"allModsBtn.png"];
[myButton setBackgroundImage:buttonImageFull forState:UIControlStateNormal];
[self.view addSubview:myButton];
// add targets and actions
[myButton addTarget:self action:#selector(getButtons:)
forControlEvents:UIControlEventTouchUpInside];
myButton.tag = 0;
}
- (void)someOtherMethod {
myButton.enabled = YES;
}
Something like this:
UIButton *myButton = [self.view viewWithTag:BUTTON_TAG]; // in your case is 0
[myButton setEnabled:YES];
Two ways to do it:
1) you can make it an ivar and then
AllList.enabled = YES;
or
[AllList setEnabled:YES];
2)
set a unique tag to the button
UIButton *AllList = [UIButton buttonWithType:UIButtonTypeCustom];
AllList.frame = CGRectMake(40, 80, 107.f, 53.5f); //set frame for button
AllList.tag = kUNIQUE_TAG;
in the method you want to mess with the button's enabled property
UIButton *theButton = (UIButton *)[self viewWithTag:kUNIQUE_TAG];
[theButton setEnabled:YES];
Well, I have a custom uitabbarcontroller with 3 UIButtons on it (simulating tabs). I have set background images for normal, selected and highlighted states (selected and highlighted are both the same).
Everything works fine but one thing: When I have on tab (button) selected, and that tab gets pressed again, instead of highlighting it shows the button being pressed (getting darker). I have tried setting to NO the property adjustsImageWhenHighlighted, but instead of getting darker, it shows the Normal state background.
Any suggestion?
EDIT: This is the code I have in the UITabBarController subclass
#import "MyTabBarViewController.h"
#interface MyTabBarViewController ()
#end
#implementation MyTabBarViewController
ExploreViewController *exploreController;
ProfileViewController *profileController;
UIButton* leftButton;
UIButton* rightButton;
- (void)viewDidLoad
{
[super viewDidLoad];
exploreController = [[ExploreViewController alloc] initWithNibName:#"ExploreViewController" bundle:nil];
profileController = [[ProfileViewController alloc] initWithNibName:#"ProfileViewController" bundle:nil];
self.viewControllers = [NSArray arrayWithObjects:exploreController, profileController, nil];
[self addLeftButtonWithImage: [UIImage imageNamed:#"LeftTabBarIcon"] highlightImage:[UIImage imageNamed:#"LeftTabBarIcon_On"]];
[self addRightButtonWithImage: [UIImage imageNamed:#"RightTabBarIcon"] highlightImage:[UIImage imageNamed:#"RightTabBarIcon_On"]];
}
- (void) leftTabPressed
{
leftButton.selected = YES;
rightButton.selected = NO;
[self setSelectedViewController:exploreController];
}
- (void) rightTabPressed
{
rightButton.selected = YES;
leftButton.selected = NO;
[self setSelectedViewController:profileController];
}
-(void) addLeftButtonWithImage:(UIImage*)buttonImage highlightImage:(UIImage*)highlightImage
{
leftButton = [UIButton buttonWithType:UIButtonTypeCustom];
leftButton.adjustsImageWhenHighlighted = NO;
[[leftButton imageView] setContentMode: UIViewContentModeScaleAspectFit];
[leftButton setBackgroundImage:buttonImage forState:UIControlStateNormal];
[leftButton setBackgroundImage:highlightImage forState:UIControlStateHighlighted];
[leftButton setBackgroundImage:highlightImage forState:UIControlStateSelected];
leftButton.frame = CGRectMake(0.0, 367, 160.0, 49.0);
[leftButton addTarget:self action:#selector(leftTabSelectPressed) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:leftButton];
}
-(void) addRightButtonWithImage:(UIImage*)buttonImage highlightImage:(UIImage*)highlightImage
{
rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
rightButton.adjustsImageWhenHighlighted = NO;
[[rightButton imageView] setContentMode: UIViewContentModeScaleAspectFit];
[rightButton setBackgroundImage:buttonImage forState:UIControlStateNormal];
[rightButton setBackgroundImage:highlightImage forState:UIControlStateHighlighted];
[rightButton setBackgroundImage:highlightImage forState:UIControlStateSelected];
rightButton.frame = CGRectMake(160.0, 367, 160.0, 49.0);
[rightButton addTarget:self action:#selector(rightTabPressed) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:rightButton];
}
#end
For your Comment your code will be like this:
-(void) addRightButtonWithImage:(UIImage*)buttonImage highlightImage:(UIImage*)highlightImage
{
rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
rightButton.adjustsImageWhenHighlighted = NO;
rightButton.showsTouchWhenHighlighted = NO;
[[rightButton imageView] setContentMode: UIViewContentModeScaleAspectFit];
[rightButton setBackgroundImage:buttonImage forState:UIControlStateNormal];
[rightButton setBackgroundImage:highlightImage forState:UIControlStateHighlighted | UIControlStateSelected];
[rightButton setBackgroundImage:highlightImage forState:UIControlStateSelected];
rightButton.frame = CGRectMake(160.0, 367, 160.0, 49.0);
[rightButton addTarget:self action:#selector(rightTabPressed) forControlEvents:UIControlEventTouchUpInside];
UILongPressGestureRecognizer *longGesture = [[[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longGestureDetected:)]autorelease];
longGesture.delaysTouchesBegan = YES;
[rightButton addGestureRecognizer:longGesture];
[self.view addSubview:rightButton];
}
- (void)longGestureDetected:(UILongPressGestureRecognizer*)longGesture
{
if(longGesture.state == UIGestureRecognizerStateBegan)
[self rightTabPressed];
}
Trick seemed to be changing UIControlStateHighlighted to UIControlStateHighlighted | UIControlStateSelected. Seems odd, but it works.
UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeCustom];
[btn1 setImage:[UIImage imageNamed:#"restaurant.png"] forState:UIControlStateNormal];
UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeCustom];
[btn2 setImage:[UIImage imageNamed:#"restaurant1.png"] forState:UIControlStateNormal];
if([scaleStr isEqualToString:#"0.139738"]){
btn1.frame = CGRectMake(330,145,5,5);
[imageScrollView addSubview:btn1];
} else if ([scaleStr isEqualToString:#"0.209607"]) {
[btn1 removeFromSuperView];
btn2.frame = CGRectMake(495,217.5,10,10);
[imageScrollView addSubview:btn2];
}
i have set the button when doubletap the background image in UIScrollview.If i double tap second time , the first button also show.I need to remove the button which i created first .
Also i remove the btn1 in next condition.
Kindly help me regarding on this.
A little bit of context might help here, but my guess is that you're really just creating a new button each time and not holding a reference to the old one. So when you call removeFromSuperView on the second tap, you're removing a button that hasn't even been added to the view, not the one you added on your last pass. Try making your buttons instance variables instead of local. In extremely loose pseudo-code:
#interface MyClass : UIView {
UIButton *btn1;
UIButton *btn2;
}
#implementation MyClass {
-(MyClass *) init {
self = [super init];
[self setupButtons];
return self;
}
-(void) setupButtons {
btn1 = [UIButton buttonWithType:UIButtonTypeCustom];
[btn1 setImage:[UIImage imageNamed:#"restaurant.png"] forState:UIControlStateNormal];
btn2 = [UIButton buttonWithType:UIButtonTypeCustom];
[btn2 setImage:[UIImage imageNamed:#"restaurant1.png"] forState:UIControlStateNormal];
}
-(void) myFunction {
[btn1 removeFromSuperView];
[btn2 removeFromSuperView];
if([scaleStr isEqualToString:#"0.139738"]){
btn1.frame = CGRectMake(330,145,5,5);
[imageScrollView addSubview:btn1];
} else if ([scaleStr isEqualToString:#"0.209607"]) {
btn2.frame = CGRectMake(495,217.5,10,10);
[imageScrollView addSubview:btn2];
}
}
}