motion-prime 0.5.5 → 0.5.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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZWI5NzE3MDI4ZThhZGM4ZTk4NGQ1NzhkZjFlYTNhZGJkY2Q0OTM2YQ==
4
+ NWRjNTUxZWEzMTQzYjA3YTQ1ZjY4YmU2ZDdlZGQ3OGY1MzQ0NzJhYw==
5
5
  data.tar.gz: !binary |-
6
- NmRiZDc2ZGNlYjEzMDQ1M2QxMTk1ZGY1Nzg0MDYzOTgxOWMxNDUyNA==
6
+ MDAyNzdlMjM1N2U0Mzk2MmFhNzJmZTM1OGRhNGVmMjBjMjEzZTkwYQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ZGE4ZTcyOTA1MzQ5MTk5MTYyOWE5ZDRlMGEzNTczYjZlNzI5Y2NkMThmNzli
10
- NzhmNjdjZmRjM2I4NmY2ZTAwNjAyOWY2NzJjZTE4ZGE1N2I0NjA3ZjNmZjAz
11
- M2JiN2U1ODAzNTAyNjVkMDhiNTkxYzY1NjMyY2RiOTNmOWZhYWI=
9
+ MDFlYjZhYjMxOTM0NjIxMTYzZDQ3ZjA5M2ZkMTQzMTYyMmFmY2QzOWFlODU4
10
+ MTc1YTRmYjBhNjA0NDA0N2I5MjA0Y2U0ZWYxMzZmMjIyZWJkYWIzYjkxYWVj
11
+ ZmZjOTdkMGMxNTFiZWE5NGI4YTA2MDg3NjM5YTY4YmNiMTJjNzM=
12
12
  data.tar.gz: !binary |-
13
- NzFjOGJjNTZlOWIyYjJhZDA5YmQ5MWQyM2JiYzdhMTk2NjVjMmY0MTFhZmE0
14
- YWIwODQ4NmQ3MDJlYmRlZTVhNzUzNTE3OWY3MWEzOWZkYmY1MTYxNDQ0YWU0
15
- YjVmODhkYzI4YWQ5MDE5MzUyNzc3MWNlYTYzNzZhNjM0NmY3ZjI=
13
+ N2FlNDdlYjQzZDUyZjVlZTZiNjA1MDA1ZGI4MjI5M2Q1ZjFkMzY5ZmI5OTVi
14
+ YjA3ZmU0NzNlN2E0YjI0ZTYyMjQ2NGJlOTliMDE0OTM2Mjg2NmExODljZDBk
15
+ ZmRiYTRiMGE4N2RkZTc3MmI1MjlhNGY1NjVjMDU1OTJlYWNmOWY=
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ === 0.5.6
2
+ * sending "title" in options is not supported now. use dsl with Proc for that.
3
+ * ability to open root screen with animation.
4
+ * refactored screens navigation.
5
+
1
6
  === 0.5.5
2
7
  * improve association fetch speed and login.
3
8
  * "delete" method is not supported for model collection now, use delete_all.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- motion-prime (0.5.5)
4
+ motion-prime (0.5.6)
5
5
  bubble-wrap
6
6
  cocoapods
7
7
  methadone
@@ -42,9 +42,9 @@ module MotionPrime
42
42
  def open_screen(screen, options = {})
43
43
  screen = prepare_screen_for_open(screen, options)
44
44
  if options[:root] || !self.window
45
- open_root_screen(screen)
45
+ open_root_screen(screen, options)
46
46
  else
47
- open_content_screen(screen)
47
+ open_content_screen(screen, options)
48
48
  end
49
49
  end
50
50
 
@@ -62,7 +62,6 @@ module MotionPrime
62
62
 
63
63
  private
64
64
  def prepare_screen_for_open(screen, options = {})
65
- screen = create_tab_bar(screen) if screen.is_a?(Array)
66
65
  Screen.create_with_options(screen, true, options)
67
66
  end
68
67
 
@@ -73,7 +72,15 @@ module MotionPrime
73
72
  screen = screen.main_controller if screen.respond_to?(:main_controller)
74
73
 
75
74
  self.window ||= UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
76
- self.window.rootViewController = screen
75
+ if options[:animated]
76
+ UIView.transitionWithView self.window,
77
+ duration: 0.5,
78
+ options: UIViewAnimationOptionTransitionFlipFromLeft,
79
+ animations: proc { self.window.rootViewController = screen },
80
+ completion: nil
81
+ else
82
+ self.window.rootViewController = screen
83
+ end
77
84
  self.window.makeKeyAndVisible
78
85
  screen
79
86
  end
@@ -81,9 +88,5 @@ module MotionPrime
81
88
  def open_content_screen(screen, options = {})
82
89
  open_root_screen(screen)
83
90
  end
84
-
85
- def create_tab_bar(screens)
86
- MotionPrime::TabBarController.new(screens)
87
- end
88
91
  end
89
92
  end
@@ -6,6 +6,9 @@ module MotionPrime
6
6
  @_bags ||= {}
7
7
  end
8
8
 
9
+ # Saves model and all associations to store.
10
+ #
11
+ # @return [Prime::Model] model
9
12
  def save
10
13
  _bags.values.each do |bag|
11
14
  bag.store = self.store
@@ -6,6 +6,9 @@ module MotionPrime
6
6
  base.class_attribute :default_sort_options
7
7
  end
8
8
 
9
+ # Saves model to default store.
10
+ #
11
+ # @return [Prime::Model] model
9
12
  def save
10
13
  raise StoreError, 'No store provided' unless self.store
11
14
  error_ptr = Pointer.new(:id)
@@ -14,6 +17,9 @@ module MotionPrime
14
17
  self
15
18
  end
16
19
 
20
+ # Removed model from default store.
21
+ #
22
+ # @return [Prime::Model] model
17
23
  def delete
18
24
  raise StoreError, 'No store provided' unless self.store
19
25
 
@@ -27,6 +33,13 @@ module MotionPrime
27
33
  super || self.class.store
28
34
  end
29
35
 
36
+ # Assigns attributes to model
37
+ #
38
+ # @params attributes [Hash] attributes to be assigned
39
+ # @params options [Hash] options
40
+ # @option options [Boolean] :skip_nil_values Do not assign nil values
41
+ # @option options [Boolean] :validate_attribute_presence Raise error if model do not have attribute
42
+ # @return [Hash] attributes
30
43
  def assign_attributes(new_attributes, options = {})
31
44
  attributes = new_attributes.symbolize_keys
32
45
  attributes.each do |k, v|
@@ -40,30 +53,54 @@ module MotionPrime
40
53
  end
41
54
  end
42
55
 
56
+ # Assigns attribute to model
57
+ #
58
+ # @params name [String, Symbol] attribute name
59
+ # @params value [Object] attribute value
60
+ # @return [Object] assigned object if has been assigned
43
61
  def assign_attribute(name, value)
44
62
  self.send("#{name}=", value) if has_attribute?(name)
45
63
  end
46
64
 
65
+ # Check if model has attribute
66
+ #
67
+ # @params name [String, Symbol] attribute name
68
+ # @return [Boolean] result
47
69
  def has_attribute?(name)
48
70
  respond_to?("#{name}=")
49
71
  end
50
72
 
73
+ # Hash of all attributes in model
74
+ #
75
+ # @return [Hash] key-value hash
51
76
  def attributes_hash
52
77
  self.info.to_hash.symbolize_keys
53
78
  end
54
79
 
80
+ # Checks if model has been saved in server (have an ID)
81
+ #
82
+ # @return [Boolean] true if model is not saved
55
83
  def new_record?
56
84
  id.blank?
57
85
  end
58
86
 
87
+ # Checks if model has been saved in server (have an ID)
88
+ #
89
+ # @return [Boolean] true if model is saved
59
90
  def persisted?
60
91
  !new_record?
61
92
  end
62
93
 
94
+ # Model class name
95
+ #
96
+ # @return [String] model class name
63
97
  def model_name
64
98
  self.class_name_without_kvo.underscore
65
99
  end
66
100
 
101
+ # Returns json-formatted representation of model
102
+ #
103
+ # @return [String] model representation
67
104
  def inspect
68
105
  "#<#{self.class}:0x#{self.object_id.to_s(16)}> " + MotionPrime::JSON.generate(info)
69
106
  end
@@ -71,9 +108,12 @@ module MotionPrime
71
108
  module ClassMethods
72
109
  # Initialize a new object
73
110
  #
74
- # Examples:
111
+ # @example:
75
112
  # User.new(name: "Bob", age: 10)
76
113
  #
114
+ # @params attributes [Hash] attributes beeing assigned to model
115
+ # @params options [Hash] options
116
+ # @option options [Boolean] :validate_attribute_presence Raise error if model do not have attribute
77
117
  # @return MotionPrime::Model unsaved model
78
118
  def new(data = {}, options = {})
79
119
  data.keys.each do |key|
@@ -90,20 +130,22 @@ module MotionPrime
90
130
  object
91
131
  end
92
132
 
93
- # Initialize a new object and save it
133
+ # Initialize a new object and save it to store
94
134
  #
95
- # Examples:
135
+ # @example:
96
136
  # User.create(name: "Bob", age: 10)
97
137
  #
98
- # @return MotionPrime::Model saved model
138
+ # @params attributes [Hash] attributes beeing assigned to model
139
+ # @return model [MotionPrime::Model] saved model
99
140
  def create(data = {})
100
141
  object = self.new(data)
101
142
  object.save
143
+ object
102
144
  end
103
145
 
104
146
  # Define model attribute
105
147
  #
106
- # Examples:
148
+ # @example:
107
149
  # class User < MotionPrime::Model
108
150
  # attribute :name
109
151
  # attribute :age
@@ -134,46 +176,45 @@ module MotionPrime
134
176
  end
135
177
  end
136
178
 
137
- # Set or return all model attribute names
179
+ # Set and/or return all model attribute names
138
180
  #
139
- # @return Array array of attribute names
181
+ # @return array [Array<Symbol>] array of attribute names
140
182
  def attributes(*attrs)
141
183
  if attrs.size > 0
142
184
  attrs.each{|attr| attribute attr}
143
- else
144
- @attributes ||= []
145
185
  end
186
+ @attributes ||= []
146
187
  end
147
188
 
148
189
  # Return store associated with model class, or shared store by default
149
190
  #
150
- # @return MotionPrime::Store store
191
+ # @return store [MotionPrime::Store] store
151
192
  def store
152
193
  @store ||= MotionPrime::Store.shared_store
153
194
  end
154
195
 
155
196
  # Define store associated with model class
156
197
  #
157
- # @param MotionPrime::Store store
158
- # @return MotionPrime::Store store
198
+ # @param store [MotionPrime::Store] store
199
+ # @return store [MotionPrime::Store] store
159
200
  def store=(store)
160
201
  @store = store
161
202
  end
162
203
 
163
204
  # Count of models
164
205
  #
165
- # @return Fixnum count
206
+ # @return count [Fixnum] count of objects with this Prime::Model
166
207
  def count
167
208
  self.store.count(self)
168
209
  end
169
210
 
170
211
  # Delete objects from store by given options
171
212
  #
172
- # Examples:
213
+ # @example:
173
214
  # User.delete(:name => "Bob") #
174
215
  #
175
- # @param [Array, MotionPrime::Model] objects to delete
176
- # @return [Array] removed item keys
216
+ # @param options [Hash, Array, MotionPrime::Model] objects to delete. See find_keys for list of options.
217
+ # @return keys [Array] removed item keys
177
218
  def delete(*args)
178
219
  if args.blank?
179
220
  raise "Using delete with no args is not allowed. Please use delete_all to delete all records"
@@ -182,6 +223,12 @@ module MotionPrime
182
223
  self.store.delete_keys(keys)
183
224
  end
184
225
 
226
+ # Delete all objects with this Prime::Model
227
+ #
228
+ # @example:
229
+ # User.delete_all
230
+ #
231
+ # @return keys [Array] removed item keys
185
232
  def delete_all
186
233
  self.store.delete_keys(find_keys)
187
234
  end
@@ -7,7 +7,7 @@ module MotionPrime
7
7
 
8
8
  # Find all models
9
9
  #
10
- # @return [Array] array of models
10
+ # @return items [Array] array of models
11
11
  def all(*args)
12
12
  return [] unless self.store
13
13
 
@@ -26,23 +26,27 @@ module MotionPrime
26
26
  end
27
27
 
28
28
  # Find last model model by default order
29
+ #
30
+ # @return item [Prime::Model] result
29
31
  def last
30
32
  all.last
31
33
  end
32
34
 
33
35
  # Find first model model by default order
36
+ #
37
+ # @return item [Prime::Model] result
34
38
  def first
35
39
  all.first
36
40
  end
37
41
 
38
42
  # Find model by criteria
39
43
  #
40
- # Examples:
44
+ # @example:
41
45
  # User.find(:name, NSFEqualTo, "Bob") # => [<User#1>]
42
46
  # User.find(:name => "Bob") # => [<User#1>]
43
47
  # User.find(:name => {NSFEqualTo => "Bob"}) # => [<User#1>]
44
48
  #
45
- # @return [Array] array of models
49
+ # @return items [Array] array of models
46
50
  def find(*arg)
47
51
  if arg[0].is_a?(Hash)
48
52
  # hash style
@@ -88,12 +92,12 @@ module MotionPrime
88
92
 
89
93
  # Find model keys by criteria
90
94
  #
91
- # Examples:
95
+ # @example:
92
96
  # User.find_keys(:name, NSFEqualTo, "Bob") # => ["1"]
93
97
  # User.find_keys(:name => "Bob") # => ["1"]
94
98
  # User.find_keys(:name => {NSFEqualTo => "Bob"}) # => ["1"]
95
99
  #
96
- # @return [Array] array of models
100
+ # @return keys [Array] array of models
97
101
  def find_keys(*arg)
98
102
  if arg[0].is_a?(Hash)
99
103
  # hash style
@@ -140,7 +144,7 @@ module MotionPrime
140
144
 
141
145
  # Find a model by key
142
146
  #
143
- # Examples:
147
+ # @example:
144
148
  # User.find_by_key(my_key)
145
149
  #
146
150
  # @return [Object, Nil] an object or nil (if not found)
@@ -29,7 +29,7 @@ module MotionPrime
29
29
 
30
30
  # Add an object or array of objects to bag
31
31
  #
32
- # @return self
32
+ # @return self [Prime::Model]
33
33
  def add(object_or_array)
34
34
  error_ptr = Pointer.new(:id)
35
35
  prepared = prepare_for_store(object_or_array)
@@ -59,8 +59,8 @@ module MotionPrime
59
59
 
60
60
  # Remove object from bag with key
61
61
  #
62
- # @param [String] key - a key or array of keys
63
- # @return self
62
+ # @param key [String] a key or array of keys
63
+ # @return self [Prime::Model]
64
64
  def delete_key(key)
65
65
  if key.is_a?(Array)
66
66
  self.removeObjectsWithKeysInArray(key)
@@ -72,7 +72,7 @@ module MotionPrime
72
72
 
73
73
  # Remove an object or array of objects from bag
74
74
  #
75
- # @param [String] object_or_array
75
+ # @param items [Array<Prime::Model>, Prime::Model] model or array of models to remove
76
76
  # @return self
77
77
  def delete(object_or_array)
78
78
  error_ptr = Pointer.new(:id)
@@ -8,19 +8,30 @@ module MotionPrime
8
8
  base.class_attribute :_associations
9
9
  end
10
10
 
11
+ # Get normalized sync url of this Prime::Model
12
+ #
13
+ # @param method [Symbol] http method
14
+ # @return url [String] url to use in model sync
11
15
  def sync_url(method = :get, options = {})
12
16
  url = self.class.sync_url
13
17
  url = url.call(method, self, options) if url.is_a?(Proc)
14
18
  normalize_sync_url(url)
15
19
  end
16
20
 
21
+ # Get normalized sync url of associated Prime::Model
22
+ #
23
+ # @param key [Symbol] association name
24
+ # @return url [String] url to use in model association sync
17
25
  def association_sync_url(key, options)
18
26
  url = options[:sync_url]
19
27
  url = url.call(self) if url.is_a?(Proc)
20
28
  normalize_sync_url(url)
21
29
  end
22
30
 
23
- # destroy on server and delete on local
31
+ # Destroy model on server and delete on local
32
+ #
33
+ # @param block [Proc] block to be executed after destroy
34
+ # @return self[Prime::Model] deleted model.
24
35
  def destroy(&block)
25
36
  use_callback = block_given?
26
37
  api_client.delete(sync_url(:delete)) do
@@ -29,12 +40,19 @@ module MotionPrime
29
40
  delete
30
41
  end
31
42
 
32
- # fetch from server and save on local
43
+ # Fetch model from server and save on local
44
+ #
33
45
  def fetch!(options = {}, &block)
34
46
  fetch(options.merge(save: true), &block)
35
47
  end
36
48
 
37
- # fetch from server
49
+ # Fetch model from server
50
+ #
51
+ # @param options [Hash] fetch options
52
+ # @option options [Symbol] :method Http method to calculate url, `:get` by default
53
+ # @option options [Boolean] :associations Also fetch associations
54
+ # @option options [Boolean] :save Save model after fetch
55
+ # @param block [Proc] block to be executed after fetch
38
56
  def fetch(options = {}, &block)
39
57
  use_callback = block_given?
40
58
  method = options[:method] || :get
@@ -54,12 +72,16 @@ module MotionPrime
54
72
  end if will_fetch_associations
55
73
  end
56
74
 
57
- # update on server and save response on local
75
+ # Update on server and save response on local
76
+ #
58
77
  def update!(options = {}, &block)
59
78
  update(options.merge(save_response: true), &block)
60
79
  end
61
80
 
62
- # update on server
81
+ # Update on server
82
+ # @param options [Hash] update options
83
+ # @option options [Symbol] :method Http method to calculate url, by default `:post` for new record and `:put` for existing
84
+ # @param block [Proc] block to be executed after update
63
85
  def update(options = {}, &block)
64
86
  use_callback = block_given?
65
87
 
@@ -72,7 +94,10 @@ module MotionPrime
72
94
  end if will_update_model
73
95
  end
74
96
 
75
- # fetch from server using url
97
+ # Fetch model from server using url
98
+ #
99
+ # @param url [String] url to fetch
100
+ # @param block [Proc] block to be executed after fetch
76
101
  def fetch_with_url(url, &block)
77
102
  use_callback = block_given?
78
103
  api_client.get(url) do |data, status_code|
@@ -81,7 +106,10 @@ module MotionPrime
81
106
  end
82
107
  end
83
108
 
84
- # update on server using url
109
+ # Update on server using url
110
+ #
111
+ # @param url [String] url to update
112
+ # @param block [Proc] block to be executed after update
85
113
  def update_with_url(url, options = {}, &block)
86
114
  use_callback = block_given?
87
115
  filtered_attributes = filtered_updatable_attributes(options)
@@ -109,14 +137,31 @@ module MotionPrime
109
137
  fetch_with_attributes(data)
110
138
  end
111
139
 
112
- # set attributes, using fetch
113
- def fetch_with_attributes(attrs, sync_options = {})
140
+ # Assign model attributes, using fetch. Differenct between assign_attributes and fetch_with_attributes is
141
+ # ths you can create method named fetch_:attribute and it will be used to assign attribute only on fetch.
142
+ #
143
+ # @example
144
+ # class User < Prime::Model
145
+ # attribute :created_at
146
+ # def fetch_created_at(value)
147
+ # self.created_at = Date.parse(value)
148
+ # end
149
+ # end
150
+ # user = User.new
151
+ # user.fetch_with_attributes(created_at: '2007-03-01T13:00:00Z')
152
+ # user.created_at # => 2007-03-01 13:00:00 UTC
153
+ #
154
+ # @params attributes [Hash] attributes to be assigned
155
+ # @params options [Hash] options
156
+ # @option options [Boolean] :save_associations Save included to hash associations
157
+ # @return model [Prime::Model] the model
158
+ def fetch_with_attributes(attrs, options = {})
114
159
  track_changed_attributes do
115
160
  attrs.each do |key, value|
116
161
  if respond_to?(:"fetch_#{key}")
117
162
  self.send(:"fetch_#{key}", value)
118
163
  elsif has_association?(key) && (value.is_a?(Hash) || value.is_a?(Array))
119
- should_save = sync_options[:save_associations]
164
+ should_save = options[:save_associations]
120
165
  fetch_association_with_attributes(key, value, save: should_save)
121
166
  elsif respond_to?(:"#{key}=")
122
167
  self.send(:"#{key}=", value)
@@ -189,7 +234,7 @@ module MotionPrime
189
234
  def fetch_has_many_with_attributes(key, data, sync_options = {})
190
235
  old_collection = self.send(key)
191
236
  model_class = key.classify.constantize
192
- self.class.store.save_interval = data.count
237
+ self.store.save_interval = data.count
193
238
  # Update/Create existing records
194
239
  data.each do |attributes|
195
240
  model = old_collection.detect{ |model| model.id == attributes[:id]}
@@ -207,7 +252,7 @@ module MotionPrime
207
252
  end
208
253
  end
209
254
  save if sync_options[:save]
210
- self.class.store.save_interval = 1
255
+ self.store.save_interval = 1
211
256
  end
212
257
 
213
258
  def fetch_has_one(key, options = {}, &block)
@@ -271,6 +316,14 @@ module MotionPrime
271
316
  end
272
317
 
273
318
  module ClassMethods
319
+ def fetch_all_with_attributes(data)
320
+ data.map do |attrs|
321
+ item = self.new
322
+ item.fetch_with_attributes(attrs)
323
+ item
324
+ end
325
+ end
326
+
274
327
  def new(data = {}, options = {})
275
328
  model = super
276
329
  if fetch_attributes = options[:fetch_attributes]
@@ -71,12 +71,17 @@ module MotionPrime
71
71
  set_callback :render, :after, method_name
72
72
  end
73
73
  def create_with_options(screen, navigation = true, options = {})
74
+ screen = create_tab_bar(screen, options) if screen.is_a?(Array)
74
75
  if screen.is_a?(Symbol)
75
76
  options[:navigation] = navigation unless options.has_key?(:navigation)
76
77
  screen = class_factory("#{screen}_screen").new(options)
77
78
  end
78
79
  screen
79
80
  end
81
+
82
+ def create_tab_bar(screens, options = {})
83
+ MotionPrime::TabBarController.new(screens, options)
84
+ end
80
85
  end
81
86
  end
82
87
  end
@@ -14,7 +14,7 @@ module MotionPrime
14
14
  screen.send(:on_screen_load) if screen.respond_to?(:on_screen_load)
15
15
  args[:animated] = args.has_key?(:animated) ? args[:animated] : true
16
16
  if args[:modal] || !has_navigation?
17
- open_screen_modal(screen, args)
17
+ open_screen_modal(screen, args.merge(modal: true))
18
18
  else
19
19
  open_screen_navigational(screen, args)
20
20
  end
@@ -36,12 +36,18 @@ module MotionPrime
36
36
  close_screen
37
37
  end
38
38
 
39
- def send_on_return(args = {})
39
+ def send_on_return
40
40
  if parent_screen && parent_screen.respond_to?(:on_return)
41
41
  parent_screen.send(:on_return)
42
42
  end
43
43
  end
44
44
 
45
+ def send_on_leave
46
+ if respond_to?(:on_leave)
47
+ on_leave
48
+ end
49
+ end
50
+
45
51
  def wrap_in_navigation?
46
52
  options[:navigation] || options[:navigation].nil?
47
53
  end
@@ -66,30 +72,26 @@ module MotionPrime
66
72
 
67
73
  private
68
74
  def setup_screen_for_open(screen, args = {})
69
- # Instantiate screen if given a class
70
- screen = Screen.create_with_options(screen, true, args)
71
-
72
- # Set parent, title & modal properties
75
+ screen = self.class.create_with_options(screen, true, args)
73
76
  screen.parent_screen = self if screen.respond_to?("parent_screen=")
74
- screen.title = args[:title] if args[:title] && screen.respond_to?("title=")
75
- screen.modal = args[:modal] if args[:modal] && screen.respond_to?("modal=")
76
-
77
- # Return modified screen instance
78
77
  screen
79
78
  end
80
79
 
81
80
  def open_screen_modal(screen, args)
81
+ screen.modal = true if screen.respond_to?("modal=")
82
82
  self.presentModalViewController(screen.main_controller, animated: args[:animated])
83
+ send_on_leave
83
84
  end
84
85
 
85
86
  def open_screen_navigational(screen, args = {})
86
87
  navigation_controller.pushViewController(screen, animated: args[:animated])
88
+ send_on_leave
87
89
  end
88
90
 
89
91
  # @return screen [Prime::Screen] screen appearing after close
90
92
  def close_screen_modal(args = {})
91
93
  parent_screen.dismissViewControllerAnimated(args[:animated], completion: lambda {
92
- send_on_return(args)
94
+ send_on_return
93
95
  })
94
96
  parent_screen
95
97
  end
@@ -111,7 +113,7 @@ module MotionPrime
111
113
  result = self.navigation_controller.childViewControllers.last
112
114
  end
113
115
  end
114
- send_on_return(args)
116
+ send_on_return
115
117
  result
116
118
  end
117
119
 
@@ -46,23 +46,60 @@ module MotionPrime
46
46
  options[:container_bounds] or raise "You must pass `container bounds` option to prerender base section"
47
47
  end
48
48
 
49
+ # Get computed container options
50
+ #
51
+ # @return options [Hash] computed options
49
52
  def container_options
50
53
  compute_container_options! unless @container_options
51
54
  @container_options
52
55
  end
53
56
 
57
+ # Get computed container height
58
+ #
59
+ # @example
60
+ # class MySection < Prime::Section
61
+ # container height: proc { element(:title).content_outer_height }
62
+ # element :title, text: 'Hello world'
63
+ # end
64
+ # section = MySection.new
65
+ # section.container_height # => 46
66
+ #
67
+ # @return height [Float, Integer] computed height
54
68
  def container_height
55
69
  container_options[:height] || DEFAULT_CONTENT_HEIGHT
56
70
  end
57
71
 
72
+ # Get section default name, based on class name
73
+ #
74
+ # @example
75
+ # class ProfileSection < Prime::Section
76
+ # end
77
+ #
78
+ # section = ProfileSection.new
79
+ # section.default_name # => 'profile'
80
+ # section.name # => 'profile'
81
+ #
82
+ # another_section = ProfileSection.new(name: 'another')
83
+ # another_section.default_name # => 'profile'
84
+ # another_section.name # => 'another'
85
+ #
86
+ # @return name [String] section default name
58
87
  def default_name
59
88
  self.class_name_without_kvo.demodulize.underscore.gsub(/\_section$/, '')
60
89
  end
61
90
 
91
+ # Get section elements options, where the key is element name.
92
+ #
93
+ # @return options [Hash] elements options
62
94
  def elements_options
63
95
  self.class.elements_options || {}
64
96
  end
65
97
 
98
+ # Create elements if they are not created yet.
99
+ # This will not cause rendering elements,
100
+ # they will be rendered immediately after that or rendered async later, based on type of section.
101
+ #
102
+ # @return result [Boolean] true if has been loaded by this thread.
66
103
  def load_section
67
104
  return if @section_loaded
68
105
  if @section_loading
@@ -75,11 +112,16 @@ module MotionPrime
75
112
  return @section_loaded = true
76
113
  end
77
114
 
115
+ # Force load section
116
+ #
117
+ # @return result [Boolean] true if has been loaded by this thread.
78
118
  def load_section!
79
119
  @section_loaded = false
80
120
  load_section
81
121
  end
82
122
 
123
+ # Force reload section, will also re-render elements.
124
+ # For table view cells will also reload it's table data.
83
125
  def reload_section
84
126
  self.elements_to_render.values.map(&:view).flatten.each do |view|
85
127
  view.removeFromSuperview if view
@@ -243,6 +243,9 @@ module MotionPrime
243
243
  display_pending_cells
244
244
  end
245
245
 
246
+ def scroll_view_did_scroll(scroll)
247
+ end
248
+
246
249
  def scroll_view_did_end_dragging(scroll, willDecelerate: will_decelerate)
247
250
  display_pending_cells unless @decelerating = will_decelerate
248
251
  end
@@ -55,6 +55,10 @@ module MotionPrime
55
55
  table_section.height_for_header_in_section(table, section)
56
56
  end
57
57
 
58
+ def scrollViewDidScroll(scroll)
59
+ table_section.scroll_view_did_scroll(scroll)
60
+ end
61
+
58
62
  def scrollViewWillBeginDragging(scroll)
59
63
  table_section.scroll_view_will_begin_dragging(scroll)
60
64
  end
@@ -1,13 +1,13 @@
1
1
  module MotionPrime
2
2
  class TabBarController < UITabBarController
3
- def self.new(screens)
3
+ def self.new(screens, global_options = {})
4
4
  controller = alloc.init
5
5
 
6
6
  view_controllers = []
7
7
 
8
8
  screens.each_with_index do |options, index|
9
9
  if options.is_a?(Hash)
10
- screen = init_screen_with_options(options, tag: index)
10
+ screen = init_screen_with_options(global_options.merge(options), tag: index)
11
11
  else
12
12
  screen = options
13
13
  screen.tabBarItem.tag = index
@@ -33,10 +33,9 @@ module MotionPrime
33
33
 
34
34
  protected
35
35
  def self.init_screen_with_options(options, tag: tag)
36
- screen, image, title = options[:screen], options[:image], options[:title]
37
- screen = Screen.create_with_options(screen).try(:weak_ref)
36
+ screen, image, title = options.delete(:screen), options.delete(:title)
37
+ screen = Screen.create_with_options(screen, true, options).try(:weak_ref)
38
38
  title ||= screen.title
39
-
40
39
  image = extract_image_from_options(options, with_key: :image)
41
40
  screen.tabBarItem = UITabBarItem.alloc.initWithTitle title, image: image, tag: tag
42
41
 
@@ -46,7 +45,7 @@ module MotionPrime
46
45
  end
47
46
 
48
47
  def self.extract_image_from_options(options, with_key: key)
49
- image = options[key]
48
+ image = options.delete(key)
50
49
  return unless image
51
50
  image = image.uiimage
52
51
  if options[:translucent] === false
@@ -1,3 +1,3 @@
1
1
  module MotionPrime
2
- VERSION = "0.5.5"
2
+ VERSION = "0.5.6"
3
3
  end
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: 0.5.5
4
+ version: 0.5.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-01-25 00:00:00.000000000 Z
12
+ date: 2014-01-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake