I have a transparent image which ("hold_empty.png", below) which I want to turn into a button. Inside the button there will be a view with a colored background which is slightly smaller size than the actual image to hold the background color.
The reason for this is because the image has rounded corners and so I cannot simply put a background color on the image as it will appear to be bigger than the image.
The image is a transparent square with "rounded corners". The effect I am trying to create should be like layers.
Background color layer (red, green, etc)
The "hold_empty.png" picture (above)
The whole object (including bg color layer) should be clickable.
The problem I am experiencing is that only the image (and its borders) appears to be clickable, and not the whole object.
The code follows below.
// x,y,w,h
CGRect frame = CGRectMake(10, 10, 72, 72);
CGRect frame2 = CGRectMake(5, 5, 60, 60); // I know this is not filling the image, its just a test
UIView *bgColorView = [[UIView alloc] initWithFrame:frame2];
[bgColorView setFrame:frame2];
bgColorView.backgroundColor = [UIColor redColor];
UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"hold_empty" ofType:#"png"]];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn addSubview:bgColorView];
[btn setImage:image forState:UIControlStateNormal];
btn.frame = frame;
[btn addTarget:self action:#selector(btnSelectColor:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
[bgColorView release];
So, to summarize: How do I make a transparent image button with a background color clickable?
Thanks.
The clickable area is generally the frame of the button which would not be clipped by its super-views, if you would let them clip contents.
The fact that you see something on screen doesn't mean it's "visible" in the sense that you can touch it. If you let every view clip its subviews (through IB, or by setting view.clipsToBounds = YES;) then any problems in that respect will show up clearly.
(Note that any UIButton, UIImageView, etc is a view and can be set to clip its contents)
Do you need to maybe enable user interaction on the subview?
bgColorView.userInteractionEnabled = YES;
I think I may have an answer that is working, but would like your comments/suggestions.
I created an UIImageView and put my background color layer and image layer inside that and then put the UIImageView inside the btn.
The only problem is now the button does not look like it is being pressed.
When I add the "setShowsTouchWhenHighlighted" option it has what looks like a big white star in the middle of the button when the user clicks ont he button.
// x,y,w,h
CGRect frame = CGRectMake(10, 10, 72, 72);
CGRect frame2 = CGRectMake(5, 5, 62, 62); // This fits, but may not be 100% accurate
// View
UIView *bgColorView = [[UIView alloc] initWithFrame:frame2];
[bgColorView setFrame:frame2];
bgColorView.backgroundColor = [UIColor redColor];
bgColorView.userInteractionEnabled = YES;
[bgColorView setNeedsDisplayInRect:frame2];
// Image
UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"hold_empty2" ofType:#"png"]];
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
[imgView insertSubview:bgColorView atIndex:0];
// Btn
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:frame];
[btn addSubview:imgView];
[btn setShowsTouchWhenHighlighted:YES];
[btn setUserInteractionEnabled:YES];
[btn addTarget:self action:#selector(btnSelectColor:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
[imgView release];
[bgColorView release];
I've cracked it now. One of the problems I was having was that it was not working with avatars (sometimes it would appear behind the layer, othertimes it would not show at all).
This is my solution.
UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"some_avatar" ofType:#"png"]];
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
CGRect fullFrame = CGRectMake(25, 10, 70,72);
CGRect frame = CGRectMake(28, 13, 63,65);
UIButton *h=[UIButton buttonWithType:UIButtonTypeCustom];
[h setFrame:fullFrame];
[[h layer] setMasksToBounds:YES];
//[h setBackgroundImage:image forState:UIControlStateNormal];
//[h setImage:image forState:UIControlStateNormal];
[h setShowsTouchWhenHighlighted:YES];
[h setClipsToBounds:YES];
CAGradientLayer *gradientLayer = [[CAGradientLayer alloc] init];
[gradientLayer setBounds:frame];
[gradientLayer setPosition:CGPointMake([h bounds].size.width/2, [h bounds].size.height/2)];
[gradientLayer setColors:[NSArray arrayWithObjects:
(id)[[UIColor darkGrayColor]CGColor],(id)[[UIColor blackColor] CGColor], nil]];
[[h layer] insertSublayer:gradientLayer atIndex:0];
[h insertSubview:imgView atIndex:1];
[h addTarget:self action:#selector(btnSelectColor:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:h];
[imgView release];
Related
I'v added an UIView in my controller then added a UIButton on that View.
Am animating that view horizontally, so along with that view my button also moving, since its add on that view, but I want that when user touches the button(which is animating) button should animate up & came down immediately.
This button's animation should be performed, while the older animation of view (button's super view) is animating.
I have done that but, button is animating up n down until the big animation of that view not get start, once the animation of button's super view get started, it is not performing that animation which it was performing before( on touch).
Here is the code
tempRabbit = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 360, 360)];
tempView=[[UIView alloc]initWithFrame:CGRectMake(900, 0, 1024, 500)];
UIImageView *temp=[[UIImageView alloc]initWithFrame:CGRectMake(0, 200, 360, 360)];
UIButton *tempBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[tempBtn setFrame:CGRectMake(0, 0, 360, 360)];
[tempBtn addTarget:self action:#selector(rabbitTaped1) forControlEvents:UIControlEventTouchUpInside];
[tempBtn setTitle:#"Show View" forState:UIControlStateNormal];
NSArray *animationArray=[[NSArray alloc]init];
animationArray=[NSArray arrayWithObjects:
[UIImage imageNamed:#"rabbit1.png"],
[UIImage imageNamed:#"rabbit2.png"],
[UIImage imageNamed:#"rabbit3.png"],
[UIImage imageNamed:#"rabbit4.png"],
[UIImage imageNamed:#"rabbit5.png"],
[UIImage imageNamed:#"rabbit6.png"],
[UIImage imageNamed:#"rabbit7.png"],
[UIImage imageNamed:#"rabbit8.png"],
[UIImage imageNamed:#"rabbit9.png"],
[UIImage imageNamed:#"rabbit10.png"],
[UIImage imageNamed:#"rabbit11.png"],
[UIImage imageNamed:#"rabbit12.png"],
[UIImage imageNamed:#"rabbit13.png"], nil];
temp.animationImages=animationArray;
temp.animationDuration=2;
temp.animationRepeatCount=0;
[temp startAnimating];
//[tempRabbit addSubview:temp];
[tempRabbit addSubview:tempBtn];
[tempView addSubview:tempRabbit];
[self.view addSubview:tempView];
i'm extending UITableViewController and have a uibutton added programtticly to the table footer , for some reason the uibutton fire only when touch in the top part ... as if someting is masking the rest of it and i can't understand what it is
i have the following code at viewForFooterInSection function:
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
UIView* footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenRect.size.width, 44.0)];
footerView.autoresizesSubviews = YES;
footerView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
footerView.userInteractionEnabled = YES;
goButton = [UIButton buttonWithType:UIButtonTypeCustom];
[goButton addTarget:self action:#selector(getReport)forControlEvents:UIControlEventTouchUpInside];
[goButton setTitle:#"GO!" forState:UIControlStateNormal];
[goButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
goButton.frame = CGRectMake(50, 20, 220.0, 50.0);
UIImage *bg = [UIImage imageNamed: #"but_go.png"];
[goButton setBackgroundImage:bg forState:UIControlStateNormal];
[goButton setBackgroundColor:[UIColor clearColor]];
if (self.optimizations == nil || self.optimizations.count < 1){
goButton.enabled = NO ;
}
[footerView addSubview: goButton];
return footerView;
It's because the button's frame fell out of its parent view. You need to increase your footerView's frame size so the whole part of the button contains in the footerView. You can try to set footerView background color to blue or red to see the actual frame area.
Here is the code I'm using:
-(void)viewDidLoad
{
NSString *checkerPath = [[NSBundle mainBundle] pathForResource:#"black-yellow-checker" ofType:#"png"];
UIImage *checkerImage = [[UIImage alloc] initWithContentsOfFile:checkerPath];
checkerView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 230.0f, 320.0f, 280.0f)];
[checkerView setImage:checkerImage];
UIButton *backButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
backButton.frame = CGRectMake(45.0f, 175.0f, 230.0f, 50.0f);
[backButton setBackgroundImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"yellowButton" ofType:#"png"]] forState:UIControlStateNormal];
[backButton addTarget:self action:#selector(goBackHome:) forControlEvents:UIControlEventTouchDown];
[backButton setTitle:#"Back" forState:UIControlStateNormal];
backButton.titleLabel.font = [UIFont fontWithName:#"Marker Felt" size:30];
backButton.titleLabel.textColor = [UIColor blackColor];
[checkerView addSubview:backButton];
}
- (void)goBackHome:(id)sender
{
NSLog(#"go back pressed");
}
Not sure why this doesn't work. The button shows up, but when I press it nothing happens. It doesn't even change to the "indented" image when I touch it. Nothing. Can't use IB, has to be programmatically. Any thoughts?
UIImageView has userInteractionEnabled set to NO by default. This prevents any subviews from getting touches.
You could either enable user interaction of the image view by
checkerView.userInteractionEnabled = YES;
or create a new UIView to include both checkerView and the backButton.
UIView* newView = ...
...
[newView addSubview:checkerView];
[newView addSubview:backButton];
I believe that the forControlEvents: has to be UIControlEventTouchUpInside.
I am trying to add an image to the UIBarButtonItem which I have to use in a UIToolbar.
I have managed to read the image and even get it to display with a UIImageView, but when i add it to the UIBarButtonItem and then add that item to the UIToolbar, the toolbar just displaces a "Blank White" space the size and shape of the image that I am trying to load.
here is what I am trying.
UIImage *image = [UIImage imageNamed:#"6.png"];
//This is the UIImageView that I was using to display the image so that i know that it is being read from the path specified.
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(0, 50, image.size.width, image.size.height);
[self.view addSubview:imageView];
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom];
[button1 setImage:image forState:UIControlStateNormal];
//This is the first way that I was trying to accomplish the task but i just get a blank white space
//This is the Second way but with the same blank white result.
UIBarButtonItem *systemItem1 = [[UIBarButtonItem alloc] initWithCustomView:button2];
NSArray *items = [NSArray arrayWithObjects: systemItem1, nil];
//Adding array of buttons to toolbar
[toolBar setItems:items animated:NO];
//Adding the Toolbar to the view.
[self.view addSubview:toolBar];
Your help will be much appreciated.
Thank You!
Shumais Ul Haq
Other than you'd normally expect in UIKit stuff, you might need to set a frame for the button explicitly. Maybe that's your problem.
This is what I wrote for a custom styled back button, as a category to UIBarButtonItem (but you can just take the pieces you need from it).
Note that this was used for the navigation bar, not the toolbar, but I presume the mechanics are the same, since it is a UIBarButtonItem as well. For UIToolbar you can just use IB to get it right at compile time.
#define TEXT_MARGIN 8.0f
#define ARROW_MARGIN 12.0f
#define FONT_SIZE 13.0f
#define IMAGE_HEIGHT 31.0f
+(UIBarButtonItem*)arrowLeftWithText:(NSString*)txt target:(id)target action:(SEL)selector
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *img = [[UIImage imageNamed:#"arrow_left.png"]
stretchableImageWithLeftCapWidth:15 topCapHeight:0];
[btn addTarget:target action:selector forControlEvents:UIControlEventTouchDown];
[btn setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight];
[btn setContentEdgeInsets:UIEdgeInsetsMake(0.0f,0.0f,0.0f,TEXT_MARGIN)];
[btn.titleLabel setFont:[UIFont fontWithName:#"Helvetica-Bold" size:FONT_SIZE]];
[btn.titleLabel setShadowOffset:CGSizeMake(0.0f,-1.0f)];
/**** this is the magic line ****/
btn.frame = CGRectMake(0.0f,0.0f,
[txt sizeWithFont:[btn.titleLabel font]].width+ARROW_MARGIN+TEXT_MARGIN,
IMAGE_HEIGHT);
[btn styleBarButtonForState:UIControlStateNormal withImage:img andText:txt];
[btn styleBarButtonForState:UIControlStateDisabled withImage:img andText:txt];
[btn styleBarButtonForState:UIControlStateHighlighted withImage:img andText:txt];
[btn styleBarButtonForState:UIControlStateSelected withImage:img andText:txt];
return [[[UIBarButtonItem alloc] initWithCustomView:btn] autorelease];
}
usage:
[UIBarButtonItem arrowLeftWithText:#"Back" target:self action:#selector(dismiss)];
UIButton *ticketButtonObj=
[[UIButton alloc]initWithFrame:CGRectMake(140.0f 100.0f, 390.0f, 40.0f)];
UIImage *buttonicon1=[UIImage alloc];
buttonicon1=[UIImage imageNamed:#"Generalticket.png"];
how can set background of ticketButtonObj with buttonicon1 .. in left alignment ?
pls help me... thanks and regards by raju.
UIButton *ticketButtonObj = [[UIButton alloc] initWithFrame:CGRectMake(140.0f 100.0f, 390.0f, 40.0f)];
UIImage* buttonicon1 = [UIImage imageNamed:#"Generalticket.png"];
[ticketButtonObj setImage:image forState:UIControlStateNormal];
ticketButtonObj.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
or, if you want to set the background image:
[ticketButtonObj setBackgroundImage:image forState:UIControlStateNormal];
But you cannot set the alignment for the background.