|
// |
|
// ButtonNode.swift |
|
// Created by Stoyan Stoyanov on 27.11.17. |
|
|
|
import SpriteKit |
|
|
|
//MARK: - Action Types |
|
|
|
extension ButtonNode { |
|
|
|
enum ActionType { |
|
case touchUpInside |
|
case touchDown |
|
case touchUp |
|
} |
|
} |
|
|
|
//MARK: - Life Cycle |
|
|
|
class ButtonNode: SKSpriteNode { |
|
|
|
var defaultTexture: SKTexture |
|
var selectedTexture: SKTexture? |
|
var disabledTexture: SKTexture? |
|
|
|
fileprivate(set) var label: SKLabelNode |
|
|
|
// action related properties |
|
var triggerType: ActionType = .touchUpInside |
|
var action: (() -> Void)? |
|
|
|
// state related properties |
|
var isEnabled: Bool = true { |
|
didSet { if (disabledTexture != nil) { texture = isEnabled ? defaultTexture : disabledTexture } } |
|
} |
|
|
|
var isSelected: Bool = false { |
|
didSet { texture = isSelected ? (selectedTexture ?? defaultTexture) : defaultTexture } |
|
} |
|
|
|
init(normalTexture defaultTexture: SKTexture, selectedTexture: SKTexture, size: CGSize? = nil, disabledTexture: SKTexture? = nil) { |
|
|
|
self.defaultTexture = defaultTexture |
|
self.selectedTexture = selectedTexture |
|
self.disabledTexture = disabledTexture |
|
label = SKLabelNode(fontNamed: "Helvetica") |
|
|
|
super.init(texture: defaultTexture, color: .white, size: size ?? defaultTexture.size()) |
|
isUserInteractionEnabled = true |
|
|
|
label.verticalAlignmentMode = .center |
|
label.horizontalAlignmentMode = .center |
|
label.zPosition = 1 |
|
addChild(label) |
|
} |
|
|
|
required init(coder: NSCoder) { fatalError("NSCoding not supported") } |
|
} |
|
|
|
//MARK: - Setters |
|
|
|
extension ButtonNode { |
|
|
|
func setAction(triggerEvent event: ActionType, action: @escaping () -> Void) { |
|
triggerType = event |
|
self.action = action |
|
} |
|
|
|
func setButtonLabel(title: String, font: String, fontSize: CGFloat) { |
|
label.text = title |
|
label.fontSize = fontSize |
|
label.fontName = font |
|
} |
|
} |
|
|
|
//MARK: - Touch Handling |
|
|
|
extension ButtonNode { |
|
|
|
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { |
|
guard isEnabled else { return } |
|
isSelected = true |
|
|
|
if triggerType == .touchDown { |
|
action?() |
|
} |
|
} |
|
|
|
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { |
|
|
|
guard isEnabled else { return } |
|
guard let touch = touches.first else { return } |
|
guard let parent = parent else { return } |
|
|
|
let touchLocation = touch.location(in: parent) |
|
|
|
if (frame.contains(touchLocation)) { |
|
isSelected = true |
|
} else { |
|
isSelected = false |
|
} |
|
} |
|
|
|
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { |
|
|
|
guard isEnabled else { return } |
|
isSelected = false |
|
|
|
if triggerType == .touchUpInside { |
|
guard let touch = touches.first else { return } |
|
guard let parent = parent else { return } |
|
let touchLocation = touch.location(in: parent) |
|
|
|
if (frame.contains(touchLocation) ) { |
|
action?() |
|
} |
|
} else if triggerType == .touchUp { |
|
action?() |
|
} |
|
} |
|
} |
works well in Xcode 9, Swift 4