【问题标题】:How to draw parallelogram like figure in iOS?如何在iOS中绘制类似图形的平行四边形?
【发布时间】:2020-07-29 05:57:37
【问题描述】:

我应该达到以下结果:

如您所见,它包含平行四边形(不是矩形)列表,其中包含标签。此外,它可以是动态的,这意味着我可以使用 stackview。首先,让我们画出类似平行四边形的视图:

class ParallelogramView: UIView {

override init(frame: CGRect) {
    super.init(frame: frame)
    backgroundColor = .clear
}


override func draw(_ rect: CGRect) {
    super.draw(rect)
    let path = UIBezierPath()
    /// let's start from this point
    path.move(to: CGPoint(x: 8, y: 0))
    /// drawing horizontal top line till we can
    path.addLine(to: CGPoint(x: rect.maxX, y: 0))
    /// drawing to bottom but little bit to left
    path.addLine(to: CGPoint(x: rect.maxX - 16, y: rect.maxY))
    /// drawing from right to left
    path.addLine(to: CGPoint(x: 0, y: rect.maxY))
    /// connecting all
    path.close()
    
    /// just for sample filling it with some color. I don't know how to change it later :(
    UIColor.red.setFill()
    
    path.fill()
}
}

所有代码都有注释。之后,让我们定义一个LabelView,其中包含我们的平行四边形,其中包含标签。

class LabelView: UIView {

/// out text
lazy var label: UILabel = {
    let label = UILabel()
    label.numberOfLines = 0
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()

/// our parallelogramView
lazy var plView: ParallelogramView = {
    let trView = ParallelogramView()
    trView.translatesAutoresizingMaskIntoConstraints = false
    return trView
}()

override init(frame: CGRect) {
    super.init(frame: frame)
    
    /// adding label to paralleogram
    plView.addSubview(label)
    addSubview(plView)
    
    NSLayoutConstraint.activate([
        plView.leadingAnchor.constraint(equalTo: leadingAnchor),
        plView.trailingAnchor.constraint(equalTo: trailingAnchor),
        plView.bottomAnchor.constraint(equalTo: bottomAnchor),
        plView.topAnchor.constraint(equalTo: topAnchor),
        
        label.leadingAnchor.constraint(equalTo: plView.leadingAnchor, constant: 16),
        label.trailingAnchor.constraint(equalTo: plView.trailingAnchor, constant: -16),
        label.bottomAnchor.constraint(equalTo: plView.bottomAnchor),
        label.topAnchor.constraint(equalTo: plView.topAnchor)
        
        
    ])
    
}

}

好的。我们的观点已经准备好了。现在,我们应该使用对齐填充将其添加到水平堆栈视图中。

for item in ["Text", "Text", "Text"] {
        let labelView = LabelView()
        labelView.label.text = item
        stackView.addArrangedSubview(labelView)
    }

这是我们得到的结果。

这不是想要的结果,因为它有理性的问题。据我了解,iOS中每个视图的框架都是矩形的,不能更改。即使我的 stackview 的间距是 0,我仍然有一种间距(实际上没有),因为无论如何视图都是矩形的。那么,如何实现截图中的结果呢?我做错了什么?

【问题讨论】:

    标签: ios drawing polygon uibezierpath cashapelayer


    【解决方案1】:

    这里有几个问题。

    首先,您绘制的平行四边形有点不准确,左侧有 8 x 的差异,尾部有 16 x 的差异,因此它们不会对齐。你可以这样解决:

    /// drawing to bottom but little bit to left
            path.addLine(to: CGPoint(x: rect.maxX - 8, y: rect.maxY))
    

    第二个是每个视图都应该重叠,因为平行四边形目前完全在边界内。您可以通过设置负间距在堆栈视图中执行此操作:

    stackView.spacing = -8

    另一种方法是让平行四边形延伸到超级视图的边界之外,然后您仍然可以使用原始大小作为其他布局的参考。

    您不能使用draw(_ rect:) 在视图边界之外进行绘制,因此您不能以这种方式展开绘图。

    要为平行四边形设置自定义颜色,请为其指定一个属性,然后在您的绘图代码中使用该属性:

    class ParallelogramView: UIView {
    
        //...
    
        var colour: UIColor = .red
    
        //...
    
        override func draw(_ rect: CGRect) {
            //... the rest of your drawing code
            colour.setFill()
            path.fill()
        }
    }
    
    labelView.plView.colour = .blue
    

    【讨论】:

    • 好的。但是如何动态改变平行四边形的颜色呢?它是由UIBezierPath 绘制的。那么配置时如何访问呢?
    • 最后一个问题。如您所见,根据设计要求,平行四边形有点圆润。我创建了带有圆角的UIBezierPath,如let path = UIBezierPath(roundedRect: rect, byRoundingCorners: [.bottomRight], cornerRadii: CGSize(width: 8, height: 8)),但现在它开始绘制的不是屏幕截图中的平行四边形,而是简单的矩形。可能是什么问题?
    • 这有点复杂,因为你需要在路径中添加一个圆弧并计算开始和结束角度。在这一点上,您最好使用可拉伸的图像作为背景,除非您也有可变高度
    • 为什么是弧形?添加曲线呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-17
    相关资源
    最近更新 更多