2

I have a UIButton, and I would like to access the UIImageView of its background image so that I can make the image circular. I know that I can affect the image itself but I would prefer to do this more elegantly. I also know that I can use the button.currentBackgroundImage property to get the UIImage in the background, but I want the view itself. Once I have the view I intend to use this code:

buttonImageView.layer.cornerRadius = buttonImageView.frame.size.width / 2;
buttonImageView.clipsToBounds = YES;

How can I access the buttonImageView?

EDIT: Due to @vhristoskov's suggestions, I tried cropping the button itself with this code:

self.button.layer.cornerRadius = self.button.frame.size.width/2;
self.button.clipsToBounds = YES;

And it made this shape:

enter image description here

After debugging I found that frame.size.width was 46, when it should have been 100. So I tried this code instead:

self.button.layer.cornerRadius = self.button.currentBackgroundImage.size.width/2;
self.button.clipsToBounds = YES;

And that produced this shape:

enter image description here

And this time, the cornerRadius was being set to 65. So it actually seems like my problem is that I don't have the correct width at the moment. Which property should I access to get the correct number?

5
  • Is there a reason to not apply the same code directly to your UIButton? Commented Jul 4, 2016 at 23:46
  • @vhristoskov hmmm I just tried that and I got a strange result, the image was oddly shaped. I can add a screenshot of what happened to my question if you'd like. Commented Jul 5, 2016 at 0:35
  • This would be great. Also you could add an image of your constraints in the IB (or the code you've used to set the button's frame). Commented Jul 5, 2016 at 0:39
  • @vhristoskov I added the images if you have any ideas Commented Jul 7, 2016 at 1:31
  • Please review my answer below and hope that this will help you and put the end of this mystery :D Commented Jul 7, 2016 at 15:17

2 Answers 2

0

Well as I guessed and as you've already found - the problem is in the button size. To be sure that your button's size at runtime is what you expected to be - review your constraints. In the example below the button has vertical and horizontal central alignment and fixed width and height.

Button Constraints

Constraints:

enter image description here

To have perfectly circular button you should have button.width == button.height. If this condition is met your code should work like a charm:

self.button.layer.cornerRadius = CGRectGetWidth(self.button.frame) / 2;
self.button.clipsToBounds = YES;

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

So it turned out that my issue was trying to get button width at viewDidLoad, and apparently the width is only valid at viewDidAppear. I'm going to accept this answer anyway, because it contains the gist of my solution. Thanks for all the help :)
0

Assuming that you called something like:

[self.myButton setBackgroundImage:[UIImage imageNamed:@"image"] forState:UIControlStateNormal];

in viewDidLoad or earlier, you can then call the following in viewDidAppear:

if (self.myButton.subviews.count > 0 && [self.myButton.subviews[0] isKindOfClass:[UIImageView class]]) {
    UIImageView *imageView = self.myButton.subviews[0];
    imageView.layer.cornerRadius = imageView.frame.size.width / 2;
    imageView.clipsToBounds = YES;
}

but it is not more elegant as the subview ordering is an implementation detail of UIButton and may change at any time.

2 Comments

It seems like the UIButton doesn't actually have any subviews :/
I found that the subviews were only added by viewDidAppear, but were not yet present at viewDidLoad time. It may be dependent on when the background image is first set.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.