在 Swift 中创建对角自定义 UIView

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

我正在致力于快速设计自定义 UIimageview。我想使用类似于此的 beizerpath 创建一个 UIimageview

编码应该是快速的。 任何帮助表示赞赏。谢谢

uiview swift3
3个回答
13
投票

创建一个

CAShapeLayer
并为其提供一个
path
和一个
fillColor
:

@IBDesignable
public class AngleView: UIView {

    @IBInspectable public var fillColor: UIColor = .blue { didSet { setNeedsLayout() } }

    var points: [CGPoint] = [
        .zero,
        CGPoint(x: 1, y: 0),
        CGPoint(x: 1, y: 1),
        CGPoint(x: 0, y: 0.5)
    ] { didSet { setNeedsLayout() } }

    private lazy var shapeLayer: CAShapeLayer = {
        let _shapeLayer = CAShapeLayer()
        self.layer.insertSublayer(_shapeLayer, at: 0)
        return _shapeLayer
    }()

    override public func layoutSubviews() {
        shapeLayer.fillColor = fillColor.cgColor

        guard points.count > 2 else {
            shapeLayer.path = nil
            return
        }

        let path = UIBezierPath()

        path.move(to: convert(relativePoint: points[0]))
        for point in points.dropFirst() {
            path.addLine(to: convert(relativePoint: point))
        }
        path.close()

        shapeLayer.path = path.cgPath
    }

    private func convert(relativePoint point: CGPoint) -> CGPoint {
        return CGPoint(x: point.x * bounds.width + bounds.origin.x, y: point.y * bounds.height + bounds.origin.y)
    }
}

现在,我做了这个可设计(所以如果你把它放在一个单独的框架目标中,你可以在你的故事板中添加这个视图并看到它在那里渲染)。如果您不使用故事板,它仍然有效。这样做很方便:

我还使用了相对坐标(值范围从零到一),并有一种将它们转换为实际坐标的方法,但如果需要,您可以对坐标进行硬编码。但是使用它作为从零到一的值,您将拥有一个可以参与自动布局的角度视图,而无需担心更改特定的坐标值。

最后,一些看似微不足道的小事情,但我在

path
中构造了
layoutSubviews
:这样,当视图大小发生变化(无论是通过自动布局还是编程更改)时,视图将正确地重新渲染。同样,通过使用
didSet
代表
fillColor
points
,如果您更改其中任何一个,视图将会为您重新渲染。

您可以根据需要随意更改此设置,但希望这说明了仅拥有

CAShapeLayer
和自定义
path
的基本想法。


如果您使用

insertSublayer
,则可以将其与 AngleView 的其他子视图组合,例如:


4
投票

我正在使用类似的东西,效果很好,你可以将任何你想要的东西添加到视图中

import UIKit

class CustomView: UIView {

// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
    // Drawing code
    // Get Height and Width
    let layerHeight = layer.frame.height
    let layerWidth = layer.frame.width
    // Create Path
    let bezierPath = UIBezierPath()
    //  Points
    let pointA = CGPoint(x: 0, y: 0)
    let pointB = CGPoint(x: layerWidth, y: 0)
    let pointC = CGPoint(x: layerWidth, y: layerHeight)
    let pointD = CGPoint(x: 0, y: layerHeight*2/3)
    // Draw the path
    bezierPath.move(to: pointA)
    bezierPath.addLine(to: pointB)
    bezierPath.addLine(to: pointC)
    bezierPath.addLine(to: pointD)
    bezierPath.close()
    // Mask to Path
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = bezierPath.cgPath
    layer.mask = shapeLayer
}
}

0
投票

出于此类目的,我将

UIImageView
与 SVG 内容一起使用。

bounds
frame
layer
之类的东西对我来说不适用于不同的屏幕尺寸。如果我正确设置约束,图像视图就会执行我想要的操作,并且由于我使用矢量图像 (SVG),它将正确缩放。

将此片段用于三角形:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" width="100" height="100">
  <polygon points="0,100 100,100 100,100 0,100" fill="white" />

将其另存为 .svg 文件并将其拉入您的资源中。使用此图像将图像视图添加到您的视图中,然后您就准备好了。

© www.soinside.com 2019 - 2024. All rights reserved.