motion-prime 0.9.9 → 0.9.9.1
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.
- 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
|