motion-prime 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
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