clipsToBounds 导致 UIImage 在 iOS10 和 XCode 8 中不显示

Posted

技术标签:

【中文标题】clipsToBounds 导致 UIImage 在 iOS10 和 XCode 8 中不显示【英文标题】:clipsToBounds causes UIImage to not display in iOS10 & XCode 8 【发布时间】:2016-08-25 04:18:32 【问题描述】:

我将我的项目切换到 ios 10 和 XCode 8 的新 beta 版本。在我使用的应用程序的所有三个区域中:

imageView.layer.cornerRadius = imageView.frame.size.width/2
imageView.clipsToBounds = true

相关图像根本不显示。我尝试清理项目以及构建文件夹,重新启动设备,尝试各种模拟器,重新添加 imageView,以编程方式设置关联的UIImage,而不是从资产中选择一个。

无论masksToBoundstrue 还是false,删除clipsToBounds 行都会显示矩形图像。如何在 XCode8 / iOS10 中制作圆形图像?

编辑:该项目是 Swift 2.x,尚未更新为 Swift 3.0 语法。

【问题讨论】:

所以如果您删除了 clipsToBounds 设置语句,cornerRadius 是否停止影响 imageView 并且您的图像再次变为矩形? @ddb 是的,去掉clipsToBounds语句后,图片是矩形的,可见。 这个答案:***.com/questions/39380128/… 建议调用 self.layoutIfNeeded 我认为这不是 iOS10 的问题。该行为也发生在 iOS9 上。这可能是 XCode 8 的错误或对布局周期的有意更新。 您应该在图层修改之前添加 layoutIfNeeded()。 ***.com/a/39815405/3718570 【参考方案1】:

我遇到了同样的问题,并在所有圆角/clipsToBounds 解决问题之前调用了layoutIfNeeded。 iOS 10 GM with xcode 8 GM causes views to disappear due to roundedCorners & clipsToBounds

【讨论】:

【参考方案2】:

这个问题也发生在我身上。

我将这些代码 imageView.layer.cornerRadius = imageView.frame.size.width/2- (void)awakeFromNib 移动到 - (void)drawRect:(CGRect)rect,这个问题就消失了。

我的 imageView 由自动布局调整大小。我认为在 iOS 10 上从 nib 唤醒时,高度和宽度并没有决定。

【讨论】:

【参考方案3】:

这听起来可能是由于 iOS 10 和 Xcode 8 以来的一个新错误,其中视图初始化为 1000x1000 大小,当尝试将角半径设置为框架的一半时,它会将其设置为 500。这在此问题中进一步记录:Since Xcode 8 and iOS10, views are not sized properly on viewDidLayoutSubviews。我认为这是解决 1000x1000 问题的原因,它在执行任何需要在界面构建器上构建的东西的大小之前调用布局子视图。

【讨论】:

【参考方案4】:

我遇到了同样的问题。未在手机上显示,但在 Storyboard 和 UI 调试器上完美。当我将项目“使用 Xcode 7 打开”而不是 8 时,它也有效,但不是一个令人满意的解决方案。所以我挖掘并发现了问题。问题在于这样的课程:

@IBDesignable public class MyButton: UIButton 

   @IBInspectable var styleName: String = "" 
        didSet 
            switch styleName 
            case "RoundedLight":
                tintColor = UIColor.lightPinkColor()
                layer.borderColor = UIColor.whiteColor().CGColor
                layer.borderWidth = 1
                layer.masksToBounds = true
            default:
                break
            
        
    

    override public func layoutSubviews() 
        super.layoutSubviews()

        switch styleName 
            case "RoundedLight":
                layer.cornerRadius = frame.height / 2
            default:
                break
        
    

我把它改成了这个,它现在可以工作了:

@IBDesignable public class MyButton: UIButton 

   @IBInspectable var styleName: String = "" 
        didSet 
            layoutIfNeeded()
        
    

    override public func layoutSubviews() 
        super.layoutSubviews()

        switch styleName 
        case "RoundedLight":
            tintColor = UIColor.lightPinkColor()
            layer.borderColor = UIColor.whiteColor().CGColor
            layer.borderWidth = 1
            layer.cornerRadius = frame.height / 2
            layer.masksToBounds = true
        default:
            break
        
    

请注意,以上都不适合我,我的意思是:

layoutSubviews() 中调用layoutIfNeeded 在我的按钮(或包含该按钮的单元格)的awakeFromNib 中调用layoutIfNeeded 在我的单元格的layoutSubview 中调用layoutIfNeeded 在我的单元格的awakeFromNib 中调用contentView.layoutIfNeeded() 在我的视图控制器中调用view.layoutIfNeeded()

【讨论】:

【参考方案5】:

我的 ImageView 是完全圆形的。下面是代码:

//MARK:- Misc functions
func setProfileImage() 
    imgProfile.layer.masksToBounds = false
    imgProfile.layer.cornerRadius = imgProfile.frame.size.height/2
    imgProfile.clipsToBounds = true
    imgProfile.contentMode = UIViewContentMode.ScaleToFill
 

这在 iOS 9 中运行良好。但是,in iOS 10 Xcode 8 the ImageView disappears. 经过调试发现ClipsToBound是罪魁祸首。

所以将代码放在viewDidLayoutSubviews() 解决了这个问题。

override func viewDidLayoutSubviews() 
    setProfileImage()

你也可以使用self.view.layoutIfNeeded()

【讨论】:

【参考方案6】:

这可能是布局问题。将clipToBounds 设置为 false 将显示图像,即使其大小为零。可以打印图片的frame 吗?

如果您在viewDidLoad 中设置cornerRadiusclipToBounds 属性,请尝试在viewDidLayoutSubviews() 中进行。

您也可以尝试拨打self.view.layoutIfNeeded()

【讨论】:

我最初尝试在 viewDidLoad 和 viewDidAppear 中设置角半径和 clipsToBounds,但没有结果。我尝试使用 viewDidLayoutSubviews 也无济于事。当我进入调试视图层次结构时,我可以看到正在绘制的 UIImageView 中的 UIImage 框架 - 只是没有显示图像。值得一提的是(我在原来的帖子中忘记了),该项目仍然是 Swift 2.x 并且没有更新到 Swift 3.0 语法。 打印帧产量:(137.5, 24.0, 100.0, 100.0)【参考方案7】:

使用 obj-c,将语法从 viewDidLoad 移动到 viewDidLayoutSubviews 对我有用。

【讨论】:

【参考方案8】:

我只是像这样实现了圆角

@implementation RoundImageView

- (instancetype)initWithCoder:(NSCoder *)coder

    self = [super initWithCoder:coder];
    if (self) 
        self.layer.masksToBounds = YES;
        self.layer.cornerRadius = MIN(self.bounds.size.height, self.bounds.size.width)/2;
        [self addObserver:self
               forKeyPath:@"bounds"
                  options:NSKeyValueObservingOptionNew
                  context:(__bridge void * _Nullable)(self)];
    
    return self;


-(void)dealloc

    [self removeObserver:self
              forKeyPath:@"bounds"
                 context:(__bridge void * _Nullable)(self)];


-(void)observeValueForKeyPath:(NSString *)keyPath
                     ofObject:(id)object
                       change:(NSDictionary<NSString *,id> *)change
                      context:(void *)context

    if(context == (__bridge void * _Nullable)(self) && object == self && [keyPath isEqualToString:@"bounds"])
    
        self.layer.cornerRadius = MIN(self.bounds.size.height, self.bounds.size.width)/2;
    


@end

所以我总是有适当的圆角。 而且我升级到 iOS10 和 XCode8 没有问题

【讨论】:

【参考方案9】:

我认为问题的发生是因为我们按照@Pranoy C 所说的那样设置了圆角和剪辑子视图。

我通过将 layoutIfNeeded 用于显示用户个人资料图片的 tableview 单元格来解决问题。我想确保图像是圆角

代码如下: - (void)awakeFromNib [超级清醒的笔尖]; [自我布局IfNeeded];

[self.inputIndicator_imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
self.profile_pic_edit_imageView.layer.cornerRadius = self.profile_pic_edit_imageView.frame.size.width/2;
self.profile_pic_edit_imageView.layer.borderWidth = 1.0;
self.profile_pic_edit_imageView.layer.borderColor = GRAY_COLOR_SUPER_LIGHT.CGColor;
self.profile_pic_edit_imageView.clipsToBounds = YES;

【讨论】:

【参考方案10】:

您应该在调用 imageView.frame.size.width 之前在主视图上调用 layoutSubviews()

[self.view layoutSubviews];
imageView.layer.cornerRadius = imageView.frame.size.width/2
imageView.clipsToBounds = true

【讨论】:

你永远不应该手动调用layoutSubviews。请致电layoutIfNeeded

以上是关于clipsToBounds 导致 UIImage 在 iOS10 和 XCode 8 中不显示的主要内容,如果未能解决你的问题,请参考以下文章

clipsToBounds 是如何工作的?

UIImageView添加圆角

iOS切圆角方法解决离屏渲染问题

iOS小知识点

从 CMSampleBufferRef 转换的 UIImage,导致 UIImage 无法正确渲染

从 MTKView 创建的 UIImage 导致颜色/不透明度差异