web-dev-qa-db-fra.com

Triangle UIView - Swift

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

Je ne peux pas savoir comment créer une vue UIV qui est un triangle. Cependant, j'ai pu le faire fonctionner comme un rectangle comme celui-ci:

 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 savoir comment faire un triangle. La raison pour laquelle je le veux en tant qu'UIView est parce que j'utilise des collisions dessus et que l'utilisateur le déplace. J'ai essayé un triangle PNG mais il détecte la collision comme étant la bordure 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

25
Zog

J'ai un peu modifié le code précédent pour ajouter une marge et une couleur de remplissage 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()
    }
}
8
Abdoelrhman

CAShapeLayer, il peut changer la forme des calques.

    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)
6

J'ai essayé un triangle PNG mais il détecte la collision comme étant la bordure de l'image et non le début du triangle.

Il n'y a rien que vous puissiez faire à ce sujet si vous allez utiliser des collisions simples (par exemple, l'UIKit Dynamics intégré - il le fait niquement collisions de vues rectangulaires). Si vous souhaitez des collisions de formes avancées, vous devez les implémenter vous-même ou utiliser des Sprites.

et pour que l'utilisateur le déplace

C'est beaucoup plus facile à gérer: remplacez simplement hitTest pour cette vue et retournez nil si l'endroit que l'utilisateur touche est en dehors des bordures de l'image du triangle.

1
matt