tgios 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +23 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +26 -0
- data/LICENSE +23 -0
- data/README.md +0 -0
- data/Rakefile +20 -0
- data/app/app_delegate.rb +14 -0
- data/lib/tgios/animatable_view.rb +50 -0
- data/lib/tgios/binding_base.rb +38 -0
- data/lib/tgios/common_ui_utility.rb +30 -0
- data/lib/tgios/custom_method.rb +35 -0
- data/lib/tgios/extended_ui_table_view.rb +37 -0
- data/lib/tgios/extended_ui_view_controller.rb +42 -0
- data/lib/tgios/image_loader.rb +60 -0
- data/lib/tgios/loading_indicator.rb +47 -0
- data/lib/tgios/model_errors_helper.rb +20 -0
- data/lib/tgios/ns_date_helper.rb +25 -0
- data/lib/tgios/photo_controller.rb +35 -0
- data/lib/tgios/photo_scroll_view.rb +61 -0
- data/lib/tgios/search_controller.rb +77 -0
- data/lib/tgios/ui_button_binding.rb +36 -0
- data/lib/tgios/ui_picker_view_list_binding.rb +53 -0
- data/lib/tgios/ui_table_view_list_binding.rb +70 -0
- data/lib/tgios/ui_table_view_model_binding.rb +373 -0
- data/lib/tgios/ui_table_view_model_list_binding.rb +173 -0
- data/lib/tgios/ui_text_field_binding.rb +268 -0
- data/lib/tgios/ui_text_view_binding.rb +177 -0
- data/lib/tgios/version.rb +3 -0
- data/lib/tgios.rb +17 -0
- data/resources/Default-568h@2x.png +0 -0
- data/spec/main_spec.rb +9 -0
- data/tgios.gemspec +27 -0
- metadata +137 -0
@@ -0,0 +1,173 @@
|
|
1
|
+
module Tgios
|
2
|
+
class UITableViewModelListBinding < BindingBase
|
3
|
+
def initialize
|
4
|
+
super
|
5
|
+
|
6
|
+
@events={}
|
7
|
+
@events[:build_cell]=->(cell_identifier) {
|
8
|
+
cell = UITableViewCell.value1(cell_identifier)
|
9
|
+
cell.detailTextLabel.adjustsFontSizeToFitWidth = true
|
10
|
+
cell
|
11
|
+
}
|
12
|
+
@events[:update_cell]=->(field_set, cell, index_path) { update_field(field_set, cell, index_path)}
|
13
|
+
self
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
def bind(tableView, models, fields)
|
18
|
+
@tableView=WeakRef.new(tableView)
|
19
|
+
@fields=fields
|
20
|
+
@contact_buttons = []
|
21
|
+
@models=WeakRef.new(models)
|
22
|
+
@tableView.dataSource=self
|
23
|
+
@tableView.delegate=self
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def models=(value)
|
28
|
+
@models=value
|
29
|
+
@tableView.reloadData
|
30
|
+
end
|
31
|
+
|
32
|
+
def on(event_name, &block)
|
33
|
+
@events[event_name]=block
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def tableView(tableView, cellForRowAtIndexPath: index_path)
|
39
|
+
|
40
|
+
field_set = field_set_at_index_path(index_path)
|
41
|
+
type = field_set[:child_index].nil? ? field_set[:type] : field_set[:child_field][:type]
|
42
|
+
|
43
|
+
cell_identifier = "CELL_IDENTIFIER_#{type}"
|
44
|
+
cell=tableView.dequeueReusableCellWithIdentifier(cell_identifier)
|
45
|
+
isReusedCell=!cell.nil?
|
46
|
+
|
47
|
+
cell=@events[:build_cell].call(cell_identifier) unless isReusedCell
|
48
|
+
|
49
|
+
@events[:update_cell].call(field_set, cell, index_path)
|
50
|
+
|
51
|
+
cell
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
def update_field(o_field_set, cell, index_path)
|
56
|
+
model = @models[index_path.section]
|
57
|
+
field_set = o_field_set
|
58
|
+
if !field_set[:child_index].nil?
|
59
|
+
model = model.send(field_set[:name])[field_set[:child_index]]
|
60
|
+
field_set = field_set[:child_field]
|
61
|
+
end
|
62
|
+
|
63
|
+
accessory_view = cell.accessoryView
|
64
|
+
if field_set[:accessory] == :contact
|
65
|
+
if accessory_view && accessory_view.buttonType == :contact.uibuttontype
|
66
|
+
contact_button = accessory_view
|
67
|
+
else
|
68
|
+
contact_button = (@contact_buttons.pop || UIButton.contact)
|
69
|
+
cell.accessoryView = contact_button
|
70
|
+
end
|
71
|
+
unhook(contact_button, :tapped)
|
72
|
+
hook(contact_button, :tapped) do
|
73
|
+
tableView(@tableView, didSelectRowAtIndexPath:index_path)
|
74
|
+
end
|
75
|
+
else
|
76
|
+
if accessory_view && accessory_view.buttonType == :contact.uibuttontype
|
77
|
+
@contact_buttons << accessory_view
|
78
|
+
cell.accessoryView = nil
|
79
|
+
end
|
80
|
+
cell.accessoryType = (field_set[:accessory] || :none).uitablecellaccessory
|
81
|
+
end
|
82
|
+
|
83
|
+
case field_set[:type]
|
84
|
+
when :array
|
85
|
+
cell.textLabel.text=field_set[:label]
|
86
|
+
cell.detailTextLabel.text = ''
|
87
|
+
when :label, :text
|
88
|
+
cell.textLabel.text= field_set[:show_label] ? field_set[:label] : field_set[:label_name].nil? ? '' : model.send(field_set[:label_name])
|
89
|
+
cell.detailTextLabel.text = model.send(field_set[:name])
|
90
|
+
when :big_label
|
91
|
+
cell.detailTextLabel.numberOfLines = 0
|
92
|
+
cell.detailTextLabel.backgroundColor = :clear.uicolor
|
93
|
+
cell.detailTextLabel.text = model.send(field_set[:name])
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
def tableView(tableView, didSelectRowAtIndexPath:index_path)
|
99
|
+
@selected_field_set=field_set_at_index_path(index_path)
|
100
|
+
@events[:touch_row].call(@selected_field_set, {tableView: tableView, didSelectRowAtIndexPath:index_path}) if @events.has_key?(:touch_row)
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
def tableView(tableView, numberOfRowsInSection: section)
|
105
|
+
count = @fields.length
|
106
|
+
@fields.each do |fld|
|
107
|
+
count += @models[section].send(fld[:name]).length if fld[:type] == :array
|
108
|
+
end
|
109
|
+
count
|
110
|
+
end
|
111
|
+
|
112
|
+
def numberOfSectionsInTableView(tableView)
|
113
|
+
@models.length
|
114
|
+
end
|
115
|
+
|
116
|
+
def tableView(tableView, commitEditingStyle:editingStyle, forRowAtIndexPath:index_path)
|
117
|
+
if editingStyle == UITableViewCellEditingStyleDelete
|
118
|
+
field_set = field_set_at_index_path(index_path)
|
119
|
+
real_fs = field_set
|
120
|
+
real_fs = real_fs[:child_field] unless real_fs[:child_index].nil?
|
121
|
+
if real_fs[:delete] == true
|
122
|
+
unless @events[:delete_row].nil?
|
123
|
+
@events[:delete_row].call(field_set, @models[index_path.section].send(field_set[:name]), {tableView: tableView, commitEditingStyle: editingStyle, forRowAtIndexPath:index_path}) do |success|
|
124
|
+
tableView.deleteRowsAtIndexPaths([index_path], withRowAnimation: UITableViewRowAnimationFade) if success
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def tableView(tableView, canEditRowAtIndexPath: index_path)
|
132
|
+
field_set = field_set_at_index_path(index_path)
|
133
|
+
field_set = field_set[:child_field] unless field_set[:child_index].nil?
|
134
|
+
return field_set[:delete] == true
|
135
|
+
end
|
136
|
+
|
137
|
+
def tableView(tableView, heightForRowAtIndexPath: index_path)
|
138
|
+
field_set = field_set_at_index_path(index_path)
|
139
|
+
field_set = field_set[:child_field] unless field_set[:child_index].nil?
|
140
|
+
if field_set[:type] == :big_label || field_set[:type] == :checkbox
|
141
|
+
20 + 20 * (field_set[:lines] || 2)
|
142
|
+
else
|
143
|
+
45
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def field_set_at_index_path(index_path)
|
148
|
+
row = index_path.row
|
149
|
+
array_indices = @fields.each_index.select{|i| @fields[i][:type] == :array}
|
150
|
+
return @fields[row] if array_indices.empty? || array_indices.first >= row
|
151
|
+
array_count_sum = 0
|
152
|
+
array_indices.each do |a_idx|
|
153
|
+
array_count = @models[index_path.section].send(@fields[a_idx][:name]).length
|
154
|
+
if row <= a_idx + array_count_sum + array_count
|
155
|
+
sub_idx = row - a_idx - array_count_sum - 1
|
156
|
+
return sub_idx < 0 ? @fields[a_idx + sub_idx + 1] : @fields[a_idx].merge(child_index: sub_idx)
|
157
|
+
end
|
158
|
+
array_count_sum += array_count
|
159
|
+
end
|
160
|
+
@fields[row - array_count_sum]
|
161
|
+
end
|
162
|
+
|
163
|
+
def onPrepareForRelease
|
164
|
+
@contact_buttons = nil
|
165
|
+
@events=nil
|
166
|
+
@models=nil
|
167
|
+
@tableView.delegate=nil
|
168
|
+
@tableView.dataSource=nil
|
169
|
+
@tableView=nil
|
170
|
+
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,268 @@
|
|
1
|
+
include SugarCube::CoreGraphics
|
2
|
+
|
3
|
+
module Tgios
|
4
|
+
class UITextFieldBinding < BindingBase
|
5
|
+
include PlasticCup
|
6
|
+
|
7
|
+
def initialize(model, ui_field, field_name, options={})
|
8
|
+
super
|
9
|
+
|
10
|
+
Base.add_style_sheet(:decimal_button_common, {
|
11
|
+
title: '.',
|
12
|
+
titleFont: lambda {UIFont.boldSystemFontOfSize(30)},
|
13
|
+
}) unless Base.get_style_sheet(:decimal_button_common)
|
14
|
+
Base.add_style_sheet(:decimal_button, {
|
15
|
+
extends: :decimal_button_common,
|
16
|
+
frame: [[0, 162.5 + 44], [104.5, 54]],
|
17
|
+
highlighted_background_image: Tgios::CommonUIUtility.imageFromColor(:white),
|
18
|
+
titleColor: :black.uicolor
|
19
|
+
}, :ios7) unless Base.get_style_sheet(:decimal_button)
|
20
|
+
|
21
|
+
Base.add_style_sheet(:decimal_button, {
|
22
|
+
extends: :decimal_button_common,
|
23
|
+
frame: [[0, 163 + 44], [105, 54]],
|
24
|
+
highlighted_background_image: Tgios::CommonUIUtility.imageFromColor(UIColor.colorWithRed(0.324, green: 0.352, blue: 0.402, alpha: 1)),
|
25
|
+
titleColor: :darkgray.uicolor,
|
26
|
+
highlighted_title_color: :white.uicolor
|
27
|
+
}) unless Base.get_style_sheet(:decimal_button)
|
28
|
+
|
29
|
+
@field_name=field_name
|
30
|
+
@options=options
|
31
|
+
@events={}
|
32
|
+
@ui_field=WeakRef.new(ui_field)
|
33
|
+
@model=WeakRef.new(model)
|
34
|
+
update_ui_field_style
|
35
|
+
assign_value_to_field
|
36
|
+
end
|
37
|
+
|
38
|
+
def assign_value_to_field
|
39
|
+
val = @model.send(@field_name)
|
40
|
+
if val.is_a?(String) || val.nil?
|
41
|
+
@ui_field.text=val
|
42
|
+
else
|
43
|
+
@original_value = val
|
44
|
+
@ui_field.text= if val.respond_to?(:round)
|
45
|
+
default_precision = 0
|
46
|
+
default_precision = 6 unless val.is_a?(Integer)
|
47
|
+
val.round((@options[:precision] || default_precision)).to_s
|
48
|
+
else
|
49
|
+
val.to_s
|
50
|
+
end
|
51
|
+
@model.send("#{@field_name}=", @ui_field.text)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def ui_field=(val)
|
56
|
+
@ui_field=WeakRef.new(val)
|
57
|
+
@ui_field.delegate=self
|
58
|
+
update_ui_field_style
|
59
|
+
assign_value_to_field
|
60
|
+
end
|
61
|
+
|
62
|
+
def model=(val)
|
63
|
+
@model=WeakRef.new(val)
|
64
|
+
assign_value_to_field
|
65
|
+
end
|
66
|
+
|
67
|
+
def update(ui_field, model)
|
68
|
+
self.ui_field=ui_field
|
69
|
+
self.model=model
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
def on(event, &block)
|
74
|
+
@events[event]=block
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def textFieldDidEndEditing(textField)
|
79
|
+
puts "textFieldDidEndEditing"
|
80
|
+
@model.send("#{@field_name}=", textField.text)
|
81
|
+
weak_text_field=WeakRef.new(textField)
|
82
|
+
@events[:end_edit].call(@model, @field_name, {text_field: weak_text_field}) unless @events[:end_edit].nil?
|
83
|
+
@decimal_button.removeFromSuperview unless @decimal_button.nil?
|
84
|
+
end
|
85
|
+
|
86
|
+
def textFieldShouldReturn(textField)
|
87
|
+
@ui_field.resignFirstResponder
|
88
|
+
weak_text_field=WeakRef.new(@ui_field)
|
89
|
+
@events[:return_tapped].call(@model, @field_name, {text_field: weak_text_field}) unless @events[:return_tapped].nil?
|
90
|
+
end
|
91
|
+
|
92
|
+
def textFieldDidBeginEditing(textField)
|
93
|
+
add_decimal_button
|
94
|
+
weak_text_field=WeakRef.new(textField)
|
95
|
+
@events[:begin_edit].call(@model, @field_name, {text_field: weak_text_field}) unless @events[:begin_edit].nil?
|
96
|
+
end
|
97
|
+
|
98
|
+
def keyboardDidShow(note)
|
99
|
+
add_decimal_button if @ui_field.isFirstResponder
|
100
|
+
end
|
101
|
+
|
102
|
+
def is_number_pad?
|
103
|
+
@ui_field.keyboardType == UIKeyboardTypeNumberPad
|
104
|
+
end
|
105
|
+
|
106
|
+
def is_decimal?
|
107
|
+
@options[:keyboard] == :decimal && is_number_pad?
|
108
|
+
end
|
109
|
+
|
110
|
+
def add_decimal_button
|
111
|
+
if is_decimal? && @ui_field.delegate == self
|
112
|
+
temp_window = (UIApplication.sharedApplication.windows[1] || UIApplication.sharedApplication.windows[0])
|
113
|
+
temp_window.subviews.each do |keyboard|
|
114
|
+
if keyboard.description.hasPrefix('<UIPeripheralHost')
|
115
|
+
if @decimal_button.nil?
|
116
|
+
@decimal_button = PlasticCup::Base.style(UIButton.custom, :decimal_button)
|
117
|
+
@decimal_button.addTarget(self, action: 'decimal_tapped', forControlEvents: UIControlEventTouchUpInside)
|
118
|
+
end
|
119
|
+
keyboard.addSubview(@decimal_button)
|
120
|
+
break
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def decimal_tapped
|
127
|
+
@ui_field.text = "#{@ui_field.text}." unless !@ui_field.text.nil? && @ui_field.text.include?('.')
|
128
|
+
end
|
129
|
+
|
130
|
+
#### options
|
131
|
+
# type:
|
132
|
+
# :password
|
133
|
+
# :label
|
134
|
+
#
|
135
|
+
# auto_correct:
|
136
|
+
# true
|
137
|
+
# false
|
138
|
+
# UITextAutocorrectionType
|
139
|
+
#
|
140
|
+
# auto_capitalize:
|
141
|
+
# true
|
142
|
+
# false
|
143
|
+
# UITextAutocapitalizationType
|
144
|
+
#
|
145
|
+
# keyboard:
|
146
|
+
# :decimal
|
147
|
+
# uikeyboardtype (sugarcube)
|
148
|
+
# UIKeyboardType
|
149
|
+
#
|
150
|
+
# precision: Numeric (only useful when value is Numeric)
|
151
|
+
# default:
|
152
|
+
# Integer: 0
|
153
|
+
# Float: 6
|
154
|
+
#
|
155
|
+
# error:
|
156
|
+
# true
|
157
|
+
# false
|
158
|
+
#
|
159
|
+
# reduce_font_size:
|
160
|
+
# true
|
161
|
+
# false
|
162
|
+
####
|
163
|
+
|
164
|
+
def update_ui_field_style
|
165
|
+
@ui_field.secureTextEntry=@options[:type]==:password
|
166
|
+
@ui_field.autocorrectionType = get_auto_correct_type(@options[:auto_correct])
|
167
|
+
@ui_field.autocapitalizationType = get_auto_capitalize_type(@options[:auto_capitalize])
|
168
|
+
@ui_field.keyboardType = get_keyboard_type(@options[:keyboard])
|
169
|
+
@ui_field.enabled = @options[:type] != :label
|
170
|
+
@ui_field.adjustsFontSizeToFitWidth = @options[:reduce_font_size]
|
171
|
+
|
172
|
+
if @model.respond_to?(:has_error?) && @model.has_error?(@field_name)
|
173
|
+
@ui_field.leftViewMode = UITextFieldViewModeAlways
|
174
|
+
if @ui_field.leftView.nil? || @ui_field.leftView.tag != 888
|
175
|
+
error_label_styles ={frame: [[0,0], [25,25]],
|
176
|
+
textColor: :red.uicolor,
|
177
|
+
backgroundColor: :clear.uicolor,
|
178
|
+
font: 'GillSans-Bold'.uifont(25),
|
179
|
+
textAlignment: :center.uialignment,
|
180
|
+
text: '!',
|
181
|
+
tag: 888}
|
182
|
+
error_label = PlasticCup::Base.style(UILabel.new, error_label_styles)
|
183
|
+
@ui_field.leftView = error_label
|
184
|
+
end
|
185
|
+
else
|
186
|
+
@ui_field.leftViewMode = UITextFieldViewModeNever
|
187
|
+
end
|
188
|
+
|
189
|
+
if is_number_pad?
|
190
|
+
text_toolbar = PlasticCup::Base.style(UIToolbar.new, frame: CGRectMake(0,0,320,44))
|
191
|
+
done_button = UIBarButtonItem.alloc.initWithBarButtonSystemItem(UIBarButtonSystemItemDone, target: self, action: 'textFieldShouldReturn:')
|
192
|
+
text_toolbar.items=[
|
193
|
+
UIBarButtonItem.flexible_space, done_button
|
194
|
+
]
|
195
|
+
@ui_field.inputAccessoryView = text_toolbar
|
196
|
+
else
|
197
|
+
@ui_field.inputAccessoryView = nil
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
stop_listen
|
202
|
+
listen_keyboard
|
203
|
+
end
|
204
|
+
|
205
|
+
def get_auto_capitalize_type(type=nil)
|
206
|
+
case type
|
207
|
+
when true, nil
|
208
|
+
UITextAutocapitalizationTypeSentences
|
209
|
+
when false
|
210
|
+
UITextAutocapitalizationTypeNone
|
211
|
+
else
|
212
|
+
type
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def get_auto_correct_type(type=nil)
|
217
|
+
case type
|
218
|
+
when true
|
219
|
+
UITextAutocorrectionTypeYes
|
220
|
+
when false
|
221
|
+
UITextAutocorrectionTypeNo
|
222
|
+
when nil
|
223
|
+
UITextAutocorrectionTypeDefault
|
224
|
+
else
|
225
|
+
type
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def get_keyboard_type(type=nil)
|
230
|
+
return type if type.is_a?(Integer)
|
231
|
+
ktype = type == :decimal ? :number : type
|
232
|
+
(ktype || :default).uikeyboardtype
|
233
|
+
end
|
234
|
+
|
235
|
+
|
236
|
+
def listen_keyboard
|
237
|
+
if is_decimal? && @ui_field.delegate == self
|
238
|
+
NSNotificationCenter.defaultCenter.addObserver(self, selector: 'keyboardDidShow:', name: UIKeyboardDidShowNotification, object: nil)
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|
242
|
+
|
243
|
+
def stop_listen
|
244
|
+
NSNotificationCenter.defaultCenter.removeObserver(self)
|
245
|
+
end
|
246
|
+
|
247
|
+
def onPrepareForRelease
|
248
|
+
stop_listen
|
249
|
+
@model=nil
|
250
|
+
@decimal_button=nil
|
251
|
+
if !@ui_field.nil? && @ui_field.delegate == self
|
252
|
+
@ui_field.delegate = nil
|
253
|
+
toolbar = @ui_field.inputAccessoryView
|
254
|
+
toolbar.items = nil unless toolbar.nil?
|
255
|
+
@ui_field.inputAccessoryView = nil
|
256
|
+
end
|
257
|
+
@ui_field=nil
|
258
|
+
@events=nil
|
259
|
+
end
|
260
|
+
|
261
|
+
def dealloc
|
262
|
+
prepareForRelease
|
263
|
+
ap 'dealloc ui_text_field_binding'
|
264
|
+
super
|
265
|
+
end
|
266
|
+
|
267
|
+
end
|
268
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
module Tgios
|
2
|
+
class UITextViewBinding < BindingBase
|
3
|
+
|
4
|
+
def initialize(model, ui_field, field_name, options={})
|
5
|
+
super
|
6
|
+
@field_name=field_name
|
7
|
+
@options=options
|
8
|
+
@events={}
|
9
|
+
@ui_field=WeakRef.new(ui_field)
|
10
|
+
@model=WeakRef.new(model)
|
11
|
+
update_ui_field_style
|
12
|
+
assign_value_to_field
|
13
|
+
end
|
14
|
+
|
15
|
+
def assign_value_to_field
|
16
|
+
val = @model.send(@field_name)
|
17
|
+
if val.is_a?(String) || val.nil?
|
18
|
+
@ui_field.text=val
|
19
|
+
else
|
20
|
+
@original_value = val
|
21
|
+
@ui_field.text= if val.respond_to?(:round)
|
22
|
+
default_precision = 0
|
23
|
+
default_precision = 6 unless val.is_a?(Integer)
|
24
|
+
val.round((@options[:precision] || default_precision)).to_s
|
25
|
+
else
|
26
|
+
val.to_s
|
27
|
+
end
|
28
|
+
@model.send("#{@field_name}=", @ui_field.text)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def ui_field=(val)
|
33
|
+
@ui_field=WeakRef.new(val)
|
34
|
+
@ui_field.delegate=self
|
35
|
+
update_ui_field_style
|
36
|
+
assign_value_to_field
|
37
|
+
end
|
38
|
+
|
39
|
+
def model=(val)
|
40
|
+
@model=WeakRef.new(val)
|
41
|
+
assign_value_to_field
|
42
|
+
end
|
43
|
+
|
44
|
+
def update(ui_field, model)
|
45
|
+
self.ui_field=ui_field
|
46
|
+
self.model=model
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
def on(event, &block)
|
51
|
+
@events[event]=block
|
52
|
+
end
|
53
|
+
|
54
|
+
#### options
|
55
|
+
# type:
|
56
|
+
# :password
|
57
|
+
# :label
|
58
|
+
#
|
59
|
+
# auto_correct:
|
60
|
+
# true
|
61
|
+
# false
|
62
|
+
# UITextAutocorrectionType
|
63
|
+
#
|
64
|
+
# auto_capitalize:
|
65
|
+
# true
|
66
|
+
# false
|
67
|
+
# UITextAutocapitalizationType
|
68
|
+
#
|
69
|
+
# keyboard:
|
70
|
+
# :decimal
|
71
|
+
# uikeyboardtype (sugarcube)
|
72
|
+
# UIKeyboardType
|
73
|
+
#
|
74
|
+
# precision: Numeric (only useful when value is Numeric)
|
75
|
+
# default:
|
76
|
+
# Integer: 0
|
77
|
+
# Float: 6
|
78
|
+
#
|
79
|
+
# error:
|
80
|
+
# true
|
81
|
+
# false
|
82
|
+
#
|
83
|
+
# reduce_font_size:
|
84
|
+
# true
|
85
|
+
# false
|
86
|
+
####
|
87
|
+
|
88
|
+
def update_ui_field_style
|
89
|
+
@ui_field.secureTextEntry=@options[:type]==:password
|
90
|
+
@ui_field.autocorrectionType = get_auto_correct_type(@options[:auto_correct])
|
91
|
+
@ui_field.autocapitalizationType = get_auto_capitalize_type(@options[:auto_capitalize])
|
92
|
+
@ui_field.keyboardType = get_keyboard_type(@options[:keyboard])
|
93
|
+
@ui_field.enabled = @options[:type] != :label
|
94
|
+
|
95
|
+
|
96
|
+
text_view_toolbar = PlasticCup::Base.style(UIToolbar.new, frame: CGRectMake(0,0,320,44))
|
97
|
+
done_button = UIBarButtonItem.alloc.initWithBarButtonSystemItem(UIBarButtonSystemItemDone, target: self, action: 'did_return:')
|
98
|
+
|
99
|
+
text_view_toolbar.items=[
|
100
|
+
UIBarButtonItem.flexible_space, done_button
|
101
|
+
]
|
102
|
+
@ui_field.inputAccessoryView = text_view_toolbar
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
def get_auto_capitalize_type(type=nil)
|
107
|
+
case type
|
108
|
+
when true, nil
|
109
|
+
UITextAutocapitalizationTypeSentences
|
110
|
+
when false
|
111
|
+
UITextAutocapitalizationTypeNone
|
112
|
+
else
|
113
|
+
type
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def get_auto_correct_type(type=nil)
|
118
|
+
case type
|
119
|
+
when true
|
120
|
+
UITextAutocorrectionTypeYes
|
121
|
+
when false
|
122
|
+
UITextAutocorrectionTypeNo
|
123
|
+
when nil
|
124
|
+
UITextAutocorrectionTypeDefault
|
125
|
+
else
|
126
|
+
type
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def get_keyboard_type(type=nil)
|
131
|
+
return type if type.is_a?(Integer)
|
132
|
+
ktype = type == :decimal ? :numbers_and_punctuation : type
|
133
|
+
(ktype || :default).uikeyboardtype
|
134
|
+
end
|
135
|
+
|
136
|
+
def textViewDidEndEditing(field)
|
137
|
+
ap 'did_end_editing'
|
138
|
+
@model.send("#{@field_name}=", field.text)
|
139
|
+
weak_text_field=WeakRef.new(field)
|
140
|
+
@events[:end_edit].call(@model, @field_name, {text_field: weak_text_field}) unless @events[:end_edit].nil?
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
def did_return(field)
|
145
|
+
ap 'did return'
|
146
|
+
@ui_field.resignFirstResponder
|
147
|
+
weak_text_field=WeakRef.new(@ui_field)
|
148
|
+
@events[:return_tapped].call(@model, @field_name, {text_field: weak_text_field}) unless @events[:return_tapped].nil?
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
def textViewDidBeginEditing(field)
|
153
|
+
ap 'did_begin_editing'
|
154
|
+
weak_text_field=WeakRef.new(field)
|
155
|
+
@events[:begin_edit].call(@model, @field_name, {text_field: weak_text_field}) unless @events[:begin_edit].nil?
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
def onPrepareForRelease
|
160
|
+
@model=nil
|
161
|
+
if !@ui_field.nil? && @ui_field.delegate == self
|
162
|
+
@ui_field.delegate = nil
|
163
|
+
toolbar = @ui_field.inputAccessoryView
|
164
|
+
toolbar.items = nil unless toolbar.nil?
|
165
|
+
@ui_field.inputAccessoryView = nil
|
166
|
+
end
|
167
|
+
@ui_field=nil
|
168
|
+
@events=nil
|
169
|
+
end
|
170
|
+
|
171
|
+
def dealloc
|
172
|
+
prepareForRelease
|
173
|
+
ap 'dealloc ui_text_view input_binding'
|
174
|
+
super
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
data/lib/tgios.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#require 'sugarcube'
|
2
|
+
#require 'sugarcube-coregraphics'
|
3
|
+
#require 'plastic_cup'
|
4
|
+
|
5
|
+
|
6
|
+
unless defined?(Motion::Project::Config)
|
7
|
+
raise "This file must be required within a RubyMotion project Rakefile."
|
8
|
+
end
|
9
|
+
|
10
|
+
Motion::Project::App.setup do |app|
|
11
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'tgios/*.rb')).each do |file|
|
12
|
+
app.files.unshift(file)
|
13
|
+
end
|
14
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'tgios/*/*.rb')).each do |file|
|
15
|
+
app.files.unshift(file)
|
16
|
+
end
|
17
|
+
end
|
Binary file
|
data/spec/main_spec.rb
ADDED
data/tgios.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/tgios/version.rb', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = 'tgios'
|
6
|
+
gem.version = Tgios::VERSION
|
7
|
+
gem.licenses = ['BSD']
|
8
|
+
|
9
|
+
gem.authors = ['April Tsang', 'William Yeung']
|
10
|
+
gem.email = ['april@tofugear.com', 'william@tofugear.com']
|
11
|
+
|
12
|
+
gem.description = <<-DESC
|
13
|
+
A package of ruby-motion libraries written by our team.
|
14
|
+
DESC
|
15
|
+
|
16
|
+
gem.summary = 'A package of ruby-motion libraries written by our team.'
|
17
|
+
gem.homepage = 'https://github.com/apriltg/tgios'
|
18
|
+
|
19
|
+
gem.files = `git ls-files`.split($\)
|
20
|
+
gem.require_paths = ['lib']
|
21
|
+
gem.test_files = gem.files.grep(%r{^spec/})
|
22
|
+
gem.add_dependency 'sugarcube', '1.1.0'
|
23
|
+
#gem.add_dependency 'sugarcube-classic'
|
24
|
+
gem.add_dependency 'awesome_print_motion'
|
25
|
+
gem.add_dependency 'motion-layout'
|
26
|
+
gem.add_dependency 'plastic_cup', '>=0.1.1'
|
27
|
+
end
|