Class: MotionPrime::TableSection

Inherits:
AbstractCollectionSection show all
Includes:
HasSearchBar, TableSectionRefreshMixin
Defined in:
motion-prime/sections/table.rb

Direct Known Subclasses

FormSection

Constant Summary

Constants inherited from Section

Section::DEFAULT_CONTENT_HEIGHT, Section::KEYBOARD_HEIGHT_LANDSCAPE, Section::KEYBOARD_HEIGHT_PORTRAIT

Instance Attribute Summary collapse

Attributes inherited from AbstractCollectionSection

#collection_element, #decelerating, #did_appear

Attributes inherited from Section

#elements, #model, #name, #options, #screen, #section_styles

Attributes included from DrawSectionMixin

#cached_draw_image, #container_element, #container_gesture_recognizers

Class Method Summary collapse

Instance Method Summary collapse

Methods included from HasSearchBar

#add_search_bar, #create_search_bar, #dealloc, #searchBar, #searchBarSearchButtonClicked

Methods included from TableSectionRefreshMixin

#add_pull_to_refresh, #finish_pull_to_refresh

Methods inherited from AbstractCollectionSection

#cell_for_index, #cell_name, #cell_section_by_index, #cell_section_styles, #collection_data, #collection_element_options, #collection_styles, #collection_view, #data, #dealloc, #fixed_collection_data, #height_for_index, #hide, #on_appear, #on_cell_render, #on_click, #refresh_if_needed, #reload, #reload_collection_data, #reload_data, #reset_collection_data, #scroll_view_did_end_decelerating, #scroll_view_did_end_dragging, #scroll_view_did_scroll, #scroll_view_will_begin_dragging, #show, #update_pull_to_refresh_after_scroll

Methods included from HasStyleChainBuilder

#build_styles_chain

Methods inherited from Section

#add_element, after_element_render, #after_element_render, after_initialize, after_render, before_initialize, before_render, bind_keyboard_close, #bind_keyboard_events, #bring_to_front, container, #container_bounds, #container_height, #container_options, #create_elements, #current_input_view_height, #dealloc, #default_name, #element, element, #elements_options, #elements_to_draw, #elements_to_render, #hard_reload_section, #has_container_bounds?, #hide, #hide_keyboard, #initialize, #keyboard_will_hide, #keyboard_will_show, #on_keyboard_hide, #on_keyboard_show, #reload, #render, #render!, #render_container, #render_element?, #screen?, #show, #strong_references, #view

Methods included from DelegateMixin

#clear_delegated, #delegated_by

Methods included from DrawSectionMixin

#after_element_render, #before_element_render, #bind_gesture_on_container_for, #clear_gesture_for_receiver, #draw_in, #prerender_elements_for_state, #prerender_enabled?

Methods included from SectionWithContainerMixin

#container_view, #init_container_element, #load_container_with_elements

Methods included from FrameCalculatorMixin

#calculate_frame_for

Methods included from HasStyles

#prepare_gradient

Methods included from HasClassFactory

#camelize_factory, #class_factory, #low_camelize_factory, #underscore_factory

Methods included from HasNormalizer

#debug_info, #element?, #normalize_object, #normalize_options, #normalize_value

Methods included from HasAuthorization

#api_client, #current_user, #reset_current_user, #user_signed_in?

Constructor Details

This class inherits a constructor from MotionPrime::Section

Instance Attribute Details

#group_header_optionsObject

Returns the value of attribute group_header_options.



11
12
13
# File 'motion-prime/sections/table.rb', line 11

def group_header_options
  @group_header_options
end

#group_header_sectionsObject

Returns the value of attribute group_header_sections.



11
12
13
# File 'motion-prime/sections/table.rb', line 11

def group_header_sections
  @group_header_sections
end

Class Method Details

.async_collection_data(options = {}) ⇒ Object



245
246
247
248
# File 'motion-prime/sections/table.rb', line 245

def async_collection_data(options = {})
  self.send :include, Prime::AsyncTableMixin
  self.set_async_data_options options
end

.group_header(name, options) ⇒ Object



250
251
252
253
254
255
# File 'motion-prime/sections/table.rb', line 250

def group_header(name, options)
  options[:name] = name
  self.group_header_options ||= []
  section = options.delete(:id)
  self.group_header_options[section] = options
end

.inherited(subclass) ⇒ Object



240
241
242
243
# File 'motion-prime/sections/table.rb', line 240

def inherited(subclass)
  super
  subclass.group_header_options = self.group_header_options.try(:clone)
end

.pull_to_refresh(options = {}, &block) ⇒ Object



257
258
259
260
# File 'motion-prime/sections/table.rb', line 257

def pull_to_refresh(options = {}, &block)
  self.pull_to_refresh_options = options
  self.pull_to_refresh_block = block
end

Instance Method Details

#add_cell_sections(sections, index = nil) ⇒ Boolean

Add cells to table view and reload table view.

Parameters:

  • cell

    sections [Prime::Section, Array<Prime::Section>] cells which will be added to table view.

Returns:

  • (Boolean)

    true



19
20
21
22
23
24
25
# File 'motion-prime/sections/table.rb', line 19

def add_cell_sections(sections, index = nil)
  prepare_collection_cell_sections(sections)
  @data ||= []
  index ||= @data.count
  @data.insert([index, @data.count].min, *sections)
  reload_collection_data
end

#cell_sections_for_group(section) ⇒ Object



165
166
167
# File 'motion-prime/sections/table.rb', line 165

def cell_sections_for_group(section)
  flat_data? ? data : data[section]
end

#collection_delegateObject



121
122
123
# File 'motion-prime/sections/table.rb', line 121

def collection_delegate
  @collection_delegate ||= TableDelegate.new(section: self)
end

#collection_styles_baseObject



115
116
117
118
119
# File 'motion-prime/sections/table.rb', line 115

def collection_styles_base
  base_styles = [:base_table]
  base_styles << :"#{type}_with_sections" unless flat_data?
  base_styles
end

#delete_cell_sections(sections, &block) ⇒ Array<NSIndexPath>

Delete cells from table data and remove them from table view with animation.

Parameters:

  • cell

    sections [Prime::Section, Array<Prime::Section>] cells which will be removed from table view.

Returns:

  • (Array<NSIndexPath>)

    index paths of removed cells.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'motion-prime/sections/table.rb', line 31

def delete_cell_sections(sections, &block)
  paths = []
  Array.wrap(sections).each do |section|
    index = index_for_cell_section(section)
    next Prime.logger.debug("Delete cell section: `#{section.name}` is not in the list") unless index
    paths << index
    delete_from_data(index)
  end
  if paths.any?
    UIView.animate(duration: 0, after: block) do
      collection_view.beginUpdates
      collection_view.deleteRowsAtIndexPaths(paths, withRowAnimation: UITableViewRowAnimationLeft)
      collection_view.endUpdates
    end
  end
  paths
end

#delete_from_data(index) ⇒ Object

Delete section from data at index

Parameters:

  • index (NSIndexPath)

    index of cell which will be removed from table data.



91
92
93
94
95
96
97
# File 'motion-prime/sections/table.rb', line 91

def delete_from_data(index)
  if flat_data?
    delete_from_flat_data(index)
  else
    delete_from_grouped_data(index)
  end
end

#flat_data?Boolean

Returns:

  • (Boolean)


161
162
163
# File 'motion-prime/sections/table.rb', line 161

def flat_data?
  !has_many_sections?
end

#has_many_sections?Boolean

Returns:

  • (Boolean)


157
158
159
# File 'motion-prime/sections/table.rb', line 157

def has_many_sections?
  group_header_options.present? || data.try(:first).is_a?(Array)
end

#header_cell_in_group(group) ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'motion-prime/sections/table.rb', line 176

def header_cell_in_group(group)
  return unless header = header_section_for_group(group)

  reuse_identifier = "header_#{group}_#{@header_stamp}"
  cached = collection_view.dequeueReusableHeaderFooterViewWithIdentifier(reuse_identifier)
  return cached if cached.present?

  styles = cell_section_styles(header).values.flatten
  wrapper = MotionPrime::BaseElement.factory(:table_header,
    screen: screen,
    styles: styles,
    parent_view: collection_view,
    reuse_identifier: reuse_identifier,
    section: header.weak_ref
  )
  wrapper.render do |container_view, container_element|
    header.container_element = container_element
    header.render
  end
end

#header_section_for_group(group) ⇒ Object



152
153
154
155
# File 'motion-prime/sections/table.rb', line 152

def header_section_for_group(group)
  self.group_header_sections ||= []
  self.group_header_sections[group] || render_header(group)
end

#height_for_header_in_group(group) ⇒ Object



197
198
199
# File 'motion-prime/sections/table.rb', line 197

def height_for_header_in_group(group)
  header_section_for_group(group).try(:container_height) || 0
end

#index_for_cell_section(section) ⇒ Object

Get index path for cell section

Parameters:

  • section (Prime::Section)

    cell section.



103
104
105
106
107
108
109
110
111
112
113
# File 'motion-prime/sections/table.rb', line 103

def index_for_cell_section(section)
  if flat_data?
    row = @data.try(:index, section)
    NSIndexPath.indexPathForRow(row, inSection: 0) if row
  else
    (@data || []).each_with_index do |cell_sections, group|
      row = cell_sections.index(section)
      return NSIndexPath.indexPathForRow(row, inSection: group) if row
    end
  end
end

#number_of_groupsObject

Table View Delegate




172
173
174
# File 'motion-prime/sections/table.rb', line 172

def number_of_groups
  has_many_sections? ? data.count : 1
end

#reload_cell_sections(sections, &block) ⇒ Array<NSIndexPath>

Reloads cells with animation, executes given block before reloading.

Parameters:

  • cell

    sections [Prime::Section, Array<Prime::Section>] cells which will be updated.

  • around

    callback [Proc] Callback which will be executed before reloading.

Returns:

  • (Array<NSIndexPath>)

    index paths of reloaded cells.



54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'motion-prime/sections/table.rb', line 54

def reload_cell_sections(sections, &block)
  paths = []
  Array.wrap(sections).each_with_index do |section, counter|
    index = index_for_cell_section(section)
    next Prime.logger.debug("Reload section: `#{section.name}` is not in the list") unless index
    paths << index
    block.call(section, index, counter)
    deque_cell(section, at: index) # deque cached
    section.reload
  end
  self.performSelectorOnMainThread(:reload_cells, withObject: paths, waitUntilDone: false)
  paths
end

#reload_cells(*paths) ⇒ Object

Forces TableView to reload Rows by index paths

Parameters:

  • index (Array<NSIndexPath>)

    paths of cells to reload.



71
72
73
74
# File 'motion-prime/sections/table.rb', line 71

def reload_cells(*paths)
  collection_view.reloadRowsAtIndexPaths(Array.wrap(paths), withRowAnimation: UITableViewRowAnimationFade)
  collection_view.reloadData # do not use reload_collection_data (due to async_form_mixin)
end

#render_cell(index) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
# File 'motion-prime/sections/table.rb', line 135

def render_cell(index)
  section = cell_section_by_index(index)
  element = section.container_element || section.init_container_element(container_element_options_for(index))

  view = element.render do
    section.render
  end

  on_cell_render(view, index)
  view
end

#render_collectionObject



131
132
133
# File 'motion-prime/sections/table.rb', line 131

def render_collection
  self.collection_element = screen.table_view(table_element_options)
end

#render_header(group) ⇒ Object



147
148
149
150
# File 'motion-prime/sections/table.rb', line 147

def render_header(group)
  return unless options = self.group_header_options.try(:[], group)
  self.group_header_sections[group] ||= FormHeaderSection.new(options.merge(screen: screen, collection_section: self.weak_ref))
end

#resize_cell_sections(sections, height) ⇒ Array<NSIndexPath>

Changes height of cells with animation.

Parameters:

  • cell

    sections [Prime::Section, Array<Prime::Section>] cells which will be updated.

  • height (Integer, Array<Integer>)

    new height of all cells, or height for each cell.

Returns:

  • (Array<NSIndexPath>)

    index paths of removed cells.



81
82
83
84
85
86
# File 'motion-prime/sections/table.rb', line 81

def resize_cell_sections(sections, height)
  reload_cell_sections(sections) do |section, index, counter|
    container_height = height.is_a?(Array) ? height[counter] : height
    section.container_options[:height] = container_height
  end
end

#table_element_optionsObject



125
126
127
128
129
# File 'motion-prime/sections/table.rb', line 125

def table_element_options
  collection_element_options.merge({
    style: (UITableViewStyleGrouped unless flat_data?)
  })
end