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

问题描述 投票:0回答:1

我有一个扩展曲线视图的底部边缘,因为这个样式用于我试图创建的应用程序中的多个屏幕。

但是,我注意到我只能使用通过界面构建​​器添加的视图。如果我尝试在以编程方式创建的视图上应用它,则它们不会呈现。

我创建了一个简单的例子来说明问题。主故事板包含两个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

swift user-interface extension-methods curve
1个回答
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
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.