Show an image in a UIButton on long press gesture - ios

I have the following problem. I have a UIScrollView on which I have a couple of buttons with icons set as images on these buttons. I have a long press recognizer attached to each button. How can I show a smaller delete icon on the sender button on long press gesture? My goal is to create the behaviour that is presented by iOS when the user wants to delete a specific application.
This is the code for a buttons (with images):
//set the button with the image of conference here.
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(3, 3, w-5, h-5);
CALayer * l = [button layer];
[l setMasksToBounds:YES];
[l setCornerRadius:8.0];
[button setImage:thumb forState:UIControlStateNormal];
button.property = confInfo;
[button addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
button.tag = i;
bView.tag = i;
//Add gesture recognizer to be used for deletion of conference.
UILongPressGestureRecognizer *pahGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressGestureRecognizerStateChanged:)];
pahGestureRecognizer.minimumPressDuration = 1.0;
[button addGestureRecognizer:pahGestureRecognizer];
This code is in a cycle (see i in the code). My long tap action is like this:
- (void)longPressGestureRecognizerStateChanged:(UIGestureRecognizer *)gestureRecognizer {
switch (gestureRecognizer.state) {
case UIGestureRecognizerStateEnded:
NSLog(#"Tapped!!!");
break;
default:
break;
}
}
How I can pass a button on which I clicked to this action to show the smaller X image on the right upper corner of the button ?

Your gesture recognizer should be attached to the UIButton via its view property.
case UIGestureRecognizerStateEnded:
NSLog(#"Tapped!!!");
[((UIButton*)gestureRecognizer.view) setImage:thumbWithX forState:UIControlStateNormal];
break;

Related

Exclude specific area for long tap recognizer

I have a method that add button on top-left of my collection view cell, and longPress recognizer. The problem is, when i set longPressRecognizer minimumPressDuration to something like 0.0001, i cant tap a button, because, instead of tapping button activates longPressRecognizer method. Please take a look:
UIButton *button = [UIButton buttonWithType:UIButtonTypeContactAdd];
[[RACObserve(self, shouldEdit) deliverOnMainThread] subscribeNext:^(id x) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeContactAdd];
if (self.shouldEdit){
self.layout.longPressGestureRecognizer.minimumPressDuration = 0.1;
int ind = indexPath.row;
NSLog(#"1 blk called");
button = [UIButton buttonWithType:UIButtonTypeContactAdd];
[button addTarget:self
action:#selector(aMethod:)
forControlEvents:UIControlEventTouchUpInside];
[button setTag:indexPath.row];
[cell addSubview:button];
[button mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(cell.mas_left).with.offset(0);
make.top.equalTo(cell.mas_top).with.offset(0);
make.width.height.equalTo(#(20));
}];
}
I use reactive cocoa and masonry, but this actually doesn't matter, what i want is exclude button area from area, that i can use for longGestureRecognizer.
self.layout.longPressGestureRecognizer.minimumPressDuration = 0.1;
you can use self.myview.longPressGestureRecognizer.minimumPressDuration = 0.1; and in myview don't place button in myview.by this you can able to tap button

Popover for button created via code for long press

I know how to create popovers if my button added to story board, but how can I create popover if my button created via code.
UIButtonS *button = [UIButtonS buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(siteButtonPressed:)forControlEvents:UIControlEventTouchUpInside];
[button setTitle:string1 forState:UIControlStateNormal];
button.frame = CGRectMake(XLocatioan, YLocation, 90, 30);
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleLongPress:)];
longPress.minimumPressDuration = 1.0;
[button addGestureRecognizer:longPress];
[self.view addSubview:button];
- (void)handleLongPress:(UILongPressGestureRecognizer*)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
}
else if (sender.state == UIGestureRecognizerStateBegan){
//create popover for button
}
}
You are already doing it right, but you are overthinking. There is no need to check the state of the gesture recognizer. If the target function has been triggered, it means that the user has done a long press. Also, note that not all of the values of the property state may be supported. As the documentation says: Some of these states are not applicable to discrete gestures.
So your code should look like this (unless you want to implement dragging or something similar):
UIButtonS *button = [UIButtonS buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(siteButtonPressed:)forControlEvents:UIControlEventTouchUpInside];
[button setTitle:string1 forState:UIControlStateNormal];
button.frame = CGRectMake(XLocatioan, YLocation, 90, 30);
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleLongPress:)];
longPress.minimumPressDuration = 1.0;
[button addGestureRecognizer:longPress];
[self.view addSubview:button];
- (void)handleLongPress:(UILongPressGestureRecognizer*)sender {
//create popover for button
}
If your target is iOS 6+ you should use a UIPopoverController to create the popover, otherwise use UIAlertView.

Change properties of programmatically created UIButton in a different IBAction

I have one method that creates a number of UIButton instances programmatically and positions them in the view. Another IBAction needs to change the background colour of one of these UIButton when fired however when I try to action it, it tells me that the Property not found on object of type UIView *
The button is created using:
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
[view addSubview:button];
When I try to access it from the other IBAction like:
button.backgroundColor = [UIColor blackColor];
It fails with the error noted above.
Any help is much appreciated. I saw another answer which suggested to create an array as an IBOutlet and access it that way but I'm wondering if there's another way.
Thanks!
declare this button in globally and identify each button in tag, just like or assume this
UIButton * button, *button2; // declare in your view controller.h
- (IBAction)butaction:(id)sender; //this is your color change method;
in your view controller.m wherever u add this button
button = [UIButton buttonWithType:UIButtonTypeCustom];
button.tag=10; //this is important
[self.view addSubview:button];
button1 = [UIButton buttonWithType:UIButtonTypeCustom];
button1.tag=20; //this is important
[self.view addSubview:button1];
//here ur color change method
- (IBAction) butaction:(UIButton*)sender {
switch (sender.tag)
{
case 10:
[button setBackgroundColor:[UIColor blackColor]];
break;
case 20:
[button1 setBackgroundColor:[UIColor blackColor]];
break;
default:
break;
}
}
Try this, it may be helpful
for (int index=1; index<=5; index++) {
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:#selector(ButtonClickedFunction:) forControlEvents:UIControlEventTouchUpInside];
button.tag= index;
[view addSubview:button];
};
implement this in IBAction
-(IBAction)ButtonClickedFunction:(UIButton *)button{
button.backgroundColor = [UIColor blackColor];
}
Note: In this I have created 5 buttons but not set frame. Please set frame according to your requirements.
Thanks

UIButton does not change background on touchUpInside

I have some custom type UIButtons placed pragmatically in a custom view. The view is basically a menu. I am generating the buttons with the following code, inside the view's .m file:
-(void) generateButtons: (NSMutableArray *) buttonsArray
{
UIImage *barItemImage = [[UIImage imageNamed:#"ipad-menubar-button.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
float buttonWidth = (self.frame.size.width - (2 * FIRSTBUTTONXCOORDINATE) - 25)/ 6.0f;
float xCoord = FIRSTBUTTONXCOORDINATE;
float yCoord = (self.frame.size.height - BUTTONHEIGHT) / 2.0f;
for (int i = 0; i < buttonsArray.count; i++)
{
NSString* buttonTitle = [buttonsArray objectAtIndex:i];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self
action:#selector(botButtonAction:)
forControlEvents:UIControlEventTouchUpInside];
[button setTitle:buttonTitle forState:UIControlStateNormal];
button.frame = CGRectMake(xCoord, yCoord, buttonWidth, BUTTONHEIGHT);
button.tag = i;
[button setBackgroundImage:barItemImage forState:UIControlStateNormal];
xCoord += buttonWidth + 5;
[self addSubview:button];
}
}
On touchUpInside, botButtonAction is called and it does what it is supposed to. However, the buttons do not usually give any visual indication of the touchUpInside. When I touchDown on a button and swipe in any direction, then I see the background color get darker. Sometimes, I see the same visual indication on touchUpInside. It seems completely random though.
Any ideas as to what I might be doing wrong here?
Edit: Sorry, I got occupied with other issues. Here is the code for botButtonAction and the method it calls
-(void) botButtonAction: (UIButton *) sender
{
if (self.delegate)
[self.delegate optionsMenuAction:self data:sender.tag];
}
-(void)optionsMenuAction:(OptionsMenueView *)view data:(int)tag
{
if (self.PDFVC)
{
[self.navigationController popToViewController:self animated:YES];
}
if (!self.optionsMenue.isAtWPC || tag != WPC)
[self transitionFromViewAtIndex:self.selectedVCIndex toView:tag];
else
[self transitionFromViewAtIndex:self.selectedVCIndex toView:WPList];
}
But since I am using touchUpInside, these methods don't get called on touchDown. I just want the button to be highLight (grayout the bg a little) on touchDown. As I state before, that happens on touchDown and swipe.
Edit
I had so far been running this on actual devices (iPad air and iPad 2). When I tried running it on the simulator, I get the correct result. On mouse click, the button gets highlighted.
Edit
I think I figured out the exact problem (still looking for a solution). If I touchDown precisely on the button and the touch does not cover any part of the insets, then the highlighting works. However, if the touch covers part of the button and also part of the insets/outside, then the highlighting doesn't work.
add this line:
[button setBackgroundImage:HighlightImage forState:UIControlStateHighlighted];
change the title colour when tap on the button like this
[yourButon setTitleColor:[UIColor colorYouWant] forState:UIControlStateHighlighted];
hope this will help you......
put this code in botButtonAction:
-(void)botButtonAction:(UIButton *)sender
{
[sender setBackgroundImage:[UIImage imageNamed:#"some iamge.png"]
forState:UIControlStateNormal];
}
or use the code below code in for loop
[button setBackgroundImage:[UIImage imageNamed:#"back_button_press.png"] forState: UIControlStateHighlighted];
or if you want to give some color then setcolour of button
I had this problem at some point too. These other answers will give you the result you seek normally. However.... You are using [UIButton buttonWithType:UIButtonTypeCustom].. Which is really buggy if you do not alloc/init the UIButton.. Try changing this line to a normal button allocation and then add the following lines of the answers in this post. This should work for you.
So in short,
replace [UIButton buttonWithType:UIButtonTypeCustom];
with [[UIButton alloc] init];
And then add the following changes to your code to change the image.
[myNewlyAllocatedButton setBackgroundImage:[UIImage imageNamed:#"back_button_press.png"] forState: UIControlStateHighlighted];

Dynamically added buttons covering each other in iOS

I'm working on an iOS app (my first - I've been a .NET developer for a very long time).
I'm setting up a dynamically added button - everything works great, except the buttons I'm trying to create are covering each other.
Any thoughts on how to dynamically add buttons and change their positions? (In ASP.NET I'd add a placeholder and controls...but in iOS, that's not an option)
Code:
UIButton btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn addTarget: self action:#selector(loadQuestion:) forControlEvents:UIControlEventTouchUpInside;
[btn setTitle:#"My Button" forState:UIControlStateNormal];
btn.frame = CGRectMake(350.0,750.0,160.0,40.0);
[self.view addSubView:btn];
Dont use same X-cordinates for all buttons. See the below code
-(void)addSixButtons{
float xCord = 5.0;
for(int itemIndex = 1; itemIndex < 7; itemIndex++){
UIButton myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[myButton addTarget: self action:#selector(loadQuestion:) forControlEvents:UIControlEventTouchUpInside;
[myButton setTitle:#"My Button" forState:UIControlStateNormal];
myButton.frame = CGRectMake(xCord,750.0,160.0,40.0);
myButton.tag = itemIndex;
[self.view addSubView:myButton];
xCord += 165.0;
}
}
-(void)loadQuestion:(id)sender{
UIButton *btnClicked = (UIButton *)sender;
switch(btnClicked.tag){
case1:
//clicked first button
break;
case2:
//clicked second button
break;
default:
break;
}
}
Here, issue with your code is that you are specifying same frame for the buttons CGRectMake(350.0,750.0,160.0,40.0)
you need to change the x position of the button if you want them to align horizontally and can change y posyion if you want to align them vertically.
In iPhone, positions are specified by frame CGRectMake(x,y,width,height). So, specify different x and y values as per reuirement and can also increment that values if you are using loops.

Resources