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.
In a tableviewcell I have a UISlider. If I move the slider knob, go back to my previous view, and then return back to the table view, the knob on the slider returned back to zero but I see a "ghosting" of the knob where I had previously moved the slider too.
I clear the context view on the slider object in cellForRowAtIndexPath: and reload the table in viewDidAppear.
Anyone know how to fix this? It's quite annoying. I put the slider code down below if that helps at all.
// Setup slider
CGRect sliderFrame = CGRectMake(15, 56, 230, 0);
UISlider *slider = [[UISlider alloc] initWithFrame:sliderFrame];
slider.clearsContextBeforeDrawing = YES;
[slider addTarget:self action:#selector(sliderUpdated:) forControlEvents:UIControlEventValueChanged];
[slider addTarget:self action:#selector(sliderStopped:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:slider];
[slider release];
I appreciate it! Thanks!
It is most likely that you are creating a new UISlider over the old UISlider which gives the ghosting effect.
Two possible solutions
Tag the UISlider when you add it to a cell.
Subclass UITableViewCell and add a UISlider to it's content view and keep a reference to it with an ivar.
To do 1 simply tag the UISlider when you add it to the contentView. Then when you get a cell again you try getting the view back first or you create it a fresh.
const int sliderViewTag = 99;
UISlider *slider = [cell.contentView viewWithTag:sliderViewTag];
if (!slider) {
CGRect sliderFrame = CGRectMake(15, 56, 230, 0);
slider = [[UISlider alloc] initWithFrame:sliderFrame];
slider.clearsContextBeforeDrawing = YES;
[slider addTarget:self action:#selector(sliderUpdated:) forControlEvents:UIControlEventValueChanged];
[slider addTarget:self action:#selector(sliderStopped:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:slider];
[slider release]; slider = nil;
}
Although 2 is a little more involved it is my preferred method but I am sure there are some great examples of how to do it. There is some great docs by Apple so check them out Table View Programming Guide specifically look at the section A Closer Look at Table-View Cells
I have view hierarchy as follows
MyViewController --> ScrollView(added via IB) --> ImageView (+ zooming there) ---> button added on image View(added via code)
imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"map.png"]];
[scroll addSubview:imageView];
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
myButton.frame = CGRectMake(660, 120, 40, 40);
[myButton setTitle:#"10" forState:UIControlStateNormal];
[myButton addTarget:self action:#selector(asiaPressed:) forControlEvents:UIControlEventTouchUpInside];
[myButton setEnabled:YES];
[imageView addSubview:myButton];
later on in view controller, i defined selector as
-(void) asiaPressed:(id)sender{
NSLog(#"asiaPressed clicked");
}
But it is never going inside selector..
Pls help...i guess it is very basic error..
Thanks in advance
UIImageView has userInteractionEnabled property set to NO by default so it (and its subviews) does not receive touch events. You need to set that property to YES manually:
...
imageView.userInteractionEnabled = YES;
...
P.S. You also mention gesture recognizer in question title, however have not posted any code with it - so if it present it may also cause the problems, but the problem is most likely is what I described above
I created UIButtons in UITableViewCell. It is displaying properly in iphone. But when I upgrade this app for iPad UIbuttons are shifted to right side and come out of the table's boundary . Here is my code
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeCustom];
[button2 setFrame:CGRectMake(47.0f, 100.0f, 16, 16.0f)];
[button2 setImage:[UIImage imageNamed:#"Delete.png"] forState:UIControlStateNormal];
[button2 addTarget:self action:#selector(delete:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:button2];
return cell;
You should probably add the button to the cell's contentView, and not to the cell directly.
You might also want to place the button's frame origin relative to the contentView's frame size, + set the button's autoresizing mask so that it is placed properly according to the cell size (which can change based on device type and/or interface orientation).
Please try this one. In you code remove [cell addSubview:button2]; add write there [cell.contentView addSubview:button2]; and also for removing overlapping of cell or for removing disturb buttons frame add this for loop before all cell content view allocated.
for(UIView *view in cell.contentView.subviews)
{
[view removeFromSuperview];
}
then you can add here uibuttons uilabels , etc...
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;
}
}