-
Notifications
You must be signed in to change notification settings - Fork 0
/
RadioButtons.swift
121 lines (97 loc) · 3 KB
/
RadioButtons.swift
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
//
// RadioButtons.swift
// pinknoise
//
// Created by Adam Tait on 2/21/18.
// Copyright © 2018 Sisterical Inc. All rights reserved.
//
import Foundation
func wrap<T>(_ before : @escaping () -> Void,
_ fn : @escaping (T) -> Void,
_ after : @escaping () -> Void)
-> (T)
-> Void
{
return { v in
before()
fn(v)
after()
}
}
class RadioButtons
// a collection of mutually exclusively selected/highlighted ButtonVC
// mutually exclusive => only one button is selected at a time
// double selection: when the same button is selected twice in a row, that button is de-selected
{
let buttons : [ButtonVC]
let selectedIndex : MutableProperty<Int>
fileprivate var selectedObservers : [Observable.Ref] = []
// initializers
convenience init(_ btns : [ButtonVC])
{
self.init(btns,
selected: -1) // -1 => none selected. Any value outside 0..<buttons.count will do
}
init(_ btns : [ButtonVC],
selected : Int)
{
self.buttons = btns
self.selectedIndex = MutableProperty<Int>(selected)
// add observers
for i in 0 ..< btns.count
{
let bvc = btns[i]
if i == selected { bvc.selected.set(true) }
let o = newTouchesObserver(buttonVC: bvc, index: i)
_ = bvc.node.touches.addObserver(o)
selectedObservers.append(bvc.selected.addObserver(o))
}
}
// Observers
func newTouchesObserver(buttonVC : ButtonVC,
index i : Int)
-> (_ o: Observable)
-> Void
{
return wrap(
{ // de-activate selected observers
self.selectedObservers.forEach { $0.active.set(false) }
},
{ o in
// de-select current selected VC
if let vc = self.getSelectedVC() {
vc.selected.set(false)
}
if i == self.selectedIndex.get()
{ // double selection
self.selectedIndex.set(-1)
}
else
{ // select new VC
self.selectedIndex.set(i)
buttonVC.selected.set(true)
}
},
{ // re-activate selected observers
self.selectedObservers.forEach { $0.active.set(true) }
})
}
// Find Selected VC
func getSelectedIndex() -> Int?
{
if let i = selectedIndex.get()
{
if buttons.indices.contains(i) { return i }
}
return nil
}
func getSelectedVC() -> ButtonVC?
{
if let i = getSelectedIndex() { return buttons[i] }
return nil
}
func deselectAll()
{
if let vc = getSelectedVC() { vc.selected.set(false) }
}
}