Skip to content

Instantly share code, notes, and snippets.

@stoqn4opm
Created November 27, 2017 15:36
Show Gist options
  • Save stoqn4opm/88fd17c9986c4ee7aa4b707f9d892b42 to your computer and use it in GitHub Desktop.
Save stoqn4opm/88fd17c9986c4ee7aa4b707f9d892b42 to your computer and use it in GitHub Desktop.
Implementetation of button for Apple's SpriteKit framework
//
// 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?()
}
}
}
@stoqn4opm
Copy link
Author

works well in Xcode 9, Swift 4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment