简体   繁体   中英

UIimageView masks into a diamond

Running into a super weird bug in my iOS application I cannot figure out.

I load a UIImageView for a user in my iOS application and then round it into a circle.

- (void)viewDidLoad {
  [super viewDidLoad];

    self.profileImage.file = [[self.profileObject objectForKey:@"UserID"] valueForKey:@"ProfilePhoto"];
    [self.profileImage loadInBackground:^(UIImage *image, NSError *error) {
        self.profileImage.image = image;
        self.profileImage.layer.cornerRadius = self.profileImage.frame.size.width / 2;
        self.profileImage.layer.masksToBounds = YES;
        self.profileImage.contentMode = UIViewContentModeScaleAspectFill;
   }];
}

This runs perfectly, until I dismiss that view and go back into it a few moments later.

- (void)dismissView {
  [self dismissViewControllerAnimated:YES completion:nil];
  self.profileImage.image = nil;
}

When I go back into the view, the image rounds from the point it was already rounded prior. Which means it then turns into somewhat of a diamond. See here: http://cl.ly/image/3p1P0M0M1d2H

Any ideas on why this would be happenig?

Workaround

I found that if I load the image in viewDidLoad and round it in viewDidAppear it works just fine. But that seems to "hacky" and doesn't load everything at the same time properly.

Any ideas on what I should try?

The problem is that you're loading the image using sone background threading technique, and the first time you do so, it has to presumably fetch the image from somewhere, the second time it presumably has a cached version so it can run the completion block immediately.

Why should this matter?

At viewDidLoad , under Autolayout, your image view's frame will be zero, yet you're using it to round the corners.

On the first run, the delay in loading the image is enough for the view to have performed a layout pass, so it can round properly. On the second run, it hasn't (because the image is cached), so it can't.

The solution, as you've already discovered, is to set the corner radius when layout has happened - either in viewDidLayoutSubviews or viewDidAppear . Setting the radius can be totally separate to loading the image, and isn't "hacky" at all.

A better solution would be to write an image view subclass that performed it's own corner rounding on layoutSubviews . It's not really the view controller's job to do that rounding.

try changing

self.profileImage.layer.cornerRadius = self.profileImage.frame.size.width / 2;

to

self.profileImage.layer.cornerRadius = self.profileImage.bounds.size.width / 2;

in general it is always better to work internally with bounds rather than frame rect, because this is the internal perspective. self.bounds will reflect autoresizing, auto layout, rotation, scaling and other geometry issues which self.frame will not. Good luck

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM