圆形UIView不是一个完整的圆圈

时间:2017-03-03 23:15:45

标签: uiview interface-builder cornerradius ibinspectable

我有一个有趣的问题,但我不确定如何解决它。我试图用@IBInspectable扩展UIView。但是,使用此方法时,角半径似乎是从nib文件的默认端设置的,而不是视图的实际大小。

所以,在IB中我将" View设置为"对于iPhoneSE和为iPhoneSE构建,视图是一个圆圈。但是,如果我为iPhone7构建,角落不会完全圆化成圆形。相反,如果我设置"查看为"对于iPhone7和iPhone7的构建,视图是一个圆圈,但是,如果我为iPhoneSE构建,角落是圆形的。

下面的图片和代码:

扩展

extension UIView {

    @IBInspectable var cornerRadius:Double {
        get {
            return Double(layer.cornerRadius)
        }
        set {
            layer.cornerRadius = CGFloat(newValue)
            layer.masksToBounds = newValue > 0
        }
    }

    @IBInspectable var circleView:Bool {
        get {
            return layer.cornerRadius == min(self.frame.width, self.frame.height) / CGFloat(2.0) ? true : false
        }
        set {
            if newValue {
                layer.cornerRadius = min(self.frame.width, self.frame.height) / CGFloat(2.0)
                layer.masksToBounds = true
            }
            else{
                layer.cornerRadius = 0.0
                layer.masksToBounds = false
            }
        }
    }

}

"查看为"在IB中设置为iPhoneSE

专为iPhoneSE而设

enter image description here

为iPhone 7构建

enter image description here

"查看为"设为iPhone7

为iPhone SE构建

enter image description here

为iPhone 7构建

enter image description here

IB设置 enter image description here enter image description here

4 个答案:

答案 0 :(得分:2)

如果您的视图是正方形,则只会获得一个完整的圆圈。

如果您查看的是一个矩形,并且您将cornerRadius的值设置为小于最小尺寸的一半,您将获得第二个视图,如果它的值大于您的值将获得钻石形状。

检查您的约束条件,您应该在视图完成cornerRadius中的布局后计算viewDidLayout,以便获得正确的大小。

这是一个展示这个的游乐场(我已添加动画以更好地展示问题):

import UIKit
import PlaygroundSupport

extension UIView
{
  func addCornerRadiusAnimation(from: CGFloat, to: CGFloat, duration: CFTimeInterval)
  {
    let animation = CABasicAnimation(keyPath:"cornerRadius")
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    animation.fromValue = from
    animation.toValue = to
    animation.duration = duration
    self.layer.add(animation, forKey: "cornerRadius")
    self.layer.cornerRadius = to
  }
}

let v = UIView(frame: CGRect(x: 0, y: 0, width: 350, height: 450))
PlaygroundPage.current.liveView = v

let squareView = UIView(frame: CGRect(x: 10, y: 10, width: 100, height: 100))
squareView.backgroundColor = .red
squareView.layer.masksToBounds = true
v.addSubview(squareView)
var cornerRadius = CGFloat(0.5*min(squareView.frame.width,
                                   squareView.frame.height))
squareView.addCornerRadiusAnimation(from: 0, to: cornerRadius, duration: 5)

let rectangleView = UIView(frame: CGRect(x: 10, y: 200, width: 100, height: 200))
rectangleView.backgroundColor = .blue
rectangleView.layer.masksToBounds = true
v.addSubview(rectangleView)
cornerRadius = CGFloat(0.5*min(rectangleView.frame.width,
                                   rectangleView.frame.height))
rectangleView.addCornerRadiusAnimation(from: 0, to: cornerRadius, duration: 5)

let diamondView = UIView(frame: CGRect(x: 200, y: 200, width: 100, height: 200))
diamondView.backgroundColor = .green
diamondView.layer.masksToBounds = true
v.addSubview(diamondView)
cornerRadius = CGFloat(0.5*max(diamondView.frame.width,
                               diamondView.frame.height))
diamondView.addCornerRadiusAnimation(from: 0, to: cornerRadius, duration: 5)

Playground output

答案 1 :(得分:0)

您提到宽度和高度为185.5,但您将宽度约束保持为350。

答案 2 :(得分:0)

如果你不想在viewDidLayout上移动,你可以通过添加.layoutIfNeeded()来设置你的角半径之前完成这个技巧。

yourCircleView.layoutIfNeeded()
yourCircleView.layer.cornerRadius = yourCircleView.frame.size.width/2

答案 3 :(得分:0)

如果仍然失败,在Xcode中删除所有(ALL)约束并在Cell Class中添加以下内容:

override func awakeFromNib() {
    super.awakeFromNib()        
    userImageView.layoutIfNeeded()
    userImageView.layer.cornerRadius = userImageView.frame.size.width / 2
    userImageView.layer.masksToBounds = true
    userImageView.clipsToBounds = true

}