制作一个形状为 CAShapeLayer 的 UIButton [英] Making a UIButton with shape CAShapeLayer

查看:22
本文介绍了制作一个形状为 CAShapeLayer 的 UIButton的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在制作一种基于六边形的简单游戏.这是它的样子:

So I'm making a kind of simple game based on hexagons. Here's what it looks like:

我已经设法按照我想要的方式绘制六边形作为 CAShapeLayers,但我想让它们可点击.简而言之,我想以某种方式将它们投射到 UIButtons 中,以便我可以通过 touchUpInside 跟踪选择了哪个.我能想到的另一种方法是跟踪触摸并检查它们是否在带有标签的形状中,但这似乎很复杂.下面是我的代码:

I've managed to draw the hexagons exactly the way I want them as CAShapeLayers, but I'd like to make them clickable. In short I would like to cast them somehow into UIButtons so I can track which one is selected via touchUpInside. The other way I can think of doing it is track touches and check if they were in the shape with tag, but it seems way to complicated. Below is my code:

        let screenSize: CGRect = UIScreen.mainScreen().bounds
        let screenWidth = screenSize.width
        let screenHeight = screenSize.height

        let radius : CGFloat = screenWidth/6

        var c = 0

        var counter = 0

        for j in 1...6 {
            for i in 1...3 {

                for x in 1...2 {

                    var center = CGPoint(x: CGFloat((i-1)*2)*radius+CGFloat(i-1)*radius, y: CGFloat((j-1)*2)*radius)

                    if (x==2) {
                        center.x = center.x+1.5*radius
                        center.y = center.y+radius
                    }



                    let shape = CAShapeLayer()
                    view.layer.addSublayer(shape)
                    shape.opacity = 0.5
                    shape.lineWidth = 2
                    shape.lineJoin = kCALineJoinMiter
                    shape.strokeColor = UIColor(hue: 0.786, saturation: 0.79, brightness: 0.53, alpha: 1.0).CGColor
                    shape.fillColor = UIColor(hue: 0.786, saturation: 0.15, brightness: 0.89, alpha: 1.0).CGColor


                    let path = UIBezierPath()
                    path.moveToPoint(CGPointMake(center.x-radius, center.y))
                    path.addLineToPoint(CGPointMake(center.x-radius/2, center.y-radius))
                    path.addLineToPoint(CGPointMake(center.x+radius/2, center.y-radius))
                    path.addLineToPoint(CGPointMake(center.x+radius, center.y))
                    path.addLineToPoint(CGPointMake(center.x+radius, center.y))
                    path.addLineToPoint(CGPointMake(center.x+radius/2, center.y+radius))
                    path.addLineToPoint(CGPointMake(center.x-radius/2, center.y+radius))

                    path.closePath()
                    shape.path = path.CGPath



                }


            }

        }

推荐答案

我能想到的另一种方法是跟踪触摸并检查它们是否在带有标签的形状中,但这似乎很复杂

The other way I can think of doing it is track touches and check if they were in the shape with tag, but it seems way to complicated

好的,但问题是您选择对图层执行此操作,而图层根本不检测触摸,因此很难看出还有哪些其他选择可供您选择.您不能将图层投射"到按钮中;如果你想要按钮或视图来检测自己的点击,你应该使用按钮或视图,不是层.

Okay, but the problem is that you've chosen to do this with layers, and layers do not detect touches at all, so it's hard to see what other choice is open to you. You cannot "cast" a layer into a button; if you wanted buttons, or views that detect taps on themselves, you should have used buttons or views, not layers.

例如,如果您使用自定义 UIView,它可以使用您的形状图层作为其图层并实施命中测试以确定点击是否落在形状图层的六边形路径内.下面是一个让您入门的示例:

If you use a custom UIView, for example, it can use your shape layer as its layer and implement hit-testing to determine whether a tap falls within the shape layer's hexagon path. Here's an example to get you started:

class HexButton: UIView {

    var path: UIBezierPath!

    override class func layerClass() -> AnyClass {
        return CAShapeLayer.self
    }

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

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

    func finishInitialization() {
        let shape = self.layer as! CAShapeLayer
        shape.opacity = 0.5
        shape.lineWidth = 2
        shape.lineJoin = kCALineJoinMiter
        shape.strokeColor = UIColor(hue: 0.786, saturation: 0.79, brightness: 0.53, alpha: 1.0).CGColor
        shape.fillColor = UIColor(hue: 0.786, saturation: 0.15, brightness: 0.89, alpha: 1.0).CGColor

        let center = CGPoint(x:self.bounds.midX, y: self.bounds.midY)
        let radius = self.bounds.width/2.0

        let path = UIBezierPath()
        path.moveToPoint(CGPointMake(center.x-radius, center.y))
        path.addLineToPoint(CGPointMake(center.x-radius/2, center.y-radius))
        path.addLineToPoint(CGPointMake(center.x+radius/2, center.y-radius))
        path.addLineToPoint(CGPointMake(center.x+radius, center.y))
        path.addLineToPoint(CGPointMake(center.x+radius, center.y))
        path.addLineToPoint(CGPointMake(center.x+radius/2, center.y+radius))
        path.addLineToPoint(CGPointMake(center.x-radius/2, center.y+radius))

        path.closePath()
        shape.path = path.CGPath

        self.path = path

    }

    override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
        return self.path.containsPoint(point) ? self : nil
    }

}

如果您将点击手势识别器附加到该视图,您将看到它仅在点击位于六边形内部时触发.

If you attach a tap gesture recognizer to that view, you will see that it fires only if the tap is inside the hexagon.

这篇关于制作一个形状为 CAShapeLayer 的 UIButton的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆