Triangle UIView - Swift

donc je fais un jeu dans lequel je laisse tomber des objets qui doivent être détruits par une transitoire(triangle) au bas de l'écran par un utilisateur.

Je ne peux pas trouver comment faire un uivi qui est un triangle. Toutefois, j'ai été capable de le faire fonctionner comme un rectangle comme ceci:

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

Et cela a fonctionné. Mais je ne peux pas trouver comment faire un triangle. La raison pour laquelle je le veux comme UIView est parce que j'utilise collisions sur elle et pour l'utilisateur de la déplacer. J'ai essayé un triangle PNG mais il détecte la collision comme le bord de l'image et non le début du triangle.

j'ai essayé mais ça ne marche pas...

 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)

Toute aide sera appréciée,

Merci,

Alex

23
demandé sur Alex 2015-06-04 20:25:21

4 réponses

mise à Jour 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:
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);
       }
 } 

Cela va démarrer à partir de MinX, MaxY;

Tracez une ligne à partir du début de MaxX, MaxY;

Tracez une ligne à partir de MaxX,MaxY de MaxX/2, MinY;

Puis fermer le chemin de l'emplacement de départ.

La partie suivante définit la couleur que vous souhaitez utiliser. Dans cet exemple 255,127,0, Alpha 0,6 Puis remplira le chemin que vous venez de dessiner ci-dessus avec la couleur définie.

puis dans votre contrôleur de vue

Swift 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:
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.
    }
}

cependant, cela va causer le même problème que le cadre de cette vue va encore être un rectangle. UIKit fonctionne avec des rectangles, vous devriez utiliser un autre cadre, comme Sprite Kit.

63
répondu Taylor M 2016-12-10 17:16:33

CAShapeLayer il peut changer la forme des couches.

    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)
5
répondu Shanmugasundharam selvadurai 2015-06-04 19:19:55

j'ai essayé un triangle PNG mais il détecte la collision comme le bord de l'image pas le début du triangle.

il n'y a rien que vous pouvez faire à ce sujet si vous allez utiliser des collisions simples d'esprit (par exemple la dynamique UIKit intégrée-il fait collisions à vue rectangulaire). Si vous voulez des collisions de formes avancées, soit vous devez les implémenter vous-même, soit vous devez utiliser des Sprites.

et pour l'utilisateur déplacer

C'est beaucoup plus facile à gérer: outrepassez simplement hitTest pour ce point de vue et retour nil si l'endroit que l'utilisateur touche est en dehors des limites de l'image du triangle.

1
répondu matt 2015-06-04 17:30:46

j'ai un peu modifié le code précédent pour ajouter marge et remplir couleur comme inspectable et cela fonctionne bien avec 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()
    }
}
1
répondu Abdoelrhman 2017-11-30 17:38:31