Swift 中的圆 - 无法摆脱剪裁

Posted

技术标签:

【中文标题】Swift 中的圆 - 无法摆脱剪裁【英文标题】:Circles in Swift - can't get rid of clipping 【发布时间】:2017-01-30 22:30:30 【问题描述】:

我正在使用 Swift 3.0 并使用 UIBezierPath 绘制圆圈。我的代码如下。无论我改变什么,圆的边缘仍然被剪裁。圆圈位于图像视图中。我尝试过操纵视图的高度/重量,以及将其更改为“方面填充”“方面适合”“中心”等。我看过的教程还告诉我,如果我更改“var multiplier: CG Float = 1.0 " 到 0.85 或其他数字,剪裁将消失。我已经尝试过了,但它没有用。我该如何解决这个问题?

class Circle1: UIView 
    var multiplier:CGFloat = 0.85
    //this takes away the "clippinh" you might see in the view

    var centerOfCirclesView: CGPoint
        return CGPoint(x:bounds.midX, y:bounds.midY)
    
    var halfOfViewsSize: CGFloat
        return min(bounds.size.height, bounds.size.width) / 2
    

    var lineWidth:CGFloat = 1.0

    //circle radius compute

    var full = CGFloat(M_PI * 2)
    var quarter = CGFloat(M_PI / 2)
    var half = CGFloat(M_PI)
    var threeQuarters = CGFloat(3 * M_PI / 2)


    func drawCircleCenteredAt(_:CGPoint, withRadius radius:CGFloat) -> UIBezierPath
        let circlePath = UIBezierPath(arcCenter: centerOfCirclesView,
                                      radius: halfOfViewsSize,
                                      startAngle: 00,
                                      endAngle: full,
                                      clockwise: false)
        circlePath.lineWidth = lineWidth

        return circlePath
    

    override func draw(_ rect: CGRect) 
        UIColor(hue: 0.7194, saturation: 0, brightness: 0.52, alpha: 1.0).set()
        lineWidth = 15.0
        drawCircleCenteredAt(centerOfCirclesView, withRadius: halfOfViewsSize).stroke()
    



class Circle2: UIView 

    var multiplier:CGFloat = 0.85
    //this takes away the "clippinh" you might see in the view

    var centerOfCirclesView: CGPoint
        return CGPoint(x:bounds.midX, y:bounds.midY)
    
    var halfOfViewsSize: CGFloat
        return min(bounds.size.height, bounds.size.width) / 2
    

    var lineWidth:CGFloat = 1.0

    //circle radius compute

    var full = CGFloat(M_PI * 2)
    var quarter = CGFloat(M_PI / 2)
    var half = CGFloat(M_PI)
    var threeQuarters = CGFloat(3 * M_PI / 2)


    func drawCircleCenteredAt(_:CGPoint, withRadius radius:CGFloat) -> UIBezierPath
        let circlePath = UIBezierPath(arcCenter: centerOfCirclesView,
                                      radius: halfOfViewsSize,
                                      startAngle: 00,
                                      endAngle: half,
                                      clockwise: false)
        circlePath.lineWidth = lineWidth

        return circlePath
    

【问题讨论】:

您需要通过乘以 0.85 乘数或减去 0.5 * 线宽来减小半径。 你应该在 Swift 3 中使用 .pi 而不是 M_PI 【参考方案1】:

你需要减少你的radius,这样你的圈子就不会被剪裁。例如,在Circle1 中,将halfOfViewSize - 0.5 * lineWidth 传递给radiusdrawCircleCenteredAt(_:withRadius:),然后在创建UIBezierPath 时使用该半径:

func drawCircleCenteredAt(_:CGPoint, withRadius radius:CGFloat) -> UIBezierPath 
    let circlePath = UIBezierPath(arcCenter: centerOfCirclesView,
                                  radius: radius,               // Changed this to radius
                                  startAngle: 0,
                                  endAngle: full,
                                  clockwise: false)
    circlePath.lineWidth = lineWidth

    return circlePath


override func draw(_ rect: CGRect) 
    UIColor(hue: 0.7194, saturation: 0, brightness: 0.52, alpha: 1.0).set()
    lineWidth = 15.0
    drawCircleCenteredAt(centerOfCirclesView, withRadius: halfOfViewsSize - 0.5 * lineWidth).stroke()

您的multiplier 无效,因为您没有在任何地方使用它。您还可以在创建UIBezierPath 时使用halfOfViewSize * multiplier 来减少radius


这是修改后的代码,它从draw(_:) 例程中删除了颜色和线宽的设置。

class Circle1: UIView 
    var centerOfCirclesView: CGPoint
        return CGPoint(x:bounds.midX, y:bounds.midY)
    

    var halfOfViewsSize: CGFloat
        return min(bounds.size.height, bounds.size.width) / 2
    

    var lineWidth:CGFloat = 1.0

    var color = UIColor(hue: 0.7194, saturation: 0, brightness: 0.52, alpha: 1.0)
    //circle radius compute

    var full = CGFloat.pi * 2
    var quarter = CGFloat.pi / 2
    var half = CGFloat.pi
    var threeQuarters = 3 * CGFloat.pi / 2

    func drawCircleCenteredAt(_:CGPoint, withRadius radius:CGFloat) -> UIBezierPath
        let circlePath = UIBezierPath(arcCenter: centerOfCirclesView,
                                      radius: radius,                     // Changed this to radius
                                      startAngle: 0,
                                      endAngle: full,
                                      clockwise: false)
        circlePath.lineWidth = lineWidth

        return circlePath
    

    override func draw(_ rect: CGRect) 
        color.set()
        drawCircleCenteredAt(centerOfCirclesView, withRadius: halfOfViewsSize - 0.5 * 15.0).stroke()
    

这是一个在 Swift Playground 中运行的演示:

【讨论】:

一切看起来都很棒!但是,现在较小宽度的圆圈不在较大宽度的圆圈内居中。你知道如何纠正这个问题吗? 我意识到你可能不知道那是什么意思.. 宽度较小的圆圈位于宽度较大的圆圈之上。当它被剪裁时,它是居中的,现在它不是。外边界与另一个圆圈的外边界对齐。知道如何让它再次居中吗?谢谢! 您只需要两个圆具有相同的半径即可。因此,在计算两个圆圈的 radius 时,请使用较粗圆圈中的 lineWidth 如果您觉得这个答案有帮助,请点击旁边的灰色复选标记将其变为绿色来接受它。

以上是关于Swift 中的圆 - 无法摆脱剪裁的主要内容,如果未能解决你的问题,请参考以下文章

IOS Swift UITableView - 无法解释的边距 - 如何摆脱?

Swift - 如何摆脱 UISearchController 中的这种深色背景?

Swift:摆脱时间戳 NSLog()

你如何摆脱swift中主要故事板的代码?

在 Swift 中对 UITabBarController 进行 segue 后如何摆脱 UINavigationController?

央行数字货币可以摆脱对SWIFT的依赖吗?