ios 三角形 UIView - Swift

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30650343/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 06:13:32  来源:igfitidea点击:

Triangle UIView - Swift

iosxcodeswiftuiviewios8

提问by Zog

So I'm making a game in which I am dropping objects which have to be destroyed by a spike(triangle) at the bottom of the screen by a user.

所以我正在制作一个游戏,其中我正在丢弃必须由用户在屏幕底部的尖峰(三角形)破坏的对象。

I cannot work out how to make a UIView that is a triangle. However I have been able to make it work as a rectangle like this:

我不知道如何制作一个三角形的 UIView。但是我已经能够使它像这样的矩形工作:

 let barrier = UIView(frame: CGRect(x:125, y: 650, width: 130, height:20))
 barrier.backgroundColor = UIColor.orangeColor()
 view.addSubview(barrier)

And this has worked. But I cannot work out how to make a triangle. The reason I want it as a UIView is because im using collisions on it and for the user to move it. I have tried a PNG triangle but it detects the collision as the border of the image not the start of the triangle.

这已经奏效了。但我不知道如何制作三角形。我想要它作为 UIView 的原因是因为我在它上面使用了碰撞并让用户移动它。我试过一个 PNG 三角形,但它检测到碰撞是图像的边界而不是三角形的开始。

I have tried this but it doesn't work...

我试过这个,但它不起作用......

 let square = UIView(frame: CGPathMoveToPoint(path, nil, 50, 0), CGPathAddLineToPoint(path, nil, 100, 50), CGPathAddLineToPoint(path, nil, 0, 100))
 square.backgroundColor = UIColor.purpleColor()
 view.addSubview(square)

Any and all help will be appreciated,

任何和所有的帮助将不胜感激,

Thanks,

谢谢,

Alex

亚历克斯

回答by Taylor M

Updated for Swift 3:

Swift 3更新:

class TriangleView : UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func draw(_ rect: CGRect) {

        guard let context = UIGraphicsGetCurrentContext() else { return }

        context.beginPath()
        context.move(to: CGPoint(x: rect.minX, y: rect.maxY))
        context.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
        context.addLine(to: CGPoint(x: (rect.maxX / 2.0), y: rect.minY))
        context.closePath()

        context.setFillColor(red: 1.0, green: 0.5, blue: 0.0, alpha: 0.60)
        context.fillPath()
    }
}



Swift 2:斯威夫特2

import UIKit

class TriangleView : UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func drawRect(rect: CGRect) {

        var ctx : CGContextRef = UIGraphicsGetCurrentContext()

        CGContextBeginPath(ctx)
        CGContextMoveToPoint(ctx, CGRectGetMinX(rect), CGRectGetMaxY(rect))
        CGContextAddLineToPoint(ctx, CGRectGetMaxX(rect), CGRectGetMaxY(rect))
        CGContextAddLineToPoint(ctx, (CGRectGetMaxX(rect)/2.0), CGRectGetMinY(rect))
        CGContextClosePath(ctx)

        CGContextSetRGBFillColor(ctx, 1.0, 0.5, 0.0, 0.60);
        CGContextFillPath(ctx);
       }
 } 

This will start from MinX, MaxY;
Draw a line from the start to MaxX, MaxY;
Draw a line from MaxX,MaxY to MaxX/2, MinY;
Then close the path to the start location.

这将从MinX,MaxY开始;
从起点到MaxX、MaxY画一条线;
从 MaxX,MaxY 到 MaxX/2, MinY 画一条线;
然后关闭到起始位置的路径。

The next part sets the color you want to use. In this example 255,127,0, Alpha 0.6 Then will fill the path you just drew above with the set color.

下一部分设置您要使用的颜色。在这个例子中 255,127,0, Alpha 0.6 然后将用设置的颜色填充你刚刚在上面绘制的路径。

Then in your View Controller

然后在您的视图控制器中

Swift 3:

斯威夫特 3

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let triangle = TriangleView(frame: CGRect(x: 10, y: 20, width: 25 , height: 30))
        triangle.backgroundColor = .white
        view.addSubview(triangle)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}



Swift 2:斯威夫特2

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let triangle = TriangleView(frame: CGRectMake(10, 20, 25, 30))
        triangle.backgroundColor = .whiteColor()
        view.addSubview(triangle)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

However, this is going to cause the same problem as the frame of this view is still going to be a rectangle. UIKit works with rectangles, you would have to use another framework, like Sprite Kit.

然而,这将导致同样的问题,因为这个视图的框架仍然是一个矩形。UIKit 适用于矩形,您必须使用另一个框架,例如 Sprite Kit。

回答by Abdoelrhman

I've modified the previous code a bit to add margin and fill color as inspectable and it works well with Swift4:

我稍微修改了之前的代码,将边距和填充颜色添加为可检查的,并且它适用于 Swift4:

import UIKit

@IBDesignable
class TriangleView : UIView {
    var _color: UIColor! = UIColor.blue
    var _margin: CGFloat! = 0

    @IBInspectable var margin: Double {
        get { return Double(_margin)}
        set { _margin = CGFloat(newValue)}
    }


    @IBInspectable var fillColor: UIColor? {
        get { return _color }
        set{ _color = newValue }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func draw(_ rect: CGRect) {

        guard let context = UIGraphicsGetCurrentContext() else { return }

        context.beginPath()
        context.move(to: CGPoint(x: rect.minX + _margin, y: rect.maxY - _margin))
        context.addLine(to: CGPoint(x: rect.maxX - _margin, y: rect.maxY - _margin))
        context.addLine(to: CGPoint(x: (rect.maxX / 2.0), y: rect.minY + _margin))
        context.closePath()

        context.setFillColor(_color.cgColor)
        context.fillPath()
    }
}

回答by Shanmugasundharam

CAShapeLayer it can change the shape of layers.

CAShapeLayer 它可以改变图层的形状。

    var mask = CAShapeLayer()
    mask.frame = self.layer.bounds

    let width = self.layer.frame.size.width
    let height = self.layer.frame.size.height

    var path = CGPathCreateMutable()

    CGPathMoveToPoint(path, nil, 30, 0)
    CGPathAddLineToPoint(path, nil, width, 0)
    CGPathAddLineToPoint(path, nil, width, height)
    CGPathAddLineToPoint(path, nil, 0, height)
    CGPathAddLineToPoint(path, nil, 30, 0)

    mask.path = path

    // CGPathRelease(path); - not needed

    self.layer.mask = mask

    var shape = CAShapeLayer()
    shape.frame = self.bounds
    shape.path = path
    shape.lineWidth = 3.0
    shape.strokeColor = UIColor.whiteColor().CGColor
    shape.fillColor = UIColor.clearColor().CGColor

    self.layer.insertSublayer(shape, atIndex: 0)

回答by Saifan Nadaf

Swift 5:

斯威夫特 5:

This code worked for me for different sides. for UIViewusing CGMutablePath()and CAShapeLayer()

这段代码适用于我的不同方面。用于UIView使用CGMutablePath()CAShapeLayer()

*Assuming your view's height and width are same.

*假设您的视图的高度和宽度相同。

*Set your views's background color as clearColor.

*将视图的背景颜色设置为 clearColor。

A) Right Side

A) 右侧

 @IBOutlet weak var triangleView: UIView!

 override func viewDidLoad() {
        super.viewDidLoad()
        self.setRightTriangle()   
    }

 func setRightTriangle(){
        let heightWidth = triangleView.frame.size.width //you can use triangleView.frame.size.height
        let path = CGMutablePath()

        path.move(to: CGPoint(x: heightWidth/2, y: 0))
        path.addLine(to: CGPoint(x:heightWidth, y: heightWidth/2))
        path.addLine(to: CGPoint(x:heightWidth/2, y:heightWidth))
        path.addLine(to: CGPoint(x:heightWidth/2, y:0))

        let shape = CAShapeLayer()
        shape.path = path
        shape.fillColor = UIColor.blue.cgColor

        triangleView.layer.insertSublayer(shape, at: 0)
    }

enter image description here

在此处输入图片说明



B) Left Side

B) 左侧

 func setLeftTriangle(){
        let heightWidth = triangleView.frame.size.width
        let path = CGMutablePath()

        path.move(to: CGPoint(x: heightWidth/2, y: 0))
        path.addLine(to: CGPoint(x:0, y: heightWidth/2))
        path.addLine(to: CGPoint(x:heightWidth/2, y:heightWidth))
        path.addLine(to: CGPoint(x:heightWidth/2, y:0))

        let shape = CAShapeLayer()
        shape.path = path
        shape.fillColor = UIColor.blue.cgColor

        triangleView.layer.insertSublayer(shape, at: 0)
    }

enter image description here

在此处输入图片说明



C) Up Side

C) 向上

  func setUpTriangle(){
        let heightWidth = triangleView.frame.size.width
           let path = CGMutablePath()

           path.move(to: CGPoint(x: 0, y: heightWidth))
           path.addLine(to: CGPoint(x:heightWidth/2, y: heightWidth/2))
           path.addLine(to: CGPoint(x:heightWidth, y:heightWidth))
           path.addLine(to: CGPoint(x:0, y:heightWidth))

           let shape = CAShapeLayer()
           shape.path = path
           shape.fillColor = UIColor.blue.cgColor

           triangleView.layer.insertSublayer(shape, at: 0)
       }

enter image description here

在此处输入图片说明



D) Down Side

D) 下侧

  func setDownTriangle(){
        let heightWidth = triangleView.frame.size.width
        let path = CGMutablePath()

        path.move(to: CGPoint(x: 0, y: 0))
        path.addLine(to: CGPoint(x:heightWidth/2, y: heightWidth/2))
        path.addLine(to: CGPoint(x:heightWidth, y:0))
        path.addLine(to: CGPoint(x:0, y:0))

        let shape = CAShapeLayer()
        shape.path = path
        shape.fillColor = UIColor.blue.cgColor

        triangleView.layer.insertSublayer(shape, at: 0)
    }

enter image description here

在此处输入图片说明

*Change X any Y values according to your requirement.

*根据您的要求更改 X 任何 Y 值。

回答by matt

I have tried a PNG triangle but it detects the collision as the border of the image not the start of the triangle.

我试过一个 PNG 三角形,但它检测到碰撞是图像的边界而不是三角形的开始。

There is nothing you can do about that if you're going to use simple-minded collisions (e.g. the built-in UIKit Dynamics - it does onlyrectangular view collisions). If you want advanced shape collisions, either you must implement them yourself or you must use Sprites.

没有什么可以做,如果你要使用头脑简单的碰撞(例如内置的UIKit动力学-它只是矩形视图碰撞)。如果你想要高级形状碰撞,要么你必须自己实现它们,要么你必须使用 Sprites。

and for the user to move it

并让用户移动它

That is much easier to deal with: simply override hitTestfor this view and return nilif the place the user touches is outside the borders of the triangle image.

这更容易处理:只需覆盖hitTest此视图,nil如果用户触摸的位置在三角形图像的边界之外,则返回。