motion-prime 1.0.5 → 1.0.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 45140a3e0294c388e06a65d8984b3178d3a61860
4
- data.tar.gz: bbdb962a185668be9c8788616fd562697b4dc80f
3
+ metadata.gz: 5a7abdeb0d07ef7b8ff96929509ca71f4d9735b2
4
+ data.tar.gz: 506e027301a4ce09c546ae0a89103813bf708158
5
5
  SHA512:
6
- metadata.gz: 29e217defff9f85b314495158591cd4bb0215d58f86e3bee2e7660fd4e70e36668c035917f9589345425527d3f10edfd02d57255bfd7608937279b09203682cc
7
- data.tar.gz: a459b509909885a8b77d71f94a4cb02cb12e91f56b9c9f91c24b1e1c863d9ba073b105258908fc6648da2487d8225638a98bc34b3bc479ec55f30a7c3f29b78d
6
+ metadata.gz: 4890d0d9e1f0231b41194eef01979d6b6f9314c465e8b4a4e5b9280ee1dc67924c148d746ab8263d7c996cf9eec39ba1c16827e7d4072a22cc162c0e2eead179
7
+ data.tar.gz: 114bd8c2ab635bd8ce17a4963965b03428bb71a045fdcec832c4e11d9e23841b386b0b295096d97aa7330a1b4a9e564ad2b702c4ff4f74cf96fac0f2806429c1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ === 1.0.6
2
+ * Memory leak fixes
3
+ * Fix pagination of page view section
4
+
1
5
  === 1.0.5
2
6
  * Bug fixes
3
7
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- motion-prime (1.0.5)
4
+ motion-prime (1.0.6)
5
5
  activesupport
6
6
  afmotion (~> 2.1.0)
7
7
  bubble-wrap (~> 1.6.0)
data/files/Gemfile CHANGED
@@ -1,7 +1,7 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
3
  gem 'motion-cocoapods', '~> 1.4.1'
4
- gem 'motion-prime', '1.0.5'
4
+ gem 'motion-prime', '1.0.6'
5
5
 
6
6
  # add reside menu for sidebar support
7
7
  # gem 'prime_reside_menu', '~> 0.1.4'
@@ -91,7 +91,11 @@ class Kernel
91
91
  Prime.logger.debug "User must define `strong_references` in `#{self.class.name}`"
92
92
  return false
93
93
  end
94
- @_strong_references.all? { |key, ref| @_strong_references.count; ref.retainCount == @_strong_references.count }
94
+ res = @_strong_references.all? { |key, refs|
95
+ refs.all? { |ref| ref.retainCount - 1 <= @_strong_references.count }
96
+ }
97
+ Prime.logger.debug "Released `#{self.class.name}`" if res
98
+ res
95
99
  end
96
100
 
97
101
  def clear_instance_variables(options = {})
@@ -24,6 +24,7 @@ module MotionPrime
24
24
  }
25
25
 
26
26
  text = "#{options[:text]}<style>* { #{styles.join} }</style>"
27
+ # WARNING: there is a bug - it uses WebKit and can not be used in secondary threads
27
28
  NSAttributedString.alloc.initWithData(text.dataUsingEncoding(NSUTF8StringEncoding), options: html_options, documentAttributes: nil, error: nil)
28
29
  end
29
30
 
@@ -70,9 +70,10 @@ module MotionPrime
70
70
  end
71
71
 
72
72
  def strong_references
73
- refs = [section, (section.collection_section if section.respond_to?(:cell_section_name))]
74
- refs += section.try(:strong_references)
75
- refs.compact
73
+ # .compact() is required here, otherwise screen will not be released
74
+ refs = [section, (section.collection_section if section.respond_to?(:cell_section_name))].compact
75
+ refs += section.strong_references if section
76
+ refs
76
77
  end
77
78
 
78
79
  def load_image
@@ -92,12 +93,15 @@ module MotionPrime
92
93
  return
93
94
  end
94
95
 
96
+ if computed_options[:post_process].present?
97
+ image = computed_options[:post_process][:method].to_proc.call(computed_options[:post_process][:target], image)
98
+ end
95
99
  self.image_data = image
96
100
  section.cached_draw_image = nil
97
101
  if section.respond_to?(:cell_section_name)
98
102
  section.pending_display!
99
103
  else
100
- self.view.performSelectorOnMainThread :setNeedsDisplay, withObject: nil, waitUntilDone: false
104
+ self.view.performSelectorOnMainThread :setNeedsDisplay, withObject: nil, waitUntilDone: true
101
105
  end
102
106
  @loading = false
103
107
  release_strong_references(ref_key)
@@ -1,6 +1,7 @@
1
1
  module MotionPrime
2
2
  class ImageElement < BaseElement
3
3
  after_render :fetch_image
4
+
4
5
  def view_class
5
6
  "UIImageView"
6
7
  end
@@ -8,8 +9,40 @@ module MotionPrime
8
9
  def fetch_image
9
10
  return unless computed_options[:url]
10
11
  raise "You must set default image for `#{name}`" unless computed_options[:default]
11
- view.setImageWithURL NSURL.URLWithString(computed_options[:url]),
12
- placeholderImage: computed_options[:default].uiimage
12
+
13
+ view.setImage(computed_options[:default].uiimage)
14
+ ref_key = allocate_strong_references
15
+ BW::Reactor.schedule do
16
+ manager = SDWebImageManager.sharedManager
17
+ manager.downloadWithURL(computed_options[:url],
18
+ options: 0,
19
+ progress: lambda{ |r_size, e_size| },
20
+ completed: lambda{ |image, error, type, finished|
21
+ unless image
22
+ release_strong_references(ref_key)
23
+ return
24
+ end
25
+
26
+ if computed_options[:post_process].present?
27
+ image = computed_options[:post_process][:method].to_proc.call(computed_options[:post_process][:target], image)
28
+ end
29
+
30
+ self.performSelectorOnMainThread :set_image, withObject: image, waitUntilDone: true
31
+ release_strong_references(ref_key)
32
+ }
33
+ )
34
+ end
35
+ end
36
+
37
+ def set_image(*args)
38
+ self.view.setImage(args)
39
+ end
40
+
41
+ def strong_references
42
+ # .compact() is required here, otherwise screen will not be released
43
+ refs = [section, (section.collection_section if section.respond_to?(:cell_section_name))].compact
44
+ refs += section.strong_references if section
45
+ refs
13
46
  end
14
47
  end
15
48
  end
@@ -31,7 +31,7 @@ module MotionPrime
31
31
  name = is_a?(TableSection) ? name : self.class_name_without_kvo.underscore
32
32
  screen = is_a?(TableSection) ? self.screen : self
33
33
  options[:styles] ||= []
34
- options[:styles] += [:"base_search_bar", :"base_#{name}_search_bar"]
34
+ options[:styles] += [:"base_search_bar", :"base_#{name}_search_bar", :"#{name}_search_bar"]
35
35
 
36
36
  screen.search_bar(options).view
37
37
  end
@@ -162,7 +162,7 @@ module MotionPrime
162
162
  if respond_to?(:"fetch_#{key}")
163
163
  self.send(:"fetch_#{key}", value)
164
164
  elsif has_association?(key) && (value.is_a?(Hash) || value.is_a?(Array))
165
- fetch_association_with_attributes(key, value, save: options[:save_associations])
165
+ fetch_association_with_attributes(key.to_sym, value, save: options[:save_associations])
166
166
  elsif respond_to?(:"#{key}=")
167
167
  self.send(:"#{key}=", value)
168
168
  # TODO: self.info[:"#{key}"] = value is much faster, maybe we could use it
@@ -59,7 +59,7 @@ module MotionPrime
59
59
  end
60
60
 
61
61
  def has_navigation?
62
- !navigation_controller.nil?
62
+ navigation_controller.weakref_alive? && !navigation_controller.nil?
63
63
  end
64
64
 
65
65
  def navigation_controller
@@ -222,6 +222,10 @@ module MotionPrime
222
222
  @decelerating = true
223
223
  end
224
224
 
225
+ def scroll_view_will_begin_decelerating(scroll); end
226
+
227
+ def scroll_view_did_end_scrolling_animation(scroll); end
228
+
225
229
  def scroll_view_did_end_decelerating(scroll)
226
230
  @decelerating = false
227
231
  display_pending_cells
@@ -278,6 +282,7 @@ module MotionPrime
278
282
  Prime::Config.prime.cell_section.mixins.each do |mixin|
279
283
  cell.class.send(:include, mixin) unless (class << cell; self; end).included_modules.include?(mixin)
280
284
  end
285
+
281
286
  cell.screen ||= screen
282
287
  cell.collection_section ||= self.weak_ref if cell.respond_to?(:collection_section=)
283
288
  end
@@ -54,7 +54,7 @@ module MotionPrime
54
54
  end
55
55
 
56
56
  def strong_references
57
- [screen, screen.try(:main_controller)]
57
+ [screen, screen.try(:main_controller)].compact
58
58
  end
59
59
 
60
60
  def container_bounds
@@ -49,10 +49,18 @@ module MotionPrime
49
49
  collection_section.update_pull_to_refresh_after_scroll(scroll)
50
50
  end
51
51
 
52
+ def scrollViewDidEndScrollingAnimation(scroll)
53
+ collection_section.scroll_view_did_end_scrolling_animation(scroll)
54
+ end
55
+
52
56
  def scrollViewWillBeginDragging(scroll)
53
57
  collection_section.scroll_view_will_begin_dragging(scroll)
54
58
  end
55
59
 
60
+ def scrollViewWillBeginDecelerating(scroll)
61
+ collection_section.scroll_view_will_begin_decelerating(scroll)
62
+ end
63
+
56
64
  def scrollViewDidEndDecelerating(scroll)
57
65
  collection_section.scroll_view_did_end_decelerating(scroll)
58
66
  end
@@ -120,8 +120,8 @@ module MotionPrime
120
120
  end
121
121
 
122
122
  def keyboard_will_show
123
- return if collection_view.contentSize.height + collection_view.top <= UIScreen.mainScreen.bounds.size.height - KEYBOARD_HEIGHT_PORTRAIT
124
123
  current_inset = collection_view.contentInset
124
+ return if collection_view.contentSize.height + collection_view.top + current_inset.top <= UIScreen.mainScreen.bounds.size.height - KEYBOARD_HEIGHT_PORTRAIT
125
125
  current_inset.bottom = KEYBOARD_HEIGHT_PORTRAIT + (self.collection_element.computed_options[:bottom_content_inset] || 0)
126
126
  collection_view.contentInset = current_inset
127
127
  end
@@ -163,7 +163,6 @@ module MotionPrime
163
163
  end
164
164
 
165
165
  def reload_data
166
- @groups_count = nil
167
166
  init_form_fields # must be before resetting to reflect changes on @data
168
167
  reset_collection_data
169
168
  reload_collection_data
@@ -250,32 +249,33 @@ module MotionPrime
250
249
  self.field_indexes = {}
251
250
  self.grouped_data = []
252
251
  section_indexes = []
253
- (self.class.fields_options || {}).each do |key, field|
254
- next unless render_field?(key, field)
255
- section_id = field[:group].to_i
256
- @groups_count = [@groups_count || 1, section_id + 1].max
257
252
 
258
- grouped_data[section_id] ||= []
259
- section_indexes[section_id] ||= 0
253
+ grouped_fields = (self.class.fields_options || {}).inject([]) do |result, (key, field)|
254
+ next result unless render_field?(key, field)
255
+ group_id = field[:group].to_i
256
+ result[group_id] ||= {}
257
+ result[group_id][key] = field
258
+ result
259
+ end
260
260
 
261
- section = load_field(field)
262
- if section.options[:after_render].present?
263
- puts "DEPRECATION: form field's option :after_render is deprecated, please use Prime::Section#after_field_render instead"
261
+ header_options = Array.wrap(self.class.group_header_options).map(&:clone)
262
+ header_options.each { |opts| normalize_options(opts) if opts }
263
+ self.group_header_options = header_options.delete_if.each_with_index { |opts, id| grouped_fields[id].blank? }
264
+
265
+ grouped_fields.compact.each_with_index do |fields, group_id|
266
+ fields.each_with_index do |(key, field), row_id|
267
+ section = load_field(field)
268
+ if section.options[:after_render].present?
269
+ puts "DEPRECATION: form field's option :after_render is deprecated, please use Prime::Section#after_field_render instead"
270
+ end
271
+ self.fields[key] = section
272
+ self.field_indexes[key] = NSIndexPath.indexPathForRow(row_id, inSection: group_id)
273
+ grouped_data[group_id] ||= []
274
+ grouped_data[group_id][row_id] = section
264
275
  end
265
- self.fields[key] = section
266
- self.field_indexes[key] = NSIndexPath.indexPathForRow(section_indexes[section_id], inSection: section_id)
267
- grouped_data[section_id][section_indexes[section_id]] = section
268
-
269
- section_indexes[section_id] += 1
270
276
  end
271
- init_form_headers
272
- reset_data_stamps
273
- end
274
277
 
275
- def init_form_headers
276
- options = Array.wrap(self.class.group_header_options).map(&:clone)
277
- options.compact.each { |opts| normalize_options(opts) }
278
- self.group_header_options = options.delete_if.each_with_index { |opts, id| grouped_data[id].nil? }
278
+ reset_data_stamps
279
279
  end
280
280
  end
281
281
  end
@@ -66,21 +66,27 @@ module MotionPrime
66
66
  # Delegate
67
67
  def page_for_index(index)
68
68
  return nil if !index || data.length == 0 || index < 0 || index >= data.size
69
- @view_controllers ||= []
70
- if @view_controllers[index]
71
- @view_controllers[index]
72
- else
69
+ @view_controllers.try(:[], index) || prepare_cell_section(data[index], index)
70
+ end
71
+
72
+ def index_for_page(view_controller)
73
+ Array.wrap(@view_controllers).index(view_controller)
74
+ end
75
+
76
+ private
77
+ def prepare_collection_cell_sections(sections)
78
+ Array.wrap(sections.flatten).each_with_index do |section, index|
79
+ prepare_cell_section(section, index)
80
+ end
81
+ end
82
+
83
+ def prepare_cell_section(section, index)
84
+ @view_controllers ||= []
73
85
  controller = MotionPrime::Screen.new
74
86
  controller.parent_screen = self.screen
75
- section = data[index]
76
87
  section.screen = controller.weak_ref
77
88
  controller.set_section :main, instance: section
78
89
  @view_controllers[index] = controller
79
90
  end
80
- end
81
-
82
- def index_for_page(view_controller)
83
- Array.wrap(@view_controllers).index(view_controller)
84
- end
85
91
  end
86
92
  end
@@ -234,6 +234,9 @@ module MotionPrime
234
234
  def reset_data_stamps
235
235
  super
236
236
  set_header_stamp
237
+ rescue # "undefined `super` method" bug fix
238
+ Prime.logger.debug "Undefined `super` in `table_section`"
239
+ []
237
240
  end
238
241
 
239
242
  class << self
@@ -64,10 +64,18 @@ module MotionPrime
64
64
  table_section.update_pull_to_refresh_after_scroll(scroll)
65
65
  end
66
66
 
67
+ def scrollViewDidEndScrollingAnimation(scroll)
68
+ table_section.scroll_view_did_end_scrolling_animation(scroll)
69
+ end
70
+
67
71
  def scrollViewWillBeginDragging(scroll)
68
72
  table_section.scroll_view_will_begin_dragging(scroll)
69
73
  end
70
74
 
75
+ def scrollViewWillBeginDecelerating(scroll)
76
+ table_section.scroll_view_will_begin_decelerating(scroll)
77
+ end
78
+
71
79
  def scrollViewDidEndDecelerating(scroll)
72
80
  table_section.scroll_view_did_end_decelerating(scroll)
73
81
  end
@@ -1,3 +1,3 @@
1
1
  module MotionPrime
2
- VERSION = "1.0.5"
2
+ VERSION = "1.0.6"
3
3
  end
@@ -281,7 +281,7 @@ module MotionPrime
281
281
  max_width max_outer_width min_width min_outer_width
282
282
  max_height max_outer_height min_height min_outer_width
283
283
  font_name font_size placeholder_font_name placeholder_font_size placeholder_font
284
- bounds
284
+ bounds post_process
285
285
  ].include?(key.to_s)
286
286
  end
287
287
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motion-prime
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Iskander Haziev
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-08-11 00:00:00.000000000 Z
12
+ date: 2014-08-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake