motion-prime 0.5.5 → 0.5.6

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