简体   繁体   English

UIimageView蒙版成钻石

[英]UIimageView masks into a diamond

Running into a super weird bug in my iOS application I cannot figure out. 我不知道我的iOS应用程序中遇到了一个超级奇怪的错误。

I load a UIImageView for a user in my iOS application and then round it into a circle. 我在iOS应用程序中为用户加载了UIImageView,然后将其四舍五入。

- (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 看到这里: 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. 我发现如果将图像加载到viewDidLoad中并在viewDidAppear中将其取整,则效果很好。 But that seems to "hacky" and doesn't load everything at the same time properly. 但这似乎是“ hacky”,并且不能同时正确加载所有内容。

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. viewDidLoad “自动布局”下,图像视图的框架将为零,但您正在使用它进行圆角处理。

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 . 正如您已经发现的,解决方案是在布局发生时设置视点半径-在viewDidLayoutSubviewsviewDidAppear 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 . 更好的解决方案是编写一个图像视图子类,该子视图在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. self.bounds将反映self.frame不会自动调整大小,自动布局,旋转,缩放和其他几何问题。 Good luck 祝好运

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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