Show touch when clicked UIButton Objective-C - objective-c

I have a UIButton that has only an UIImage set, when Clicked (long press) the images changes automatically with a shadow, What I want is that even if the button gets clicked but not with a long press the images should have the shadow. I already tried from IB to set the UIButton properties Reverse on Highlight and Shows Touch On Highlight but with no results

This is about UIControl Class. It's default to be with shadow. So if you wanna customize it, you should addTarget to your button to every action on UIButton like tapping,long press,touchUpInside and I think it s not about long press it's just you can't realize the difference on tapping.
in one of my project I customize my button actions like this:
buyButton = [[UIButton alloc] initWithFrame:CGRectMake(self.frame.size.width*3/4-2, 0, self.frame.size.width/4+4, self.frame.size.height)];
[buyButton addTarget:self action:#selector(buyButtonClicked:) forControlEvents:UIControlEventTouchDown];
[buyButton addTarget:self action:#selector(buyButtonNormal:) forControlEvents:UIControlEventTouchUpInside];
[buyButton addTarget:self action:#selector(buyButtonNormal:) forControlEvents:UIControlEventTouchUpOutside];
and methods of this like:
- (void) buyButtonClicked:(UIButton *) sender {
if ([self.backgroundColor isEqual:[Util UIColorForHexColor:#"fede32"]]) {
self.backgroundColor = [Util UIColorForHexColor:#"fdca2e"];
}
else if([self.backgroundColor isEqual:[Util UIColorForHexColor:#"cfd3dc"]]) {
self.backgroundColor = [Util UIColorForHexColor:#"c0c5d0"];
}
}
- (void) buyButtonNormal:(UIButton *) sender {
if ([self.backgroundColor isEqual:[Util UIColorForHexColor:#"fdca2e"]]) {
self.backgroundColor = [Util UIColorForHexColor:#"fede32"];
}
else if([self.backgroundColor isEqual:[Util UIColorForHexColor:#"c0c5d0"]]) {
self.backgroundColor = [Util UIColorForHexColor:#"cfd3dc"];
}
[delegate purchaseOffer:selectedOffer];
}
If you need more information about UIButton actions there are a lot of question on this site.

Related

UIButton does not detect touch events when clicked

I've created a tableview that has custom cells (I've subclassed UITableViewCell).
I'm creating several UIButtons in it. Declaring this in the .h file:
#property (nonatomic, strong) UIButton *myButton;
and this in the .m file:
myButton = [[UIButton alloc] initWithFrame:CGRectMake(-100.0, 285.0, 60.0, 30.0)];
myButton.titleLabel.font = [UIFont boldSystemFontOfSize:16.0];
myButton.backgroundColor = [UIColor clearColor];
[myButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[myButton setTitle:#"text" forState:UIControlStateNormal];
[myButton addTarget:self action:#selector(myButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.contentView addSubview:myButton];
I'm moving the cell to the right using UIPanGestureRecognizer and then the UIButton is revealed (notice that it is in a negative X index).I can see it but it is not clickable (I guess it is not in the view any more).
Any suggestion about how to make it clickable?
More details:
In the init of the cell, I'm doing:
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanGesture:)];
panGesture.delegate = self;
[self.contentView addGestureRecognizer:panGesture];
Then I implemented the gesture:
-(void)handlePanGesture:(UIPanGestureRecognizer *)sender {
CGPoint translate = [sender translationInView:self.contentView];
CGRect currentFrame = self.contentView.frame;
switch ([sender state]) {
case UIGestureRecognizerStateChanged:
currentFrame.origin.x = translate.x;
self.contentView.frame = currentFrame;
break;
default:
break;
}
}
When the frame moves to the right - the button is revealed. But not clickable...
If a button's frame is outside that of its parent's frame, it will not register touches. In this case, you mention that your button stops working when its frame's x location is set to -100. This makes sense because it is outside the touch area.
Your pan gesture you implemented moves the cell's view, so while the button may appear on screen, it is still OUTSIDE of the cell's view, hence it cannot receive touches.
One possible suggestion for fixing this would be to make your cells bigger from the start. So for example, if a cell's frame size is currently 0,0,320,44, you could instead make it -100,0,420,44 and place the contents of your cell accordingly. Now, your button's frame would change to 0,0,x,y and it would be inside of the cell's view and able to receive touches.

Capture dynamic button tap ios

I have button created programmatically in the UIImageView. This view was also created programmatically. When image in this view is tapped the button is created, now I want to capture when this button is tapped but I'm unable to here is my relevant code :
- (void)imageTapped:(UIGestureRecognizer *)sender{
MyImageView *myView = (MyImageView *)sender.view;
NSLog(#"Image tapped is => %#", myView.currentImageName);
//add button to view
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self
action:#selector(pressedPlay:)
forControlEvents:UIControlEventTouchDown];
//button image
UIImage *backgroundImage = [UIImage imageNamed:[NSString stringWithFormat:#"playbutton.png"]];
button.frame = CGRectMake(85.0, 175.0, backgroundImage.size.width, backgroundImage.size.height);
myView.userInteractionEnabled = YES;
button.userInteractionEnabled = YES;
[button setImage:backgroundImage forState:(UIControlStateNormal)];
[myView addSubview:button];
}
Now this code should handle the tap but for some reason it doesn't :
- (void)pressedPlay:(UIGestureRecognizer *)sender{
//MyImageView *senderView = (MyImageView *) sender.view;
NSLog(#"%#", #"I Presed button");
}
Any reason why this is not working?
Your code suggests that you are using a UIGestureRecognizer (most likely a UITapGestureRecognizer) to detect the initial tap. The problem is that UIGestureRecognizer is being greedy and stopping the UIButton from receiving the touch.
You will need to do some shifting to disable the gesture recognizer after the initial detection and then reenable it after the play has been tapped.
UIGestureRecognizer has the property
#property(nonatomic, getter=isEnabled) BOOL enabled
or you can choose to implement UIGestureRecognizerDelegate and provide an implementation of
gestureRecognizer:shouldReceiveTouch:
a very simple attempt could look like:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
{
return ![touch.view isKindOfClass:[UIButton class]];
}
and don't forget to set the delegate on the gesture recognizer
myGesture.delegate = self;
set the button frame from:
button.frame = CGRectMake(85.0, 175.0, backgroundImage.size.width, backgroundImage.size.height);
to:
button.frame = CGRectMake(0,0, backgroundImage.size.width, backgroundImage.size.height);
it looks like you are setting button frame outside the imageview's frame and hence the button is not actually getting any interaction.
The Button frame is likely setting the button outside the bounds of the UIImageView, frames are always relative to the superviews coordinate in this case the UIImageView.
[button setExclusiveTouch:YES];

How to change the image of the button on click of the button in objective c

I have placed a pause button in UI, where when the user clicks the button, the image of button from pause image it has to change to the start image. I have placed both the start and the pause images in the bundle, I am able to do this,but when i click on start again , it should show pause image button,How to do this, the following is the code i am using,
-(IBAction)btnClked:(id)sender
{
[pauseButton setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateNormal];
UIButton *btn=(UIButton *)sender;
[btn setImage:[UIImage imageNamed:#"start.png"] forState:UIControlStateNormal];
}
You need a variable to keep track of that state change. A BOOL is fine.
But using your code, you can "abuse" the tag property of UIButton to tell if it's playing (tag == 1) or paused (tag == 0)
-(IBAction)btnClked:(id)sender {
UIButton *btn=(UIButton *)sender;
if (btn.tag == 1) {
btn.tag = 0;
[btn setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateNormal];
} else {
btn.tag = 1;
[btn setImage:[UIImage imageNamed:#"start.png"] forState:UIControlStateNormal];
}
}
You can use UIButton's selected state to do the same. For example, while initiating the button you have to define 2 images. One for normal state and other for selected state. When touch event of the button fired, you have to make it selected. If it is already selected you need to deselect it. This is much better, than maintaining additional variables to check selected state of the button. Also you could improve the performance with this approach.
Code example
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIButton *startButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 300, 60, 60)];
[startButton setBackgroundImage:[UIImage imageNamed:#"start.png"] forState:UIControlStateNormal];
[startButton setBackgroundImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateSelected];
[startButton addTarget:self action:#selector(modeButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:startButton];
}
- (IBAction)modeButtonClick:(id)sender {
UIButton *startButton = (UIButton *)sender;
[startButton setSelected:![startButton isSelected]];
}
If you are creating the button from story board or XIBs set the backgroud image for default state config and selected state config.

UIButton created runtime in a loop, now I need a specific function depending on the button touched

I am creating some buttons and putting them inside a UIScrollView like this:
int i = 0;
while (i != numberOfButtons ) {
int updatetY = 160*i;
CGRect buttonFrame = CGRectMake(updatetY, 0, 160, 60);
UIButton *button = [[UIButton alloc] initWithFrame:buttonFrame];
UIImage *buttonImage = [UIImage imageNamed:#"bg.png"];
[button setBackgroundImage:buttonImage forState:UIControlStateNormal];
[button setTitle:[buttonsArray objectAtIndex:i] forState:UIControlStateNormal];
[button addTarget:self action:#selector(MYPROBLEM) forControlEvents:UIControlEventTouchUpInside];
[menuScrollView addSubview:button];
i++;
}
Now I need to build a method to capture which button is being touched, and run a specific bunch of code (see (MYPROBLEM).
Anybody knows what I can do to "trace" which button is being touched and then run a specific function?
something like:
-(void) buttonfunction
{
case ...
doThis
case...
doThat
}
thanks in advance.
You need to use the tag property of the uibutton control. It's a numeric id for the button. You can set a tag on the button based on the i variable in your loop, for instance:
button.tag=i;
Then in your button's action message, you would simply add the id of the button as a parameter and check its tag like so:
-(void) buttonFunction:(id)sender {
switch (sender.tag)
{
//code goes here
}
}
Hope this helps.

How can I create a ToggleButton in Obj-C? Skin the UISwitch or subclass the UIButton? [duplicate]

Is there either a way to implement UISwitch with custom graphics for the switch-states?
Or as an alternative the other way round, an UIButton with UISwitch functionality?
UIButton already supports a "switch" functionality.
Just set a different image in Interface Builder for the "Selected State Configuration", and use the selected property of UIButton to toggle its state.
set the image to show on selected state:
[button setImage:[UIImage imageNamed:#"btn_graphics"] forState:UIControlStateSelected];
and then on touch up inside selector, set:
button.selected = YES;
if you want this to cancel another button's selection, set:
otherButton.selected = NO;
To build on what PGB and nurne said above, after you set your states and attach a selector (event method) you would want to put this code in that selector.
- (IBAction)cost:(id)sender
{
//Toggle current state and save
self.buttonTest.selected = !self.buttonTest.selected;
/**
The rest of your method goes here.
*/
}
For programmatically inclined:
-(void) addToggleButton {
CGRect aframe = CGRectMake(0,0,100,100);
UIImage *selectedImage = [UIImage imageNamed:#"selected"];
UIImage *unselectedImage = [UIImage imageNamed:#"unselected"];
self.toggleUIButton = [[UIButton alloc] initWithFrame:aframe];
[self.toggleUIButton setImage:unselectedImage forState:UIControlStateNormal];
[self.toggleUIButton setImage:selectedImage forState:UIControlStateSelected];
[self.toggleUIButton addTarget:self
action:#selector(clickToggle:)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.toggleUIButton];
}
-(void) clickToggle:(id) sender {
BOOL isSelected = [(UIButton *)sender isSelected];
[(UIButton *) sender setSelected:!isSelected];
}