【问题标题】:Create a UIView with only one diagonal side创建一个只有一个对角边的 UIView
【发布时间】:2014-10-13 12:23:25
【问题描述】:

我需要创建一个 UIView,它的左边框倾斜 45 度 我想知道,有没有办法以编程方式实现这一目标? CATransform3D 在这种情况下是否对我有帮助,因为它不是真正的“3D 旋转”?

编辑

这是一张图片,解释了我需要的更多输出

【问题讨论】:

  • 这可以有多种解释。你有你想要的照片吗?这可能是直角三角形,或菱形等...所有可能的编程方式不使用变换,但我们需要一张图片(或更好的解释)才能回答。
  • 使用转换会扭曲视图的内容,这可能不是您想要的。
  • 感谢@Fogmeister 的回复,我加了一张图片
  • @JamesSnook 这个 UIView 不会有内容.. 它只是用于覆盖..
  • 我想继承 UIView 并覆盖 drawRect 是解决您的问题的最佳方法...

标签: ios swift uiview cashapelayer diagonal


【解决方案1】:

如果您只想要没有内容的形状,那么您可以创建一个CAShapeLayer 并将其添加到您的视图层。 (其实你也可以用这个方法把内容放在那里,但是你需要稍微改动一下)。

CAShapeLayer *layer = [CAShapeLayer layer];

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(0, 100)]; // bottom left corner
[path addLineToPoint:CGPointMake(100, 0)]; // top middle
[path addLineToPoint:CGPointMake(300, 0)]; // top right corner
[path addLineToPoint:CGPointMake(300, 100)]; // bottom right corner
[path closePath];

layer.path = path.CGPath;
layer.fillColor = [UIColor blackColor].CGColor;
layer.strokeColor = nil;

[theView.layer addSubLayer:layer];

这不需要使用drawRect 或任何东西。您必须根据所需的值更改坐标。

您还可以使用UIView 子类并覆盖drawRect。它需要更多的工作,但UIBezierPath 几乎相同。

CALayer 非常强大,被苹果公司大量使用。例如,Pages 中的编辑画布几乎完全使用CALayers 编写。

【讨论】:

  • 这是一个很好的答案!正是我需要的。非常感谢@Fogmeister
  • @Chris 不用担心,很乐意提供帮助。谢谢
  • @Fogmeister 当你说你需要稍微改变方法来包含内容时,你到底是什么意思?我正在尝试做一些与此非常相似的事情,但里面有内容
  • @Fogmeister 。你的逻辑对我帮助很大。我有一些疑问
  • 如何让100.0点四舍五入? - 像cornerRadius一样?
【解决方案2】:

Resulted shape

Swift5 中的代码

    -

 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: 30)
    let pointB = CGPoint(x: 20, y: 0)
    let pointC = CGPoint(x: layerWidth, y: 0)
    let pointD = CGPoint(x: layerWidth, y:30)
    // 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
}
}

【讨论】:

    【解决方案3】:

    实现这一目标的最短方法可能是采取以下步骤:

    1. 子类UIView
    2. 覆盖 drawRect 为视图提供自定义绘图
    3. 在drawRect 中,使用Core Graphics API,它允许您在绘图上下文中绘制自定义形状,并提供rotation 或scaling 等功能

    Here is an overview of the API from the Apple docs.

    【讨论】:

      【解决方案4】:

      我想提供一个使用 Swift 5 的代码示例,说明如何在 UIViewController 中实现它,全部使用带有 UIKit 的编程 UI。对我来说,我错过的关键组件是在您创建 CAShapeLayer 并将其添加到视图层的地方,如果您在 UIView 或 viewDidLayoutSubviews() 中进行操作,则必须在 layoutSubviews() 中调用它。 '在UIViewController 中创建形状。您需要熟悉如何使用 UIBezierPath 来了解绘图机制。

      以下是我认为最有用的资源:

      Apple Docs on UIBezierPath

      Medium Blog write up on UIBezierPath

      import UIKit
      
      class ViewController: UIViewController {
          var diagonalSideView: UIView = {
              let view = UIView()
              view.translatesAutoresizingMaskIntoConstraints = false
              view.backgroundColor = .black
              return view
          }()
      
          override func viewDidLoad() {
              super.viewDidLoad()
              setupViews()
          }
      
          override func viewDidLayoutSubviews() {
              super.viewDidLayoutSubviews()
              makeDiagonalDividerShape(from: diagonalSideView)
          }
      
          private func setupViews() {
              view.addSubview(diagonalSideView)
      
              let heightConstraint = diagonalSideView.heightAnchor.constraint(equalToConstant: 200)
              let leftConstraint = diagonalSideView.leftAnchor.constraint(equalTo: view.leftAnchor)
              let rightConstraint = diagonalSideView.rightAnchor.constraint(equalTo: view.rightAnchor)
              let centerXConstraint = diagonalSideView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
              let centerYConstraint = diagonalSideView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
      
              NSLayoutConstraint.activate([heightConstraint,
                                           leftConstraint,
                                           rightConstraint,
                                           centerXConstraint,
                                           centerYConstraint])
          }
      
          private func makeDiagonalDividerShape(from view: UIView) {
              let layer = CAShapeLayer()
      
              // Create Path
              let bezierPath = UIBezierPath()
      
              //  Points of the Polygon with Diagonal left side
              let pointA = CGPoint(x: view.bounds.origin.x, y: view.bounds.height)
              let pointB = CGPoint(x: view.bounds.width / 4, y: view.bounds.origin.y)
              let pointC = CGPoint(x: view.bounds.width, y: view.bounds.origin.y)
              let pointD = CGPoint(x: view.bounds.width, y: view.bounds.height)
      
              // Draw the path
              bezierPath.move(to: pointA)
              bezierPath.addLine(to: pointB)
              bezierPath.addLine(to: pointC)
              bezierPath.addLine(to: pointD)
              bezierPath.close()
      
              // Create the mask
              layer.path = bezierPath.cgPath
              view.layer.mask = layer
          }
      }
      

      最终结果:

      【讨论】:

        猜你喜欢
        • 2019-09-09
        • 1970-01-01
        • 1970-01-01
        • 2018-07-02
        • 1970-01-01
        • 1970-01-01
        • 2015-06-19
        • 2015-03-25
        • 1970-01-01
        相关资源
        最近更新 更多