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
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.
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)
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.
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()
}
}