迅捷-添加自定义Curve扩展后,它不会呈现以编程方式创建的视图,仅呈现使用Interface Builder创建的视图

时间:2019-04-18 11:18:51

标签: swift user-interface extension-methods curve

我有一个扩展,可以将视图的底部边缘弯曲,因为此样式已在我尝试创建的应用程序的多个屏幕上使用。

但是,我注意到我只能使其与添加了槽式界面生成器的视图一起使用。如果我尝试将其应用到以编程方式创建的视图上,则它们不会呈现。

我创建了一个简单的示例来说明问题。主故事板包含两个viewControllers,中间有一个彩色视图:一个是用Interface Builder创建的,另一个是通过编程创建的。

在StoryboardVC中,可以正确呈现带有曲线的视图,而不会出现任何问题。 setBottomCurve()方法用于创建曲线。

如果将此与将入口点设置为ProgrammaticVC进行比较,则运行该应用程序可以看到纯白色的屏幕。注释掉该行以查看视图再次出现。

这是使用的扩展名:

extension UIView {
    func setBottomCurve(curve: CGFloat = 40.0){

        self.frame = self.bounds

        let rect = self.bounds
        let y:CGFloat = rect.size.height - curve
        let curveTo:CGFloat = rect.size.height

        let myBezier = UIBezierPath()
        myBezier.move(to: CGPoint(x: 0, y: y))
        myBezier.addQuadCurve(to: CGPoint(x: rect.width, y: y), controlPoint: CGPoint(x: rect.width / 2, y: curveTo))
        myBezier.addLine(to: CGPoint(x: rect.width, y: 0))
        myBezier.addLine(to: CGPoint(x: 0, y: 0))
        myBezier.close()

        let maskForPath = CAShapeLayer()
        maskForPath.path = myBezier.cgPath
        layer.mask = maskForPath      
    }
    }

我希望ProgrammaticVC看起来与StoryboardVC相同(除了颜色不同)

可以在此处找到示例项目: https://github.com/belamatedotdotipa/CurveTest2

1 个答案:

答案 0 :(得分:0)

我建议创建一个子类而不是使用扩展,这是一种特定的行为。

在这种情况下,当您以编程方式添加视图时,您看不到预期的结果,因为在viewDidLoad中您没有视图框架,在此示例中,您可以使用draw函数:

class BottomCurveView: UIView {

    @IBInspectable var curve: CGFloat = 40.0 {
        didSet {
            setNeedsLayout()
        }
    }

    override func draw(_ rect: CGRect) {
        setBottomCurve()
    }

    private func setBottomCurve() {
        let rect = bounds
        let y: CGFloat = rect.size.height - curve
        let curveTo: CGFloat = rect.size.height

        let myBezier = UIBezierPath()
        myBezier.move(to: CGPoint(x: 0, y: y))
        myBezier.addQuadCurve(to: CGPoint(x: rect.width, y: y), controlPoint: CGPoint(x: rect.width / 2, y: curveTo))
        myBezier.addLine(to: CGPoint(x: rect.width, y: 0))
        myBezier.addLine(to: CGPoint(x: 0, y: 0))
        myBezier.close()

        let maskForPath = CAShapeLayer()
        maskForPath.path = myBezier.cgPath
        layer.mask = maskForPath
    }
}