I created a button programmatically:
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
myButton.frame = CGRectMake(290, 120, 40,20); // position in the parent view and set the size of the button
[myButton setTitle:#"Back" forState:UIControlStateNormal];
// add targets and actions
[myButton addTarget:self action:#selector(backLogin:) forControlEvents:UIControlEventTouchUpInside];
// add to a view
[myButton setAlpha:0];
[self.view addSubview:myButton];
Now I would like to hide this button again using another method and use animation to make the button fade away (!).
Obviously, I cannot use the variable myButton again and I don't want to make the variable global. Removing the Subview from the layer won't animate I guess. Do you have an idea? I can't make it to work... Thanks!
I don't think you're going about this the right way, but first of all, you're adding an invisible button to your view. Assuming you meant to add the button with an alpha of 1, here we go.
Fist of all, set a tag for the button:
myButton.tag = 1;
Any will do, as long as you're not using that tag for something else.
Next in your other method we can iterate through the subviews in your view controller and we can find the view with the tag of 1, and set it's alpha to 0 with a nice fade effect:
for (UIButton *button in self.view.subviews) {
if (button.tag == 1) {
[UIView animateWithDuration:2.0 animations:^ {
button.alpha = 0;
}];
}
}
However, this is really a bad way to go about it, and I would highly suggest just creating an instance variable.
Related
I'm having a bit of trouble with the action on my UIButtons. I'm creating 4 buttons programmatically but I'm not able to get the TouchUpInside event to fire.
I've had a read through SO but I'm still having trouble so any pointers will be greatly appreciated!
Here's the code where I create and set the button and it's action:
UIButton *btn;
float newWidth = 10;
for (int i = 0; i < _btnImages.count; ++i) {
btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
CGRect imageFrame = CGRectMake(/*X*/newWidth, /*Y*/height - 80, 65, 65);
btn.frame = imageFrame;
btn.tag = i;
[btn setBackgroundImage:[UIImage imageNamed:[_btnImages objectAtIndex:i]] forState:UIControlStateNormal];
[btn addTarget:self
action:#selector(btnSelected:)
forControlEvents:UIControlEventTouchUpInside];
[btn setEnabled:true];
[self addSubview:btn];
newWidth = newWidth + 75;
}
and here is the btnSelected method:
-(void)btnSelected:(UIButton *)button
{
NSLog(#"Button %ld Clicked",(long int)[button tag]);
}
The code you have shown is okay.
The possible problems are:
You are adding the buttons into a view that has user interaction disabled (or any of its ancestor has user interaction disabled).
Your buttons are clipped by their superview. Make sure your buttons are inside the bounds of their superview (and the superview is inside the bounds of its superview etc.).
Other issues can happen when there are gesture recognizers on your views - they can delay & cancel touches in the subviews, including buttons. Make sure the touch event is not handled by some gesture recognizer.
also UIControlEventTouchUpInside is fired when u release the button from inside the bounds of the button... it can be a little tricky concept but if you press the button, and release from outside the bounds of the button, this control event will not trigger.
UIControlEventTouchUpInside
A touch-up event in the control where the finger is inside the bounds of the control.
Available in iOS 2.0 and later.
Declared in UIControl.h.
I have a UITableView and it is populated with information, detailed information and images for each cell. I also have it so when a cell is selected it brings the user to a detailed view. What I am trying to accomplish is how to tell the difference between when the user clicks a cell or the image in the cell.
I would like to display a small subview that when the user clicks a image in a cell the small sub view will stay in the original frame but give the user something else to interact with.
I have looked all around and can not seem to even find a simple explanation or somewhere to start. It is done with apps such as facebook and twitter, where in a table view you see the users profile picture and you can click this instead of the actual cell ....
Any information would be great thanks!
Thank you #Nekno I have started to attempt to try to implement this method and have a few questions if you dont mind clearing up or giving your opinion.
Here is what I have wrote so far
// Here we use the new provided setImageWithURL: method to load the web image with
//SDWebImageManager
[cell.imageView setImageWithURL:[NSURL URLWithString:[(Tweet*)[avatarsURL
objectAtIndex:indexPath.row]avatarURL]]
placeholderImage:[UIImage imageNamed:#"avatar.png"]];
//create the button
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setBackgroundImage:[NSURL URLWithString:[(Tweet*)[avatarsURL
objectAtIndex:indexPath.row]avatarURL]] forState:UIControlStateNormal];
//the button should be as big as the image in tableView
[button setFrame:CGRectMake(10, 10, 45, 45)];
//set the type of action for the button
[button addTarget:self action:#selector(imageSubViewAction:)
forControlEvents:UIControlEventTouchUpInside];
//more stuff
return cell }
Then I use this action that I specified in the #selector above
-(IBAction)imageSubViewAction:(id)sender{
[UIView beginAnimations:#"animateView" context:nil];
[UIView setAnimationDuration:0.5];
CGRect viewFrame = [subView frame];
viewFrame.origin.x += -300;
subView.frame = viewFrame;
subView.alpha = 1.0;
[self.view addSubview:subView];
[UIView commitAnimations];
So I know I will have to add an action to dismiss the subView but first things first.
This seems not to have any affect on the cells at all so far and I am not sure what step I would take next to make it functional.
Does the gesture method completely disable the function of didselectindexrow? because I would like to have both.
It seems as though this method with just adding a button within the cell and giving that button a action should work but I am a little lost to where to continue my journey.
Thank again I highly appreciate the help!
}
I think the easiest way would be to add a UIButton as the subview, and add your image as the background view for the UIButton, either through Interface Builder or by creating a UIImage.
Then you can hook up an event handler to the Touch Up Inside outlet that will handle the button tap.
With the UIButton, the UITableView cell selection shouldn't fire. If for some reason you're finding that the table cell is getting selected when the user touches the button, you could use a UIImageView instead of a UIButton, and then add a gesture recognizer to the UIImageView that handles the touches on the image and cancels the table cell selection.
To add the gesture recognizer to the UIImageView and cancel the touches for the UITableView:
Note: imageView is a local variable that references your UIImageView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//...
// by default, UITapGestureRecognizer will recognize just a tap.
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
gestureRecognizer.cancelsTouchesInView = YES; // cancels table view cell selection
[imageView addGestureRecognizer:gestureRecognizer];
[gestureRecognizer release];
//...
}
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer {
// get the imageView that was tapped
UIImageView* imageView = gestureRecognizer.view;
// do something else
}
Here is how I accomplished this for anyone who is looking for an answer you can use this at will!
//create the button
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[cell addSubview:button];
[cell bringSubviewToFront:button];
button.backgroundColor = [UIColor clearColor];
//[button setBackgroundImage:[UIImage imageNamed:#"cellbutton.png"]
//forState:UIControlStateNormal]; //sets the image
[button setImage:[UIImage imageNamed:#"cellButton.png"]
forState:UIControlStateHighlighted]; //sets the highlighted image
//the button should be as big as the image in tableView
[button setFrame:CGRectMake(10, 25, 50, 50)];
//set the type of action for the button
[button addTarget:self action:#selector(detailSubView:)
forControlEvents:UIControlEventTouchUpInside];
In an iPhone app I am working on, I need to place buttons in a UIScrollView, but because of the fact that I need to place so many buttons to scroll through, I cannot place them in interface builder. Therefore I am having to put them all in the Scroll View through my code. How can I create a button in code, and then use it to trigger an action.
See "How do I create a basic UIButton programmatically". See also the Target / Action mechanism.
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//position button
myButton.frame = CGRectMake(50, 50, 50, 50);
[myButton setTitle:#"Click" forState:UIControlStateNormal];
// add targets and actions
[myButton addTarget:self action:#selector(myButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
// add to a view
[self.view addSubview:myButton];
Further information here
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIButton_Class/UIButton/UIButton.html
I want to change the image on UIButton, when User presses that button. So, I wrote
btnthumbnail2 setImage:[UIImage imageNamed:#"leaderboard_ov.png"] forState:UIControlStateNormal];
and after that I changed the view.
The image is changing but not display the changed image.I think the controll goes to next view tha's why it is happening. But I want to show the change, How can I do this?? Plz help me for this..
I am using Interface Builder, in which I added a UIButton to the view.
I defined the button selected by default and selected my image for the selected state (Use drop-down list in Inspector window to choose "Selected State Configuration" before selecting the image).
Create an IBAction in the controller and connect the button to that action.
Then see the code below:
-(IBAction) toggleUIButtonImage:(id)sender{
if ([sender isSelected]) {
[sender setImage:unselectedImage forState:UIControlStateNormal];
[sender setSelected:NO];
} else {
[sender setImage:selectedImage forState:UIControlStateSelected];
[sender setSelected:YES];
}
}
This is the simplest way that I am doing it and it works every time
-(void)buttonTouched:(id)sender
{
UIButton *btn = (UIButton *)sender;
if( [[btn imageForState:UIControlStateNormal] isEqual:[UIImage imageNamed:#"icon-Locked.png"]])
{
[btn setImage:[UIImage imageNamed:#"icon-Unlocked.png"] forState:UIControlStateNormal];
// other statements
}
else
{
[btn setImage:[UIImage imageNamed:#"icon-Locked.png"] forState:UIControlStateNormal];
// other statements
}
}
You can use other similar checks for other states such as SELECTED, ENABLED, HIGHLIGHTED.
The code you have there should work fine, but I'm guessing that the button image doesn't appear changed until the next run through the event loop, so you don't see it before the view gets switched out.
It's kind of a hack, but you could try delaying the view change just slightly so that the button will update.
So instead of this:
[btnthumbnail2 setImage:[UIImage imageNamed:#"leaderboard_ov.png"] forState:UIControlStateNormal];
[self showMyOtherView];
Try this:
[btnthumbnail2 setImage:[UIImage imageNamed:#"leaderboard_ov.png"] forState:UIControlStateNormal];
[self performSelector:#selector(showMyOtherView) withObject:self afterDelay:0.01];
To change the image for the selected state you have to call setImage for state UIControlStateSelected. You can set separate images for different states (Normal, Highlighted, Disabled, Selected, etc).
If you want to change the image when the button is clicked, this way, works perfectly:
-(IBAction)buttonClicked: (id)sender
{
UIButton *buttonObj = (UIButton*)sender;
[buttonObj setBackgroundImage:[UIImage imageNamed:#"myImage.png"]
forState:UIControlStateNormal];
}
The simplest way to accomplish this is to simply set the highlighted image in Interface Builder.
Building on Nicsoft's answer.
-(void)viewDidLoad {
[super viewDidLoad];
[self.button setImage:[UIImage imageNamed:#"unselectedImageName"] forState:UIControlStateNormal];
[self.button setImage:[UIImage imageNamed:#"selectedImageName"] forState:UIControlStateSelected];
}
-(IBAction)toggleButton:(UIButton *)sender {
sender.selected = !sender.selected;
// Add logic here
}
I wrote code that does exactly this last night, and I didn't have to resort to any strange delaying tactics. In this particular case, I'm doing it from inside a tableViewCell. This is more code than you asked for, but it shows the whole process I used. As you can see, I chose not to have any special image for the period of time DURING a button touch.
// Button set up, inside cellForRowAtIndexPath:
// imageFrame is just the rect that you want the button to occupy
[self setFavorite:[[UIButton alloc] initWithFrame:imageFrame]];
[[self favorite] addTarget:self action:#selector(toggleFavorite:)
forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:[self favorite]];
[self draw];
// definition of the callback specified above
- (void) toggleFavorite:(id) sender {
if (favoriteState == 0 ){
favoriteState = 1;
} else {
favoriteState = 0;
}
[self draw];
}
// the draw method, to set the images
// favOn and favOff are statically defined at the top of the class
- (void) draw {
if (favoriteState != 0) {
[[self favorite] setBackgroundImage:favOn forState:UIControlStateNormal];
[[self favorite] setBackgroundImage:favOn forState:UIControlStateHighlighted];
} else {
[[self favorite] setBackgroundImage:favOff forState:UIControlStateNormal];
[[self favorite] setBackgroundImage:favOff forState:UIControlStateHighlighted];
}
}
Hate to add to the plethora of answers, but:
Select images in IB for the button's default and selected states.
Connect an IBAction and keep it simple.
#IBAction func buttonTapped(sender: UIButton){sender.selected = !sender.selected}
Done.
I thought to be clever and just put an transparent UIButton over an UIImageView with the exact frame size, so that I can wire it up easily with any event I like, for example TouchUpInside, and make it call a action method of an view controller when the user touches it. Well, it works until alpha is below 0.1f. If I do 0.01f, it will not work. So to get it work, when looking a long time on the screen, you'll see that 0.1f of alpha shining through. And that's totally disgusting ;)
It seems like iPhone OS trys to be clever and won't catch events on the button if it's visually not there. Any idea how to solve that?
Sure I could make a subclass of UIImageView and implement touchesBegan:... etc., but it doesn't feel really elegant. I mean...when I want to hyperlink an image on the web, I would never want create my own HTML element for that image, just to wire it up to an url when it's clicked. That just doesn't make a lot of sense to me.
You should be able to set the button's 'Type' to Custom in Interface Builder, and it will not display any text or graphical elements over the UIImageView. This way, you don't need to adjust the alpha. If the view is built from code, use:
button = [UIButton buttonWithType:UIButtonTypeCustom];
In addition to UIButtonTypeCustom, I set the button text colors to the following:
[button setTitleColor:[UIColor clearColor] forState:UIControlStateNormal];
[button setTitleShadowColor:[UIColor clearColor] forState:UIControlStateNormal];
[button setTitleColor:[UIColor clearColor] forState:UIControlStateHighlighted];
[button setTitleShadowColor:[UIColor clearColor] forState:UIControlStateHighlighted];
The best way of doing this is:
myButton.hidden = YES;
You can't use the buttonType property because it is a read only property. Only way to use it is when creating your button dynamically.
i also beleive you can assign an image to a button.
The image can take up the entire frame and can also have no other artifacts of the buttone if you set it up right.
check out the Property
UIButtonInstance.currentImage
That way you are not hogging your resources with elements that are essentially already there.
You can hide a button (or any object) and keep it active by adding a mask to its layer. The button will be invisible but will still catch events.
let layer = CAShapeLayer()
layer.frame = .zero
myButton.layer.mask = layer
Jasons answer above is nearly correct, but setting the button type is not possible. So to programmatically create an empty button, use this code:
UIButton* myButton = [UIButton buttonWithType:UIButtonTypeCustom];
myButton.frame=frame;
[self.view addSubview:myButton];
This is what i did but with using a subclass of UIButton which i later found out should not be subclassed as per the net. My subclass was called Points
Points *mypoint=[Points buttonWithType:UIButtonTypeCustom];
then if you have an image you want to add to the button :
[mypoint setImage:imageNamed:#"myimage"] forstate: UIControlStateNormal];
if you dont add this image then the button will be invisible to the user but should respond to touch. Thats how i created a hotspot on my imageView inorder to have it respond to user interaction.
It's the only way I found...
[yourButton setImage:[UIImage imageNamed:#"AnEmptyButtonWithTheSameSize.png"] forState:UIControlStateNormal];
Take care of the image. It must be .png
Custom UIButtons respond to user interactions unless their alpha is set to 0. Put a custom UIButton on top of your imageView and connect to buttonPressed action. I have also set an additional highlighted image for my UIView, now it really behaves like a UIButton. First I have defined a duration for the UIView for staying highlighted:
#define HIGHLIGHTED_DURATION 0.1
Then set the image view highlighted if the button is pressed and start a timer to keep it highlighted for that duration. Do not forget to set the highlighted image for your imageview.
- (IBAction)buttonPressed:(id)sender {
[_yourImageView setHighlighted:YES];
_timer = [NSTimer scheduledTimerWithTimeInterval:HIGHLIGHTED_DURATION
target:self
selector:#selector(removeHighlighted)
userInfo:nil
repeats:NO];
}
And simply undo highlighting when the timer finishes:
-(void) removeHighlighted{
_yourImageView.highlighted = NO;
}
lazyImageView = [[UIImageView alloc] init];
button=[[UIButton alloc]init];
[UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(aMethodForVideo:)
forControlEvents:UIControlEventTouchUpInside];
[button setBackgroundImage:[UIImage imageNamed:#"BackTransparent.png"] forState:UIControlStateHighlighted];
[button setTitle:#"" forState:UIControlStateNormal];
lazyImageView.frame=CGRectMake(x, y, w, h);
button.frame=CGRectMake(x, y, w, h);
Set frame of button and Image both have same frame .I use this code and working fine.Also set button background image forState:UIControlStateHighlighted so when you click on that when you see the click effect.
I managed to do it using the following code.
If the iPad is landscape the button will be located in the top right of the screen.
UIButton *adminButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
adminButton.frame = CGRectMake(974.0f, 0.0f, 50.0f, 50.0f);
[adminButton setBackgroundColor:[UIColor clearColor]];
[adminButton setTag:1];
[adminButton addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:adminButton];
Pressing the 'adminButton' will run the following function:
- (void)buttonPressed:(id)sender {
int buttonId = ((UIButton *)sender).tag;
switch(buttonId) {
case 1:
NSLog (#"Admin button was pressed");
break;
case 2:
//if there was a button with Tag 2 this will be called
break;
default:
NSLog(#"Key pressed: %i", buttonId);
break;
}
}