formotion 0.5.1 → 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +24 -0
- data/LIST_OF_ROW_TYPES.md +1 -1
- data/Rakefile +20 -5
- data/app/app_delegate.rb +89 -17
- data/examples/FormModel/.gitignore +5 -0
- data/examples/FormModel/Rakefile +9 -0
- data/examples/FormModel/app/app_delegate.rb +11 -0
- data/examples/FormModel/app/user.rb +18 -0
- data/examples/FormModel/app/users_controller.rb +52 -0
- data/examples/FormModel/spec/main_spec.rb +9 -0
- data/examples/KitchenSink/app/app_delegate.rb +2 -2
- data/gh-pages/assets/css/bootstrap-responsive.css +815 -0
- data/gh-pages/assets/css/bootstrap-responsive.min.css +9 -0
- data/gh-pages/assets/css/bootstrap.css +4983 -0
- data/gh-pages/assets/css/bootstrap.min.css +9 -0
- data/gh-pages/assets/css/formotion.css +117 -0
- data/gh-pages/assets/css/pygments.css +62 -0
- data/gh-pages/assets/img/glyphicons-halflings-white.png +0 -0
- data/gh-pages/assets/img/glyphicons-halflings.png +0 -0
- data/gh-pages/assets/js/bootstrap-alert.js +90 -0
- data/gh-pages/assets/js/bootstrap-button.js +96 -0
- data/gh-pages/assets/js/bootstrap-carousel.js +169 -0
- data/gh-pages/assets/js/bootstrap-collapse.js +157 -0
- data/gh-pages/assets/js/bootstrap-dropdown.js +100 -0
- data/gh-pages/assets/js/bootstrap-modal.js +218 -0
- data/gh-pages/assets/js/bootstrap-popover.js +98 -0
- data/gh-pages/assets/js/bootstrap-scrollspy.js +151 -0
- data/gh-pages/assets/js/bootstrap-tab.js +135 -0
- data/gh-pages/assets/js/bootstrap-tooltip.js +275 -0
- data/gh-pages/assets/js/bootstrap-transition.js +61 -0
- data/gh-pages/assets/js/bootstrap-typeahead.js +285 -0
- data/gh-pages/assets/js/bootstrap.js +1825 -0
- data/gh-pages/assets/js/bootstrap.min.js +6 -0
- data/gh-pages/index.html +205 -0
- data/lib/formotion.rb +15 -2
- data/lib/formotion/base.rb +5 -5
- data/lib/formotion/{form_controller.rb → controller/form_controller.rb} +22 -3
- data/lib/formotion/controller/formable_controller.rb +21 -0
- data/lib/formotion/form/form.rb +31 -8
- data/lib/formotion/form/form_delegate.rb +26 -3
- data/lib/formotion/model/formable.rb +78 -0
- data/lib/formotion/row/row.rb +54 -21
- data/lib/formotion/row/row_cell_builder.rb +1 -1
- data/lib/formotion/row_type/back_row.rb +11 -0
- data/lib/formotion/row_type/base.rb +42 -1
- data/lib/formotion/row_type/button.rb +30 -0
- data/lib/formotion/row_type/check_row.rb +9 -5
- data/lib/formotion/row_type/date_row.rb +5 -0
- data/lib/formotion/row_type/edit_row.rb +14 -0
- data/lib/formotion/row_type/image_row.rb +7 -7
- data/lib/formotion/row_type/options_row.rb +18 -8
- data/lib/formotion/row_type/slider_row.rb +14 -5
- data/lib/formotion/row_type/string_row.rb +17 -5
- data/lib/formotion/row_type/subform_row.rb +16 -0
- data/lib/formotion/row_type/submit_row.rb +1 -24
- data/lib/formotion/row_type/switch_row.rb +10 -2
- data/lib/formotion/row_type/template_row.rb +77 -0
- data/lib/formotion/row_type/text_row.rb +12 -4
- data/lib/formotion/section/section.rb +9 -1
- data/lib/formotion/version.rb +1 -1
- data/spec/form_spec.rb +24 -0
- data/spec/formable_spec.rb +100 -0
- data/spec/functional/formable_controller_spec.rb +47 -0
- data/spec/functional/image_row_spec.rb +2 -2
- data/spec/functional/subform_row.rb +33 -0
- data/spec/functional/template_row_spec.rb +57 -0
- data/spec/helpers/row_test_helpers.rb +26 -0
- data/spec/row_type/back_spec.rb +31 -0
- data/spec/row_type/check_spec.rb +9 -9
- data/spec/row_type/date_spec.rb +3 -10
- data/spec/row_type/email_spec.rb +1 -9
- data/spec/row_type/image_spec.rb +3 -12
- data/spec/row_type/number_spec.rb +1 -9
- data/spec/row_type/options_spec.rb +18 -10
- data/spec/row_type/phone_spec.rb +1 -9
- data/spec/row_type/picker_spec.rb +2 -11
- data/spec/row_type/slider_spec.rb +11 -10
- data/spec/row_type/static_spec.rb +1 -9
- data/spec/row_type/string_spec.rb +13 -9
- data/spec/row_type/subform_spec.rb +47 -0
- data/spec/row_type/submit_spec.rb +1 -9
- data/spec/row_type/switch_spec.rb +9 -9
- data/spec/row_type/template_spec.rb +14 -0
- data/spec/row_type/text_spec.rb +9 -9
- metadata +58 -6
@@ -0,0 +1,78 @@
|
|
1
|
+
module Formotion
|
2
|
+
module Formable
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
# Relates a property to a RowType.
|
9
|
+
# @param property is the name of the attribute to KVO
|
10
|
+
# @param row_type is the Formotion::RowType to use for that attribute
|
11
|
+
# @param options are the extra options for this model. Keys can include
|
12
|
+
# any usual Formotion::Row keys to override, plus :transform, which is
|
13
|
+
# a single-argument lambda for transforming the row's string value before
|
14
|
+
# it's synced to your model.
|
15
|
+
# EX
|
16
|
+
# form_property :my_title => :string
|
17
|
+
# form_property :my_date => :date, :transform => lambda { |value| some_function(date) }
|
18
|
+
def form_property(property, row_type, options = {})
|
19
|
+
self.form_properties << { property: property, row_type: row_type}.merge(options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def form_properties
|
23
|
+
@form_properties ||= []
|
24
|
+
end
|
25
|
+
|
26
|
+
# Sets the top bar title for this model
|
27
|
+
# EX
|
28
|
+
# form_title "Some Settings"
|
29
|
+
def form_title(title = -1)
|
30
|
+
@form_title = title if title != -1
|
31
|
+
@form_title
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Creates a Formotion::Form out of the model
|
36
|
+
def to_form
|
37
|
+
rows = self.class.form_properties.collect { |options|
|
38
|
+
{
|
39
|
+
title: options[:property].capitalize,
|
40
|
+
key: options[:property],
|
41
|
+
type: options[:row_type],
|
42
|
+
value: self.send(options[:property])
|
43
|
+
}.merge(options)
|
44
|
+
}
|
45
|
+
form_hash = {
|
46
|
+
title: self.class.form_title || self.class.to_s.capitalize,
|
47
|
+
sections: [{
|
48
|
+
rows: rows
|
49
|
+
}]
|
50
|
+
}
|
51
|
+
|
52
|
+
form = Formotion::Form.new(form_hash)
|
53
|
+
form.on_submit do
|
54
|
+
self.on_submit
|
55
|
+
end
|
56
|
+
|
57
|
+
# Use the :transform lambdas passed in form_property
|
58
|
+
form.sections.first.rows.each_with_index { |row, index|
|
59
|
+
row.instance_variable_set("@formable_options", self.class.form_properties[index])
|
60
|
+
if self.class.form_properties[index][:transform]
|
61
|
+
row.class.send(:alias_method, :old_value_setter, :value=)
|
62
|
+
row.instance_eval do
|
63
|
+
def value=(value)
|
64
|
+
old_value_setter(@formable_options[:transform].call(value))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
}
|
69
|
+
|
70
|
+
form
|
71
|
+
end
|
72
|
+
|
73
|
+
# what happens when the form is submitted?
|
74
|
+
def on_submit
|
75
|
+
p "need to implement on_submit in your Formable model #{self.class.to_s}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/formotion/row/row.rb
CHANGED
@@ -16,6 +16,8 @@ module Formotion
|
|
16
16
|
# Stores possible formatting information (used by date pickers, etc)
|
17
17
|
# if :type == :date, accepts values in [:short, :medium, :long, :full]
|
18
18
|
:format,
|
19
|
+
# alternative title for row (only used in EditRow for now)
|
20
|
+
:alt_title,
|
19
21
|
|
20
22
|
# The following apply only to text-input fields
|
21
23
|
|
@@ -38,8 +40,8 @@ module Formotion
|
|
38
40
|
:clear_button,
|
39
41
|
# row height as integer; used for heightForRowAtIndexPath
|
40
42
|
# EX 200
|
41
|
-
# DEFAULT is nil, which is used as the tableView.
|
42
|
-
:
|
43
|
+
# DEFAULT is nil, which is used as the tableView.row_height
|
44
|
+
:row_height,
|
43
45
|
# range used for slider min and max value
|
44
46
|
# EX (1..100)
|
45
47
|
# DEFAULT is (1..10)
|
@@ -48,11 +50,30 @@ module Formotion
|
|
48
50
|
# EX ['free', 'pro']
|
49
51
|
# DEFAULT is []
|
50
52
|
:items,
|
53
|
+
# A hash for a Form used for subforms
|
54
|
+
# DEFAULT is nil
|
55
|
+
:subform,
|
56
|
+
# A hash for a Row used for templates
|
57
|
+
# DEFAULT is nil
|
58
|
+
:template,
|
59
|
+
# Indents row when set to true
|
60
|
+
# DEFAULT is false
|
61
|
+
:indented,
|
62
|
+
# Shows a delete sign next to the row
|
63
|
+
# DEFAULT is false
|
64
|
+
:deletable,
|
65
|
+
# When a row is deleted, actually remove the row from UI
|
66
|
+
# instead of just nil'ing the value.
|
67
|
+
# DEFAULT is false EXCEPT for template-generated rows
|
68
|
+
:remove_on_delete
|
51
69
|
]
|
52
70
|
PROPERTIES.each {|prop|
|
53
71
|
attr_accessor prop
|
54
72
|
}
|
55
|
-
BOOLEAN_PROPERTIES = [:secure]
|
73
|
+
BOOLEAN_PROPERTIES = [:secure, :indented, :deletable, :remove_on_delete]
|
74
|
+
BOOLEAN_PROPERTIES.each { |prop|
|
75
|
+
alias_method "#{prop}?", prop
|
76
|
+
}
|
56
77
|
SERIALIZE_PROPERTIES = PROPERTIES
|
57
78
|
|
58
79
|
# Reference to the row's section
|
@@ -78,31 +99,27 @@ module Formotion
|
|
78
99
|
# starts editing #text_field.
|
79
100
|
attr_accessor :on_begin_callback
|
80
101
|
|
81
|
-
#
|
102
|
+
# RowType object
|
82
103
|
attr_accessor :object
|
83
104
|
|
105
|
+
# Owning template row, if applicable
|
106
|
+
attr_accessor :template_parent
|
107
|
+
|
84
108
|
def initialize(params = {})
|
85
109
|
super
|
86
110
|
|
87
|
-
BOOLEAN_PROPERTIES.each {|prop|
|
111
|
+
BOOLEAN_PROPERTIES.each { |prop|
|
88
112
|
Formotion::Conditions.assert_nil_or_boolean(self.send(prop))
|
89
113
|
}
|
90
114
|
end
|
91
115
|
|
92
|
-
#
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
# row.checkable?
|
99
|
-
# => nil
|
100
|
-
def method_missing(method, *args, &block)
|
101
|
-
boolean_method = (method.to_s[0..-2]).to_sym
|
102
|
-
if BOOLEAN_PROPERTIES.member? boolean_method
|
103
|
-
return self.send(boolean_method)
|
116
|
+
# called after section and index have been assigned
|
117
|
+
def after_create
|
118
|
+
if self.type == :template and (self.value && self.value.any?)
|
119
|
+
self.value.each do |value|
|
120
|
+
new_row = self.object.build_new_row({:value => value})
|
121
|
+
end
|
104
122
|
end
|
105
|
-
super
|
106
123
|
end
|
107
124
|
|
108
125
|
#########################
|
@@ -117,7 +134,7 @@ module Formotion
|
|
117
134
|
end
|
118
135
|
|
119
136
|
def reuse_identifier
|
120
|
-
@reuse_identifier || "
|
137
|
+
@reuse_identifier || "Formotion_#{self.object_id}"
|
121
138
|
end
|
122
139
|
|
123
140
|
def next_row
|
@@ -139,8 +156,8 @@ module Formotion
|
|
139
156
|
nil
|
140
157
|
end
|
141
158
|
|
142
|
-
def
|
143
|
-
object.
|
159
|
+
def button?
|
160
|
+
object.button?
|
144
161
|
end
|
145
162
|
|
146
163
|
#########################
|
@@ -194,6 +211,22 @@ module Formotion
|
|
194
211
|
super
|
195
212
|
end
|
196
213
|
|
214
|
+
def subform=(subform)
|
215
|
+
@subform = subform
|
216
|
+
# enables you do to row.subform.to_form
|
217
|
+
@subform.instance_eval do
|
218
|
+
def to_form
|
219
|
+
return @hash_subform if @hash_subform
|
220
|
+
if self.is_a? Hash
|
221
|
+
@hash_subform = Formotion::Form.new(self)
|
222
|
+
elsif not self.is_a? Formotion::Form
|
223
|
+
raise Formotion::InvalidClassError, "Attempted subform = '#{self.inspect}' should be of type Formotion::Form or Hash"
|
224
|
+
end
|
225
|
+
@hash_subform ||= self
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
197
230
|
private
|
198
231
|
def const_int_get(base, value)
|
199
232
|
return value if value.is_a? Integer
|
@@ -15,7 +15,7 @@ module Formotion
|
|
15
15
|
|
16
16
|
cell = UITableViewCell.alloc.initWithStyle(row.object.cell_style, reuseIdentifier:row.reuse_identifier)
|
17
17
|
|
18
|
-
cell.accessoryType = UITableViewCellAccessoryNone
|
18
|
+
cell.accessoryType = cell.editingAccessoryType = UITableViewCellAccessoryNone
|
19
19
|
cell.textLabel.text = row.title
|
20
20
|
cell.detailTextLabel.text = row.subtitle
|
21
21
|
|
@@ -3,6 +3,8 @@ module Formotion
|
|
3
3
|
class Base
|
4
4
|
attr_accessor :row, :tableView
|
5
5
|
|
6
|
+
FIELD_BUFFER = Device.iphone? ? 20 : 64
|
7
|
+
|
6
8
|
def tableView
|
7
9
|
@tableView ||= self.row.form.table
|
8
10
|
end
|
@@ -11,7 +13,7 @@ module Formotion
|
|
11
13
|
@row = row
|
12
14
|
end
|
13
15
|
|
14
|
-
def
|
16
|
+
def button?
|
15
17
|
false
|
16
18
|
end
|
17
19
|
|
@@ -20,6 +22,16 @@ module Formotion
|
|
20
22
|
UITableViewCellStyleSubtitle
|
21
23
|
end
|
22
24
|
|
25
|
+
# Sets the UITableViewCellEditingStyle
|
26
|
+
def cellEditingStyle
|
27
|
+
row.deletable? ? UITableViewCellEditingStyleDelete : UITableViewCellEditingStyleNone
|
28
|
+
end
|
29
|
+
|
30
|
+
# Indents row while editing
|
31
|
+
def indentWhileEditing?
|
32
|
+
row.indented?
|
33
|
+
end
|
34
|
+
|
23
35
|
# builder method for row cell specific implementation
|
24
36
|
def build_cell(cell)
|
25
37
|
# implement in row class
|
@@ -36,6 +48,35 @@ module Formotion
|
|
36
48
|
def on_select(tableView, tableViewDelegate)
|
37
49
|
# implement in row class
|
38
50
|
end
|
51
|
+
|
52
|
+
# called when the delete editing style was triggered tableView:commitEditingStyle:forRowAtIndexPath:
|
53
|
+
def on_delete(tableView, tableViewDelegate)
|
54
|
+
if row.remove_on_delete?
|
55
|
+
row.section.rows.delete_at(row.index)
|
56
|
+
row.section.refresh_row_indexes
|
57
|
+
delete_row
|
58
|
+
else
|
59
|
+
row.value = nil
|
60
|
+
self.tableView.reloadData
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def delete_row
|
65
|
+
tableView.beginUpdates
|
66
|
+
tableView.deleteRowsAtIndexPaths [row.index_path], withRowAnimation:UITableViewRowAnimationBottom
|
67
|
+
tableView.endUpdates
|
68
|
+
end
|
69
|
+
|
70
|
+
def break_with_semaphore(&block)
|
71
|
+
return if @semaphore
|
72
|
+
with_semaphore(&block)
|
73
|
+
end
|
74
|
+
|
75
|
+
def with_semaphore(&block)
|
76
|
+
@semaphore = true
|
77
|
+
block.call
|
78
|
+
@semaphore = false
|
79
|
+
end
|
39
80
|
end
|
40
81
|
end
|
41
82
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Formotion
|
2
|
+
module RowType
|
3
|
+
class Button < Base
|
4
|
+
|
5
|
+
def button?
|
6
|
+
true
|
7
|
+
end
|
8
|
+
|
9
|
+
# Does a clever little trick to override #layoutSubviews
|
10
|
+
# for just this one UITableViewCell object, in order to
|
11
|
+
# center it's labels horizontally.
|
12
|
+
def build_cell(cell)
|
13
|
+
cell.swizzle(:layoutSubviews) do
|
14
|
+
def layoutSubviews
|
15
|
+
old_layoutSubviews
|
16
|
+
|
17
|
+
center = lambda {|frame, dimen|
|
18
|
+
((self.frame.size.send(dimen) - frame.size.send(dimen)) / 2.0)
|
19
|
+
}
|
20
|
+
|
21
|
+
self.textLabel.center = CGPointMake(self.frame.size.width / 2 - (FIELD_BUFFER / 2), self.textLabel.center.y)
|
22
|
+
self.detailTextLabel.center = CGPointMake(self.frame.size.width / 2 - (FIELD_BUFFER / 2), self.detailTextLabel.center.y)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,13 +1,21 @@
|
|
1
1
|
module Formotion
|
2
2
|
module RowType
|
3
3
|
class CheckRow < Base
|
4
|
+
include BW::KVO
|
5
|
+
|
6
|
+
def update_cell_value(cell)
|
7
|
+
cell.accessoryType = cell.editingAccessoryType = row.value ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone
|
8
|
+
end
|
4
9
|
|
5
10
|
# This is actually called whenever again cell is checked/unchecked
|
6
11
|
# in the UITableViewDelegate callbacks. So (for now) don't
|
7
12
|
# instantiate long-lived objects in them.
|
8
13
|
# Maybe that logic should be moved elsewhere?
|
9
14
|
def build_cell(cell)
|
10
|
-
cell
|
15
|
+
update_cell_value(cell)
|
16
|
+
observe(self.row, "value") do |old_value, new_value|
|
17
|
+
update_cell_value(cell)
|
18
|
+
end
|
11
19
|
nil
|
12
20
|
end
|
13
21
|
|
@@ -15,13 +23,9 @@ module Formotion
|
|
15
23
|
if row.section.select_one and !row.value
|
16
24
|
row.section.rows.each do |other_row|
|
17
25
|
other_row.value = (other_row == row)
|
18
|
-
|
19
|
-
cell = tableView.cellForRowAtIndexPath(other_row.index_path)
|
20
|
-
other_row.object.build_cell(cell) if cell
|
21
26
|
end
|
22
27
|
elsif !row.section.select_one
|
23
28
|
row.value = !row.value
|
24
|
-
build_cell(tableView.cellForRowAtIndexPath(row.index_path))
|
25
29
|
end
|
26
30
|
end
|
27
31
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Formotion
|
2
|
+
module RowType
|
3
|
+
class EditRow < Button
|
4
|
+
def on_select(tableView, tableViewDelegate)
|
5
|
+
was_editing = tableView.isEditing
|
6
|
+
if row.alt_title
|
7
|
+
new_title = !was_editing ? row.alt_title : row.title
|
8
|
+
tableView.cellForRowAtIndexPath(row.index_path).textLabel.text = new_title
|
9
|
+
end
|
10
|
+
tableView.setEditing(!was_editing, animated: true)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -11,10 +11,10 @@ module Formotion
|
|
11
11
|
observe(self.row, "value") do |old_value, new_value|
|
12
12
|
@image_view.image = new_value
|
13
13
|
if new_value
|
14
|
-
self.row.
|
15
|
-
cell.accessoryView = nil
|
14
|
+
self.row.row_height = 200
|
15
|
+
cell.accessoryView = cell.editingAccessoryView = nil
|
16
16
|
else
|
17
|
-
self.row.
|
17
|
+
self.row.row_height = 44
|
18
18
|
add_plus_accessory(cell)
|
19
19
|
end
|
20
20
|
row.form.reload_data
|
@@ -36,9 +36,9 @@ module Formotion
|
|
36
36
|
|
37
37
|
field_frame = formotion_field.frame
|
38
38
|
field_frame.origin.y = 10
|
39
|
-
field_frame.origin.x = self.textLabel.frame.origin.x + self.textLabel.frame.size.width +
|
40
|
-
field_frame.size.width = self.frame.size.width - field_frame.origin.x -
|
41
|
-
field_frame.size.height = self.frame.size.height -
|
39
|
+
field_frame.origin.x = self.textLabel.frame.origin.x + self.textLabel.frame.size.width + FIELD_BUFFER
|
40
|
+
field_frame.size.width = self.frame.size.width - field_frame.origin.x - FIELD_BUFFER
|
41
|
+
field_frame.size.height = self.frame.size.height - FIELD_BUFFER
|
42
42
|
formotion_field.frame = field_frame
|
43
43
|
end
|
44
44
|
end
|
@@ -92,7 +92,7 @@ module Formotion
|
|
92
92
|
end
|
93
93
|
button
|
94
94
|
end
|
95
|
-
cell.accessoryView = @add_button
|
95
|
+
cell.accessoryView = cell.editingAccessoryView = @add_button
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
@@ -1,18 +1,28 @@
|
|
1
1
|
module Formotion
|
2
2
|
module RowType
|
3
3
|
class OptionsRow < Base
|
4
|
-
|
5
|
-
SLIDER_VIEW_TAG = 1200
|
4
|
+
include BW::KVO
|
6
5
|
|
7
6
|
def build_cell(cell)
|
8
7
|
cell.selectionStyle = UITableViewCellSelectionStyleNone
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
cell.accessoryView =
|
8
|
+
segmentedControl = UISegmentedControl.alloc.initWithItems(row.items || [])
|
9
|
+
segmentedControl.selectedSegmentIndex = row.items.index(row.value) if row.value
|
10
|
+
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar
|
11
|
+
cell.accessoryView = cell.editingAccessoryView = segmentedControl
|
13
12
|
|
14
|
-
|
15
|
-
|
13
|
+
segmentedControl.when(UIControlEventValueChanged) do
|
14
|
+
break_with_semaphore do
|
15
|
+
row.value = row.items[segmentedControl.selectedSegmentIndex]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
observe(self.row, "value") do |old_value, new_value|
|
19
|
+
break_with_semaphore do
|
20
|
+
if row.value
|
21
|
+
segmentedControl.selectedSegmentIndex = row.items.index(row.value)
|
22
|
+
else
|
23
|
+
segmentedControl.selectedSegmentIndex = UISegmentedControlNoSegment
|
24
|
+
end
|
25
|
+
end
|
16
26
|
end
|
17
27
|
|
18
28
|
nil
|