UIView设置cornerRadius显示椭圆而非圆形,求解决方案
嘿,这个问题我之前做项目的时候也踩过坑,咱们来捋清楚怎么解决~
首先先澄清一个误区:cornerRadius并不是只适用于正方形UIView,只要视图的宽高相等,不管尺寸是多少,把cornerRadius设为宽/2(或者高/2,因为宽高相等),就能得到完美的圆形。你遇到的79*158视图显示成椭圆的问题,大概率是因为你设置cornerRadius的时机不对,导致获取到的视图尺寸不是最终的布局尺寸。
为什么会显示成椭圆?
如果你的redView是用AutoLayout来约束尺寸的,那么在viewDidLoad方法中,视图还没有完成最终的布局计算,此时redView.frame的尺寸可能不是你预期的79*158,用这个错误的尺寸计算出来的cornerRadius自然就不对,最终显示成椭圆。
解决办法
1. 在布局完成后设置cornerRadius
iOS提供了viewDidLayoutSubviews方法,这个方法会在视图的布局(包括AutoLayout约束)完全完成后调用,此时视图的frame/bounds是最终的正确尺寸。你可以把设置圆角的代码放到这里:
override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() // 用bounds比frame更可靠,因为bounds是视图自身的尺寸,不受父视图位置影响 redView.layer.cornerRadius = redView.bounds.height / 2 redView.layer.masksToBounds = true }
2. 用约束保证宽高始终相等(支持动态调整尺寸)
如果你希望视图在动态调整尺寸时始终保持圆形,可以给redView添加宽高相等的约束,这样不管视图怎么变化,宽高都会保持一致,再配合布局完成后设置圆角,就能始终显示圆形:
// 在设置其他约束的同时,添加宽高相等的约束 redView.widthAnchor.constraint(equalTo: redView.heightAnchor).isActive = true // 同样在viewDidLayoutSubviews中设置圆角 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() redView.layer.cornerRadius = redView.bounds.height / 2 redView.layer.masksToBounds = true }
3. 自定义UIView自动维护圆形(更优雅的方案)
如果你的项目中需要多个圆形视图,可以自定义一个UIView子类,在layoutSubviews方法中自动设置圆角,这样每次视图尺寸变化时都会自动更新:
class CircularView: UIView { override func layoutSubviews() { super.layoutSubviews() layer.cornerRadius = bounds.height / 2 layer.masksToBounds = true } }
之后直接使用CircularView代替普通的UIView,就不用每次手动设置圆角了,动态调整尺寸也能自动保持圆形。
总结
cornerRadius的使用没有限制,只要视图宽高相等就能得到圆形。核心问题是要在视图布局完成后再设置圆角,或者通过约束保证宽高始终一致,这样就能避免出现椭圆的情况啦。
内容的提问来源于stack exchange,提问作者Ramesh

