forked from ooleynich/OOButtonNode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOOButtonNode.swift
More file actions
171 lines (140 loc) · 4.18 KB
/
OOButtonNode.swift
File metadata and controls
171 lines (140 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//
// ButtonNode.swift
// Words
//
// Created by Oleg on 26/10/2017.
// Copyright © 2017 Oleg. All rights reserved.
//
import SpriteKit
public enum OOButtonState {
case normal
case pressed
case disabled
func defaultTextColor() -> UIColor {
switch self {
case .normal:
return UIColor.blue
case .pressed:
return UIColor.white
case .disabled:
return UIColor.gray
}
}
}
final public class OOButtonNode: SKNode {
//MARK: Public Properties
public var size = CGSize.zero {
didSet {
resizeBackground()
}
}
public var font = UIFont.systemFont(ofSize: 10.0) {
didSet {
label.fontName = font.fontName
label.fontSize = font.pointSize
}
}
public var pressedScale: CGFloat = 1.0
public var pressedBlock: ((OOButtonNode) -> Void)?
public var enabled = true {
didSet {
enabledChanged()
}
}
//MARK: Private Properties
fileprivate var state = OOButtonState.normal {
didSet {
stateChanged()
}
}
fileprivate var titles = [OOButtonState: String]()
fileprivate var titleColors = [OOButtonState: UIColor]()
fileprivate var backgrounds = [OOButtonState: SKSpriteNode]()
fileprivate let label = SKLabelNode()
fileprivate var backgroundNode: SKSpriteNode? {
didSet {
if let oldBG = oldValue {
oldBG.removeFromParent()
}
}
}
//MARK: Public Methods
public func setTitle(_ title: String, for state: OOButtonState) {
titles[state] = title
updateLabel()
}
public func setTitleColor(_ titleColor: UIColor, for state: OOButtonState) {
titleColors[state] = titleColor
updateLabel()
}
public func setBackgroundColor(_ backgroundColor: UIColor, for state: OOButtonState) {
let node = SKSpriteNode(color: backgroundColor, size: size)
node.zPosition = -100.0
backgrounds[state] = node
updateBackground()
}
public func setImage(_ image: UIImage, for state: OOButtonState) {
let node = SKSpriteNode(texture: SKTexture(image: image))
node.zPosition = -100.0
backgrounds[state] = node
updateBackground()
}
//MARK: Lifecycle
public override init() {
super.init()
setupUI()
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupUI()
}
override public func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
state = .pressed
}
override public func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let location = touch.location(in: parent!)
if self.contains(location) {
pressedBlock?(self)
}
}
state = .normal
}
}
fileprivate extension OOButtonNode {
func setupUI() {
isUserInteractionEnabled = true
label.verticalAlignmentMode = .center
addChild(label)
state = .normal
}
func stateChanged() {
updateLabel()
updateBackground()
}
func updateLabel() {
label.text = titles[state] ?? titles[.normal] ?? ""
label.fontColor = titleColors[state] ?? state.defaultTextColor()
}
func updateBackground() {
if let background = backgrounds[state], background != backgroundNode {
backgroundNode = background
addChild(backgroundNode!)
changeScale()
} else if backgrounds[.normal] != nil {
changeScale()
}
}
func resizeBackground() {
backgrounds.values.forEach { $0.size = size }
}
func changeScale() {
let newScale = state == .pressed ? pressedScale : 1.0
backgroundNode?.xScale = newScale
backgroundNode?.yScale = newScale
}
func enabledChanged() {
isUserInteractionEnabled = enabled
state = enabled ? .normal : .disabled
}
}