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];