motion-prime 0.9.9 → 0.9.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CHANGELOG.md +8 -2
- data/Gemfile.lock +2 -2
- data/ROADMAP.md +1 -3
- data/files/Gemfile +1 -1
- data/generators/templates/scaffold/table.rb +1 -1
- data/generators/templates/table.rb +1 -1
- data/motion-prime/config/base.rb +2 -2
- data/motion-prime/elements/_content_text_mixin.rb +1 -1
- data/motion-prime/elements/base_element.rb +14 -7
- data/motion-prime/elements/collection_view_cell.rb +7 -0
- data/motion-prime/elements/draw/image.rb +7 -2
- data/motion-prime/elements/table_view_cell.rb +1 -1
- data/motion-prime/helpers/has_normalizer.rb +1 -1
- data/motion-prime/helpers/has_search_bar.rb +1 -1
- data/motion-prime/models/_nano_bag_mixin.rb +1 -1
- data/motion-prime/models/model.rb +8 -8
- data/motion-prime/models/store.rb +1 -1
- data/motion-prime/screens/screen.rb +3 -3
- data/motion-prime/sections/_async_form_mixin.rb +2 -2
- data/motion-prime/sections/_async_table_mixin.rb +7 -7
- data/motion-prime/sections/_cell_section_mixin.rb +16 -11
- data/motion-prime/sections/_draw_section_mixin.rb +1 -0
- data/motion-prime/sections/{__section_with_container_mixin.rb → _section_with_container_mixin.rb} +2 -2
- data/motion-prime/sections/abstract_collection.rb +291 -0
- data/motion-prime/sections/base_section.rb +2 -2
- data/motion-prime/sections/collection/collection_delegate.rb +62 -0
- data/motion-prime/sections/form.rb +22 -18
- data/motion-prime/sections/form/base_field_section.rb +7 -7
- data/motion-prime/sections/form/form_delegate.rb +1 -1
- data/motion-prime/sections/form/form_header_section.rb +1 -1
- data/motion-prime/sections/form/password_field_section.rb +1 -1
- data/motion-prime/sections/form/static_field_section.rb +1 -1
- data/motion-prime/sections/form/string_field_section.rb +1 -1
- data/motion-prime/sections/form/text_field_section.rb +1 -1
- data/motion-prime/sections/grid.rb +92 -0
- data/motion-prime/sections/table.rb +26 -260
- data/motion-prime/sections/table/refresh_mixin.rb +3 -3
- data/motion-prime/sections/table/table_delegate.rb +1 -0
- data/motion-prime/styles/_mixins.rb +1 -1
- data/motion-prime/styles/base.rb +20 -6
- data/motion-prime/styles/form.rb +1 -1
- data/motion-prime/support/_control_content_alignment.rb +39 -0
- data/motion-prime/support/mp_button.rb +5 -13
- data/motion-prime/support/mp_collection_cell_with_section.rb +12 -0
- data/motion-prime/support/{mp_cell_content_view.rb → mp_table_cell_content_view.rb} +0 -0
- data/motion-prime/support/{mp_cell_with_section.rb → mp_table_cell_with_section.rb} +1 -1
- data/motion-prime/support/mp_text_field.rb +24 -18
- data/motion-prime/support/mp_text_view.rb +1 -0
- data/motion-prime/version.rb +1 -1
- data/motion-prime/views/_frame_calculator_mixin.rb +15 -11
- data/motion-prime/views/layout.rb +6 -4
- data/motion-prime/views/view_builder.rb +10 -0
- data/motion-prime/views/view_styler.rb +5 -1
- data/spec/factories/scaffold/sections/tasks/index_table.rb +1 -1
- data/spec/unit/support/filter_mixin_spec.rb +7 -3
- data/spec/unit/support/frame_calculator_mixin_spec.rb +43 -0
- metadata +13 -5
@@ -9,7 +9,7 @@ module MotionPrime
|
|
9
9
|
after_initialize :observe_model_errors
|
10
10
|
|
11
11
|
def prepare_table_data
|
12
|
-
@form = @options[:
|
12
|
+
@form = @options[:collection_section]
|
13
13
|
if options[:observe_errors]
|
14
14
|
# Do not remove clone() after delete()
|
15
15
|
@errors_observer_options = normalize_options(options.delete(:observe_errors).clone, elements_eval_object)
|
@@ -46,7 +46,7 @@ module MotionPrime
|
|
46
46
|
reload_section
|
47
47
|
else
|
48
48
|
create_elements!
|
49
|
-
form.
|
49
|
+
form.reload_collection_data
|
50
50
|
end
|
51
51
|
end
|
52
52
|
}.weak!
|
@@ -72,21 +72,21 @@ module MotionPrime
|
|
72
72
|
end if begin_editing
|
73
73
|
|
74
74
|
# scroll to cell
|
75
|
-
# path = form.
|
76
|
-
# form.
|
75
|
+
# path = form.collection_view.indexPathForCell(cell)
|
76
|
+
# form.collection_view.scrollToRowAtIndexPath path,
|
77
77
|
# atScrollPosition: UITableViewScrollPositionTop, animated: true
|
78
78
|
return self unless input_view = element(:input).try(:view)
|
79
79
|
origin = input_view.frame.origin
|
80
|
-
point = container_view.convertPoint(origin, toView: form.
|
80
|
+
point = container_view.convertPoint(origin, toView: form.collection_view)
|
81
81
|
|
82
82
|
nav_bar_height = screen.navigationController ? screen.navigationController.navigationBar.frame.size.height : 0
|
83
83
|
nav_bar_height += 20 # status bar height
|
84
84
|
|
85
|
-
offset = form.
|
85
|
+
offset = form.collection_view.contentOffset
|
86
86
|
new_top_offset = point.y - nav_bar_height
|
87
87
|
unless new_top_offset == offset.y
|
88
88
|
offset.y = new_top_offset
|
89
|
-
form.
|
89
|
+
form.collection_view.setContentOffset(offset, animated: true)
|
90
90
|
end
|
91
91
|
|
92
92
|
self
|
@@ -3,7 +3,7 @@ module MotionPrime
|
|
3
3
|
element :label, type: :label do
|
4
4
|
default_label_options
|
5
5
|
end
|
6
|
-
element :input, type: :text_field, delegate: proc {
|
6
|
+
element :input, type: :text_field, delegate: proc { collection_delegate } do
|
7
7
|
{secure_text_entry: true}.merge(options[:input] || {})
|
8
8
|
end
|
9
9
|
element :error_message, type: :error_message, text: proc { |field| field.all_errors.join("\n") if field.observing_errors? }
|
@@ -3,7 +3,7 @@ module MotionPrime
|
|
3
3
|
element :label, type: :label do
|
4
4
|
default_label_options
|
5
5
|
end
|
6
|
-
element :input, type: :text_view, delegate: proc {
|
6
|
+
element :input, type: :text_view, delegate: proc { collection_delegate } do
|
7
7
|
{editable: true}.merge(options[:input] || {})
|
8
8
|
end
|
9
9
|
|
@@ -0,0 +1,92 @@
|
|
1
|
+
motion_require './collection/collection_delegate'
|
2
|
+
|
3
|
+
module MotionPrime
|
4
|
+
class GridSection < AbstractCollectionSection
|
5
|
+
DEFAULT_GRID_SIZE = 3
|
6
|
+
|
7
|
+
class_attribute :grid_size_value
|
8
|
+
|
9
|
+
before_render :render_collection
|
10
|
+
|
11
|
+
# Get index path for cell section
|
12
|
+
#
|
13
|
+
# @param section [Prime::Section] cell section.
|
14
|
+
# @return index [NSIndexPath] index of cell section.
|
15
|
+
def index_for_cell_section(section)
|
16
|
+
return unless item = @data.try(:index, section)
|
17
|
+
group = item/grid_size
|
18
|
+
row = cell_sections_for_group(group).index(section)
|
19
|
+
NSIndexPath.indexPathForRow(row, inSection: group)
|
20
|
+
end
|
21
|
+
|
22
|
+
def collection_styles_base
|
23
|
+
:base_collection
|
24
|
+
end
|
25
|
+
|
26
|
+
def collection_delegate
|
27
|
+
@collection_delegate ||= CollectionDelegate.new(section: self)
|
28
|
+
end
|
29
|
+
|
30
|
+
def grid_element_options
|
31
|
+
collection_element_options.merge({
|
32
|
+
grid_size: grid_size
|
33
|
+
})
|
34
|
+
end
|
35
|
+
|
36
|
+
def render_collection
|
37
|
+
self.collection_element = screen.collection_view(grid_element_options)
|
38
|
+
end
|
39
|
+
|
40
|
+
def render_cell(index)
|
41
|
+
collection_view.registerClass(MPCollectionCellWithSection, forCellWithReuseIdentifier: cell_name(index))
|
42
|
+
view = collection_view.dequeueReusableCellWithReuseIdentifier(cell_name(index), forIndexPath: index)
|
43
|
+
|
44
|
+
section = cell_section_by_index(index)
|
45
|
+
element = section.container_element || section.init_container_element(container_element_options_for(index))
|
46
|
+
unless view.section
|
47
|
+
element.view = view
|
48
|
+
screen.set_options_for view, element.computed_options.except(:parent_view) do
|
49
|
+
section.render
|
50
|
+
end
|
51
|
+
|
52
|
+
on_cell_render(view, index)
|
53
|
+
end
|
54
|
+
view
|
55
|
+
end
|
56
|
+
|
57
|
+
def cell_sections_for_group(section)
|
58
|
+
data[section, grid_size]
|
59
|
+
end
|
60
|
+
|
61
|
+
# Table View Delegate
|
62
|
+
# ---------------------
|
63
|
+
|
64
|
+
def grid_size
|
65
|
+
self.class.grid_size || DEFAULT_GRID_SIZE
|
66
|
+
end
|
67
|
+
|
68
|
+
def number_of_cells_in_group(group)
|
69
|
+
cell_sections_for_group(group).count.to_i
|
70
|
+
end
|
71
|
+
|
72
|
+
def number_of_groups
|
73
|
+
(data.count.to_f / grid_size).ceil
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
def container_element_options_for(index)
|
78
|
+
super.merge({
|
79
|
+
type: :collection_view_cell,
|
80
|
+
view_class: 'MPCollectionCellWithSection'
|
81
|
+
})
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.grid_size(value = nil)
|
85
|
+
if value
|
86
|
+
self.grid_size_value = value
|
87
|
+
else
|
88
|
+
self.grid_size_value
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -2,102 +2,26 @@ motion_require './table/refresh_mixin'
|
|
2
2
|
motion_require './table/table_delegate'
|
3
3
|
|
4
4
|
module MotionPrime
|
5
|
-
class TableSection <
|
5
|
+
class TableSection < AbstractCollectionSection
|
6
6
|
include TableSectionRefreshMixin
|
7
|
-
include HasStyleChainBuilder
|
8
7
|
include HasSearchBar
|
9
8
|
|
10
9
|
class_attribute :group_header_options, :pull_to_refresh_block
|
11
10
|
|
12
|
-
attr_accessor :
|
13
|
-
attr_reader :decelerating
|
14
|
-
before_render :render_table
|
11
|
+
attr_accessor :group_header_sections, :group_header_options
|
15
12
|
after_render :init_pull_to_refresh
|
16
|
-
delegate :init_pull_to_refresh, to: :
|
17
|
-
delegate :set_options, :update_options, to: :table_element, allow_nil: true
|
18
|
-
|
19
|
-
# Return sections which will be used to render as table cells.
|
20
|
-
#
|
21
|
-
# This method should be redefined in your table section and must return array.
|
22
|
-
# @return [Array<Prime::Section>] array of sections
|
23
|
-
def table_data
|
24
|
-
@model || []
|
25
|
-
end
|
26
|
-
|
27
|
-
# Returns cached version of table data
|
28
|
-
#
|
29
|
-
# @return [Array<Prime::Section>] cached array of sections
|
30
|
-
def data
|
31
|
-
@data || set_table_data
|
32
|
-
end
|
33
|
-
|
34
|
-
# IMPORTANT: when you use #map in table_data,
|
35
|
-
# then #dealloc of Prime::Section will not be called to section created on that #map.
|
36
|
-
# We did not find yet why this happening, for now just using hack.
|
37
|
-
def fixed_table_data
|
38
|
-
table_data.to_enum.to_a
|
39
|
-
end
|
40
|
-
|
41
|
-
def dealloc
|
42
|
-
Prime.logger.dealloc_message :table, self, self.table_element.try(:view).to_s
|
43
|
-
table_delegate.clear_delegated
|
44
|
-
table_view.setDataSource nil
|
45
|
-
super
|
46
|
-
end
|
47
|
-
|
48
|
-
# Reset all table data and reload table view
|
49
|
-
#
|
50
|
-
# @return [Boolean] true
|
51
|
-
def reload_data
|
52
|
-
reset_table_data
|
53
|
-
reload_table_data
|
54
|
-
end
|
55
|
-
|
56
|
-
# Alias for reload_data
|
57
|
-
#
|
58
|
-
# @return [Boolean] true
|
59
|
-
def reload
|
60
|
-
reload_data
|
61
|
-
end
|
62
|
-
|
63
|
-
# Reload table view data
|
64
|
-
#
|
65
|
-
# @return [Boolean] true
|
66
|
-
def reload_table_data
|
67
|
-
table_view.reloadData
|
68
|
-
true
|
69
|
-
end
|
70
|
-
|
71
|
-
# Reload table view if data was empty before.
|
72
|
-
#
|
73
|
-
# @return [Boolean] true if reload was happened
|
74
|
-
def refresh_if_needed
|
75
|
-
@data.nil? ? reload_table_data : false
|
76
|
-
end
|
77
|
-
|
78
|
-
# Reset all table data.
|
79
|
-
#
|
80
|
-
# @return [Boolean] true
|
81
|
-
def reset_table_data
|
82
|
-
@did_appear = false
|
83
|
-
Array.wrap(@data).flatten.each do |section|
|
84
|
-
section.container_element.try(:update_options, reuse_identifier: nil)
|
85
|
-
end
|
86
|
-
@data = nil
|
87
|
-
@data_stamp = nil
|
88
|
-
true
|
89
|
-
end
|
13
|
+
delegate :init_pull_to_refresh, to: :collection_delegate
|
90
14
|
|
91
15
|
# Add cells to table view and reload table view.
|
92
16
|
#
|
93
17
|
# @param cell sections [Prime::Section, Array<Prime::Section>] cells which will be added to table view.
|
94
18
|
# @return [Boolean] true
|
95
19
|
def add_cell_sections(sections, index = nil)
|
96
|
-
|
20
|
+
prepare_collection_cell_sections(sections)
|
97
21
|
@data ||= []
|
98
22
|
index ||= @data.count
|
99
23
|
@data.insert([index, @data.count].min, *sections)
|
100
|
-
|
24
|
+
reload_collection_data
|
101
25
|
end
|
102
26
|
|
103
27
|
# Delete cells from table data and remove them from table view with animation.
|
@@ -114,9 +38,9 @@ module MotionPrime
|
|
114
38
|
end
|
115
39
|
if paths.any?
|
116
40
|
UIView.animate(duration: 0, after: block) do
|
117
|
-
|
118
|
-
|
119
|
-
|
41
|
+
collection_view.beginUpdates
|
42
|
+
collection_view.deleteRowsAtIndexPaths(paths, withRowAnimation: UITableViewRowAnimationLeft)
|
43
|
+
collection_view.endUpdates
|
120
44
|
end
|
121
45
|
end
|
122
46
|
paths
|
@@ -145,8 +69,8 @@ module MotionPrime
|
|
145
69
|
#
|
146
70
|
# @param [Array<NSIndexPath>] index paths of cells to reload.
|
147
71
|
def reload_cells(*paths)
|
148
|
-
|
149
|
-
|
72
|
+
collection_view.reloadRowsAtIndexPaths(Array.wrap(paths), withRowAnimation: UITableViewRowAnimationFade)
|
73
|
+
collection_view.reloadData # do not use reload_collection_data (due to async_form_mixin)
|
150
74
|
end
|
151
75
|
|
152
76
|
# Changes height of cells with animation.
|
@@ -188,90 +112,28 @@ module MotionPrime
|
|
188
112
|
end
|
189
113
|
end
|
190
114
|
|
191
|
-
def
|
192
|
-
|
193
|
-
|
194
|
-
base_styles = [type]
|
115
|
+
def collection_styles_base
|
116
|
+
base_styles = [:base_table]
|
195
117
|
base_styles << :"#{type}_with_sections" unless flat_data?
|
196
|
-
|
197
|
-
item_styles += Array.wrap(@styles) if @styles.present?
|
198
|
-
{common: base_styles, specific: item_styles}
|
118
|
+
base_styles
|
199
119
|
end
|
200
120
|
|
201
|
-
def
|
202
|
-
|
203
|
-
|
204
|
-
# UserFormSection example: field :email, type: :string
|
205
|
-
# form_name = `user`
|
206
|
-
# type = `field`
|
207
|
-
# field_name = `email`
|
208
|
-
# field_type = `string_field`
|
209
|
-
|
210
|
-
# CategoriesTableSection example: table is a `CategoryTableSection`, cell is a `CategoryTitleSection`, element :icon, type: :image
|
211
|
-
# table_name = `categories`
|
212
|
-
# type = `cell` (always true)
|
213
|
-
# table_cell_section_name = `title`
|
214
|
-
type = section.respond_to?(:cell_type) ? section.cell_type : 'cell'
|
215
|
-
suffixes = [type]
|
216
|
-
if section.is_a?(BaseFieldSection)
|
217
|
-
suffixes << section.default_name
|
218
|
-
end
|
219
|
-
|
220
|
-
styles = {}
|
221
|
-
# table: base_table_<type>
|
222
|
-
# form: base_form_<type>, base_form_<field_type>
|
223
|
-
styles[:common] = build_styles_chain(table_styles[:common], suffixes)
|
224
|
-
if section.is_a?(BaseFieldSection)
|
225
|
-
# form cell: _<type>_<field_name> = `_field_email`
|
226
|
-
suffixes << :"#{type}_#{section.name}" if section.name
|
227
|
-
elsif section.respond_to?(:cell_section_name) # cell section came from table
|
228
|
-
# table cell: _<table_cell_section_name> = `_title`
|
229
|
-
suffixes << section.cell_section_name
|
230
|
-
end
|
231
|
-
# table: <table_name>_table_<type>, <table_name>_table_<table_cell_section_name> = `categories_table_cell`, `categories_table_title`
|
232
|
-
# form: <form_name>_form_<type>, <form_name>_form_<field_type>, user_form_<type>_email = `user_form_field`, `user_form_string_field`, `user_form_field_email`
|
233
|
-
styles[:specific] = build_styles_chain(table_styles[:specific], suffixes)
|
234
|
-
|
235
|
-
container_options_styles = section.container_options[:styles]
|
236
|
-
if container_options_styles.present?
|
237
|
-
styles[:specific] += Array.wrap(container_options_styles)
|
238
|
-
end
|
239
|
-
|
240
|
-
styles
|
241
|
-
end
|
242
|
-
|
243
|
-
def table_delegate
|
244
|
-
@table_delegate ||= TableDelegate.new(section: self)
|
121
|
+
def collection_delegate
|
122
|
+
@collection_delegate ||= TableDelegate.new(section: self)
|
245
123
|
end
|
246
124
|
|
247
125
|
def table_element_options
|
248
|
-
|
249
|
-
section: self.weak_ref,
|
250
|
-
styles: table_styles.values.flatten,
|
251
|
-
delegate: table_delegate,
|
252
|
-
data_source: table_delegate,
|
126
|
+
collection_element_options.merge({
|
253
127
|
style: (UITableViewStyleGrouped unless flat_data?)
|
254
128
|
})
|
255
129
|
end
|
256
130
|
|
257
|
-
def
|
258
|
-
self.
|
259
|
-
end
|
260
|
-
|
261
|
-
def table_view
|
262
|
-
table_element.try(:view)
|
263
|
-
end
|
264
|
-
|
265
|
-
def hide
|
266
|
-
table_view.try(:hide)
|
267
|
-
end
|
268
|
-
|
269
|
-
def show
|
270
|
-
table_view.try(:show)
|
131
|
+
def render_collection
|
132
|
+
self.collection_element = screen.table_view(table_element_options)
|
271
133
|
end
|
272
134
|
|
273
135
|
def render_cell(index)
|
274
|
-
section =
|
136
|
+
section = cell_section_by_index(index)
|
275
137
|
element = section.container_element || section.init_container_element(container_element_options_for(index))
|
276
138
|
|
277
139
|
view = element.render do
|
@@ -284,7 +146,7 @@ module MotionPrime
|
|
284
146
|
|
285
147
|
def render_header(group)
|
286
148
|
return unless options = self.group_header_options.try(:[], group)
|
287
|
-
self.group_header_sections[group] ||= FormHeaderSection.new(options.merge(screen: screen,
|
149
|
+
self.group_header_sections[group] ||= FormHeaderSection.new(options.merge(screen: screen, collection_section: self.weak_ref))
|
288
150
|
end
|
289
151
|
|
290
152
|
def header_section_for_group(group)
|
@@ -292,10 +154,6 @@ module MotionPrime
|
|
292
154
|
self.group_header_sections[group] || render_header(group)
|
293
155
|
end
|
294
156
|
|
295
|
-
def on_cell_render(cell, index); end
|
296
|
-
def on_appear; end
|
297
|
-
def on_click(index); end
|
298
|
-
|
299
157
|
def has_many_sections?
|
300
158
|
group_header_options.present? || data.try(:first).is_a?(Array)
|
301
159
|
end
|
@@ -308,15 +166,6 @@ module MotionPrime
|
|
308
166
|
flat_data? ? data : data[section]
|
309
167
|
end
|
310
168
|
|
311
|
-
def cell_section_by_index(index)
|
312
|
-
cell_sections_for_group(index.section)[index.row]
|
313
|
-
end
|
314
|
-
|
315
|
-
def cell_name(index)
|
316
|
-
record = cell_section_by_index(index)
|
317
|
-
"cell_#{record.object_id}_#{@data_stamp[record.object_id]}"
|
318
|
-
end
|
319
|
-
|
320
169
|
# Table View Delegate
|
321
170
|
# ---------------------
|
322
171
|
|
@@ -324,33 +173,18 @@ module MotionPrime
|
|
324
173
|
has_many_sections? ? data.count : 1
|
325
174
|
end
|
326
175
|
|
327
|
-
def cell_for_index(index)
|
328
|
-
cell = cached_cell(index) || render_cell(index)
|
329
|
-
# run table view is appeared callback if needed
|
330
|
-
if !@did_appear && index.row == cell_sections_for_group(index.section).size - 1
|
331
|
-
on_appear
|
332
|
-
end
|
333
|
-
cell.is_a?(UIView) ? cell : cell.view
|
334
|
-
end
|
335
|
-
|
336
|
-
def height_for_index(index)
|
337
|
-
section = cell_section_by_index(index)
|
338
|
-
section.create_elements
|
339
|
-
section.container_height
|
340
|
-
end
|
341
|
-
|
342
176
|
def header_cell_in_group(group)
|
343
177
|
return unless header = header_section_for_group(group)
|
344
178
|
|
345
179
|
reuse_identifier = "header_#{group}_#{@header_stamp}"
|
346
|
-
cached =
|
180
|
+
cached = collection_view.dequeueReusableHeaderFooterViewWithIdentifier(reuse_identifier)
|
347
181
|
return cached if cached.present?
|
348
182
|
|
349
183
|
styles = cell_section_styles(header).values.flatten
|
350
184
|
wrapper = MotionPrime::BaseElement.factory(:table_header,
|
351
185
|
screen: screen,
|
352
186
|
styles: styles,
|
353
|
-
parent_view:
|
187
|
+
parent_view: collection_view,
|
354
188
|
reuse_identifier: reuse_identifier,
|
355
189
|
section: header.weak_ref
|
356
190
|
)
|
@@ -364,22 +198,6 @@ module MotionPrime
|
|
364
198
|
header_section_for_group(group).try(:container_height) || 0
|
365
199
|
end
|
366
200
|
|
367
|
-
def scroll_view_will_begin_dragging(scroll)
|
368
|
-
@decelerating = true
|
369
|
-
end
|
370
|
-
|
371
|
-
def scroll_view_did_end_decelerating(scroll)
|
372
|
-
@decelerating = false
|
373
|
-
display_pending_cells
|
374
|
-
end
|
375
|
-
|
376
|
-
def scroll_view_did_scroll(scroll)
|
377
|
-
end
|
378
|
-
|
379
|
-
def scroll_view_did_end_dragging(scroll, willDecelerate: will_decelerate)
|
380
|
-
display_pending_cells unless @decelerating = will_decelerate
|
381
|
-
end
|
382
|
-
|
383
201
|
private
|
384
202
|
def delete_from_flat_data(index)
|
385
203
|
@data[index.row] = nil
|
@@ -391,25 +209,8 @@ module MotionPrime
|
|
391
209
|
@data[index.section].delete_at(index.row)
|
392
210
|
end
|
393
211
|
|
394
|
-
def display_pending_cells
|
395
|
-
table_view.visibleCells.each do |cell_view|
|
396
|
-
if cell_view.section && cell_view.section.pending_display
|
397
|
-
cell_view.section.display
|
398
|
-
end
|
399
|
-
end
|
400
|
-
end
|
401
|
-
|
402
|
-
def set_table_data
|
403
|
-
sections = fixed_table_data
|
404
|
-
prepare_table_cell_sections(sections)
|
405
|
-
@data = sections
|
406
|
-
reset_data_stamps
|
407
|
-
create_section_elements
|
408
|
-
@data
|
409
|
-
end
|
410
|
-
|
411
212
|
def cached_cell(index)
|
412
|
-
|
213
|
+
collection_view.dequeueReusableCellWithIdentifier(cell_name(index)) || begin
|
413
214
|
section = cell_section_by_index(index)
|
414
215
|
cell = section.try(:cell)
|
415
216
|
if cell.try(:superview)
|
@@ -420,62 +221,27 @@ module MotionPrime
|
|
420
221
|
end
|
421
222
|
|
422
223
|
def deque_cell(section, at: index)
|
423
|
-
|
224
|
+
collection_view.dequeueReusableCellWithIdentifier(cell_name(index))
|
424
225
|
section.cell.try(:removeFromSuperview)
|
425
226
|
set_data_stamp(section.object_id)
|
426
227
|
end
|
427
228
|
|
428
|
-
def prepare_table_cell_sections(cells)
|
429
|
-
Array.wrap(cells.flatten).each do |cell|
|
430
|
-
Prime::Config.prime.cell_section.mixins.each do |mixin|
|
431
|
-
cell.class.send(:include, mixin) unless (class << cell; self; end).included_modules.include?(mixin)
|
432
|
-
end
|
433
|
-
cell.screen ||= screen
|
434
|
-
cell.table ||= self.weak_ref if cell.respond_to?(:table=)
|
435
|
-
end
|
436
|
-
end
|
437
|
-
|
438
|
-
def container_element_options_for(index)
|
439
|
-
cell_section = cell_section_by_index(index)
|
440
|
-
{
|
441
|
-
reuse_identifier: cell_name(index),
|
442
|
-
parent_view: table_view,
|
443
|
-
bounds: {height: cell_section.container_height}
|
444
|
-
}
|
445
|
-
end
|
446
|
-
|
447
|
-
def set_data_stamp(section_ids)
|
448
|
-
@data_stamp ||= {}
|
449
|
-
[*section_ids].each do |id|
|
450
|
-
@data_stamp[id] = Time.now.to_f
|
451
|
-
end
|
452
|
-
end
|
453
|
-
|
454
229
|
def set_header_stamp
|
455
230
|
@header_stamp = Time.now.to_i
|
456
231
|
end
|
457
232
|
|
458
233
|
def reset_data_stamps
|
459
|
-
|
460
|
-
set_data_stamp(keys)
|
234
|
+
super
|
461
235
|
set_header_stamp
|
462
236
|
end
|
463
237
|
|
464
|
-
def create_section_elements
|
465
|
-
if flat_data?
|
466
|
-
data.each(&:create_elements)
|
467
|
-
else
|
468
|
-
data.each { |group_sections| group_sections.each(&:create_elements) }
|
469
|
-
end
|
470
|
-
end
|
471
|
-
|
472
238
|
class << self
|
473
239
|
def inherited(subclass)
|
474
240
|
super
|
475
241
|
subclass.group_header_options = self.group_header_options.try(:clone)
|
476
242
|
end
|
477
243
|
|
478
|
-
def
|
244
|
+
def async_collection_data(options = {})
|
479
245
|
self.send :include, Prime::AsyncTableMixin
|
480
246
|
self.set_async_data_options options
|
481
247
|
end
|