formotion 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +1 -0
  3. data/Formotion.gemspec +1 -1
  4. data/LIST_OF_ROW_TYPES.md +115 -3
  5. data/README.md +1 -0
  6. data/examples/KitchenSink/app/app_delegate.rb +16 -2
  7. data/lib/formotion.rb +9 -1
  8. data/lib/formotion/form/form.rb +7 -0
  9. data/lib/formotion/form/form_delegate.rb +2 -2
  10. data/lib/formotion/patch/ui_image.rb +45 -0
  11. data/lib/formotion/patch/ui_text_view_placeholder.rb +4 -1
  12. data/lib/formotion/row/row.rb +13 -1
  13. data/lib/formotion/row_type/base.rb +13 -4
  14. data/lib/formotion/row_type/button.rb +1 -0
  15. data/lib/formotion/row_type/check_row.rb +2 -1
  16. data/lib/formotion/row_type/date_row.rb +3 -0
  17. data/lib/formotion/row_type/image_row.rb +6 -1
  18. data/lib/formotion/row_type/map_row.rb +79 -0
  19. data/lib/formotion/row_type/multi_choice_row.rb +25 -0
  20. data/lib/formotion/row_type/object_row.rb +30 -0
  21. data/lib/formotion/row_type/options_row.rb +2 -2
  22. data/lib/formotion/row_type/paged_image_row.rb +257 -0
  23. data/lib/formotion/row_type/picker_row.rb +2 -0
  24. data/lib/formotion/row_type/slider_row.rb +2 -2
  25. data/lib/formotion/row_type/static_row.rb +1 -1
  26. data/lib/formotion/row_type/string_row.rb +3 -7
  27. data/lib/formotion/row_type/subform_row.rb +3 -1
  28. data/lib/formotion/row_type/switch_row.rb +2 -2
  29. data/lib/formotion/row_type/tags_row.rb +172 -0
  30. data/lib/formotion/row_type/template_row.rb +3 -3
  31. data/lib/formotion/row_type/text_row.rb +5 -1
  32. data/lib/formotion/row_type/web_view_row.rb +44 -0
  33. data/lib/formotion/version.rb +1 -1
  34. data/resources/tags_row-selected.png +0 -0
  35. data/resources/tags_row-selected@2x.png +0 -0
  36. data/resources/tags_row.png +0 -0
  37. data/resources/tags_row@2x.png +0 -0
  38. data/spec/form_spec.rb +26 -0
  39. data/spec/functional/date_row_spec.rb +6 -0
  40. data/spec/functional/picker_row_spec.rb +5 -0
  41. data/spec/row_type/back_spec.rb +1 -1
  42. data/spec/row_type/base_spec.rb +3 -3
  43. data/spec/row_type/string_spec.rb +14 -3
  44. data/spec/row_type/subform_spec.rb +1 -1
  45. data/spec/row_type/submit_spec.rb +1 -1
  46. data/spec/row_type/text_spec.rb +7 -0
  47. metadata +17 -6
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZmNhMGY5ZTMyZWUwYWIzMzhlMTVhYmQ0ODk2NGQ3YTBlYzRmNGI5NQ==
4
+ ZmYyOTdkNGExNDMzMzU5Mjg5NjMxZGIxZWE4NzcxY2NjNjM5ZDBjMA==
5
5
  data.tar.gz: !binary |-
6
- ODI0MWFkNzkwOTAxNGFmZjM1Yjg5ZjVkYTMwYzkzMTdhMWZhMzZiOA==
6
+ YWJmNzEwODljYmUzN2ZhN2I0MTE4YmFkYWI1ODhhMDkzOTQxYzNjZg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MDkzMzM3YWE2MTNjZjMwOGI5MWUzN2ZlZWNmYWNkMGMwMTczNDY3YzA4Njli
10
- NmEzMzQzYjZkYjNkYzI5NTQxNDI2MjM3OWUwZGM3MTkxZTBjNDJlYmJiNjk4
11
- NjI2NjY2YjJlOTMyNmI5YTZmYTgyYmQ0NzNiMzBhZTc4ODEzYTc=
9
+ YzYyMTNkZjI3MWE3YTFiMGY5MzBiMTc4MWEyOGVmNGE5NGE3Y2I5MDgxZjM1
10
+ MDMxZDliM2Y0OWY2ZjhkODFjMjczYTIyMDI2MDNkNWU0YzIzYzRiOTYzNzRk
11
+ Yjg3ZGRmN2UwZWY3OTdmODY5YjBiZTEzNWU1NDg3ZjE3NjFiYzE=
12
12
  data.tar.gz: !binary |-
13
- MDM3ODUyZWI5MmE5ZTQxOGQyN2YxY2ZhZDI0MzUyNjI5ZDU4M2QyMjI1ODk5
14
- ZDA5ZTM5Y2ZlY2QyMmI5YWVjMjhjYzE3MjliYmVhMWIzYTY1NTBkNmQ0ZWQ4
15
- MWIyYTVjMjJmNzM0MWRlMzFmM2VlMjI4MTMwZTlkMDJjYmQ0ZDY=
13
+ NzQzNzdmYmM5YjJkY2YxZDU5YjliM2RmYzUyZDIyMzIyM2NjYjVkYmViZTA2
14
+ MWZmYTgxMGEyMmY4NmM1NmJjZDA1NWE3YTE4ZDRkNWEwNzA5NzYxZTgzMzU2
15
+ ZTFkZWZkODQ0MWU4ZjViNzIyY2FkMTUyN2FjMjUwYzhlNjk0ZTk=
data/.travis.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  language: objective-c
2
2
  before_install:
3
+ - rvm install ruby-1.9.3-p429
3
4
  - rvm use 1.9.3
4
5
  install: bundle install
5
6
  script: bundle exec rake spec:units
data/Formotion.gemspec CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
14
14
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
15
15
  s.require_paths = ["lib"]
16
16
 
17
- s.add_dependency "bubble-wrap", ">= 1.1.4"
17
+ s.add_dependency "bubble-wrap", "~> 1.3.0"
18
18
  s.add_dependency "motion-require", "~> 0.0.3"
19
19
  s.add_development_dependency 'rake'
20
20
  end
data/LIST_OF_ROW_TYPES.md CHANGED
@@ -5,7 +5,8 @@
5
5
  [Phone](#phone)<br/>
6
6
  [Number](#number)<br/>
7
7
  [Currency](#currency)<br/>
8
- [Date](#date)
8
+ [Date](#date)<br/>
9
+ [Object](#object)<br/>
9
10
 
10
11
  **Other**<br/>
11
12
  [Static](#static)<br/>
@@ -16,7 +17,11 @@
16
17
  [Option](#option)<br/>
17
18
  [Picker](#picker)<br/>
18
19
  [Subform](#subform)<br/>
19
- [Template](#template)
20
+ [Template](#template)<br/>
21
+ [MapView](#mapview)<br/>
22
+ [WebView](#webview)<br/>
23
+ [PagedImage](#pagedimage)<br/>
24
+ [Tags](#tags)<br/>
20
25
 
21
26
  **Buttons**<br/>
22
27
  [Button](#button)<br/>
@@ -89,6 +94,34 @@ The `TextRow` is a multiline text input row and opens the default keyboard when
89
94
  To define the height of the row set the property `row_height`.
90
95
 
91
96
 
97
+ #### <a name="text_fonts"></a> Text row with Big Font
98
+ ![Text Row](https://github.com/clayallsopp/formotion/wiki/row-types/text_big_font.png)
99
+
100
+ ```ruby
101
+ {
102
+ title: "Big Text",
103
+ key: :text,
104
+ type: :text,
105
+ font: {name: 'Helvetica', size: 24},
106
+ placeholder: "Enter your big text here",
107
+ row_height: 100
108
+ }
109
+ ```
110
+
111
+ #### <a name="text_fonts"></a> Text row with Small Font
112
+ ![Text Row](https://github.com/clayallsopp/formotion/wiki/row-types/text_small_font.png)
113
+
114
+ ```ruby
115
+ {
116
+ title: "Small Text",
117
+ key: :text,
118
+ type: :text,
119
+ font: {name: 'Chalkduster', size: 8},
120
+ placeholder: "Enter your small text here",
121
+ row_height: 100
122
+ }
123
+ ```
124
+
92
125
  ### <a name="email"></a> Email row
93
126
  ![Email row](https://github.com/clayallsopp/formotion/wiki/row-types/email.png)
94
127
  ```ruby
@@ -186,6 +219,21 @@ Note: If you use `:date_time` or `:time` for the type, `:minute_interval` will b
186
219
  the default is the Apple default of 1.
187
220
 
188
221
 
222
+ ### <a name="object"></a> Object row
223
+
224
+ ```ruby
225
+ {
226
+ title: "My Data",
227
+ type: :object,
228
+ value: object # an object
229
+ }
230
+ ```
231
+
232
+ Same as StringRow with the difference that it would not change the row.value to string.
233
+ The object needs a to_s method.
234
+
235
+
236
+
189
237
  ## Other
190
238
 
191
239
  ### <a name="static"></a> Static row
@@ -378,6 +426,69 @@ Use a `:display_key` to show the value of the subform in the row:
378
426
  }
379
427
  ```
380
428
 
429
+
430
+ ### <a name="mapview"></a> MapView row
431
+ ![MapView row](https://github.com/rheoli/formotion/wiki/row-types/Mapview.png)
432
+ ```ruby
433
+ {
434
+ title: "Map",
435
+ type: :map_view,
436
+ value: coordinates, # of type CLLocationCoordinate2D
437
+ row_height: 200 # for better viewing
438
+ }
439
+ ```
440
+
441
+ Shows a map with a pin at the coordinates from value.
442
+
443
+
444
+ ### <a name="webview"></a> WebView row
445
+ ![WebView row](https://github.com/rheoli/formotion/wiki/row-types/Webview.png)
446
+ ```ruby
447
+ {
448
+ title: "Page",
449
+ type: :web_view,
450
+ value: html, # HTML code to be shown
451
+ row_height: 200 # for better viewing
452
+ }
453
+ ```
454
+
455
+
456
+ ### <a name="pagedimage"></a> PagedImage row
457
+ ![Pagedimage row](https://github.com/rheoli/formotion/wiki/row-types/Pagedimage.png)
458
+ ```ruby
459
+ {
460
+ title: "Photos",
461
+ type: :paged_image,
462
+ value: images, # array of UIImage's
463
+ row_height: 200 # for better viewing
464
+ }
465
+ ```
466
+ Same functionality as ImageRow but you can scroll through many photos.
467
+
468
+
469
+ ### <a name="tags"></a> Tags row
470
+ ![Tags row](https://github.com/rheoli/formotion/wiki/row-types/Tags.png)
471
+ ```ruby
472
+ {
473
+ title: "Tags",
474
+ type: :tags,
475
+ value: ["Beer","Dark Beer"],
476
+ row_height: 200 # for better viewing
477
+ }
478
+ ```
479
+
480
+ Add on_tap callback:
481
+ ```ruby
482
+ row.on_tap do |row|
483
+ ... # will be called when '+' in editable mode will touched
484
+ # add the new tag with row.object.add_tag(new_tag)
485
+ end
486
+
487
+ ```
488
+ Show/Edit tags.
489
+
490
+
491
+
381
492
  ## Buttons
382
493
 
383
494
  ### <a name="button"></a> Button row
@@ -386,10 +497,11 @@ Use a `:display_key` to show the value of the subform in the row:
386
497
  {
387
498
  title: "Any Button",
388
499
  type: :button,
500
+ key: :some_button
389
501
  }
390
502
 
391
503
  # later...
392
- form.sections[0].rows[0].on_tap do |row|
504
+ form.row(:some_button).on_tap do |row|
393
505
  # do something when tapped
394
506
  end
395
507
  ```
data/README.md CHANGED
@@ -218,6 +218,7 @@ end
218
218
  row.on_enter do |row|
219
219
  p "I'm called when the user taps the return key while typing in my text field"
220
220
  end
221
+ ```
221
222
 
222
223
  ## Forking
223
224
 
@@ -57,10 +57,24 @@ class AppDelegate
57
57
  type: :string,
58
58
  row_height: 60
59
59
  }, {
60
- title: "Text",
60
+ title: "Text",
61
+ key: :text,
62
+ type: :text,
63
+ placeholder: "Enter your text here",
64
+ row_height: 100
65
+ }, {
66
+ title: "Big Text",
67
+ key: :text,
68
+ type: :text,
69
+ font: {name: 'Helvetica', size: 24},
70
+ placeholder: "Enter your big text here",
71
+ row_height: 100
72
+ }, {
73
+ title: "Small Text",
61
74
  key: :text,
62
75
  type: :text,
63
- placeholder: "Enter your text here",
76
+ font: {name: 'Chalkduster', size: 8},
77
+ placeholder: "Enter your small text here",
64
78
  row_height: 100
65
79
  }, {
66
80
  title: "Check",
data/lib/formotion.rb CHANGED
@@ -1,7 +1,15 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "formotion/version"))
2
2
  require 'bubble-wrap/core'
3
+ require 'bubble-wrap/font'
3
4
  require 'bubble-wrap/camera'
4
5
 
5
6
  require 'motion-require'
6
7
 
7
- Motion::Require.all(Dir.glob(File.expand_path('../formotion/**/*.rb', __FILE__)))
8
+ Motion::Require.all(Dir.glob(File.expand_path('../formotion/**/*.rb', __FILE__)))
9
+
10
+ Motion::Project::App.setup do |app|
11
+ app.frameworks<<'CoreLocation' unless app.frameworks.include?('CoreLocation')
12
+ app.frameworks<<'MapKit' unless app.frameworks.include?('MapKit')
13
+
14
+ app.resources_dirs << File.join(File.dirname(__FILE__), '../resources')
15
+ end
@@ -96,6 +96,13 @@ module Formotion
96
96
  self.sections[index_path.section].rows[index_path.row]
97
97
  end
98
98
 
99
+ def row(key)
100
+ each_row do |row|
101
+ return row if row.key == key
102
+ end
103
+ nil
104
+ end
105
+
99
106
  #########################
100
107
  # callbacks
101
108
 
@@ -35,7 +35,7 @@ module Formotion
35
35
  previous_row, next_row = nil
36
36
 
37
37
  last_row = self.sections[-1] && self.sections[-1].rows[-1]
38
- if last_row
38
+ if last_row && last_row.type != :text
39
39
  last_row.return_key ||= UIReturnKeyDone
40
40
  end
41
41
 
@@ -92,7 +92,7 @@ module Formotion
92
92
  def tableView(tableView, didSelectRowAtIndexPath:indexPath)
93
93
  tableView.deselectRowAtIndexPath(indexPath, animated:true)
94
94
  row = row_for_index_path(indexPath)
95
- row.object.on_select(tableView, self)
95
+ row.object._on_select(tableView, self)
96
96
  end
97
97
 
98
98
  def tableView(tableView, editingStyleForRowAtIndexPath:indexPath)
@@ -0,0 +1,45 @@
1
+ class UIImage
2
+
3
+ # Resize Image
4
+ # target_size: Array or CGSize
5
+ # upscale: Boolean (false = do not upscale image)
6
+ #
7
+ # Code ideas from http://stackoverflow.com/questions/15653953/resize-image-in-iphone
8
+ #
9
+ def resize_image_to_size(target_size, upscale=true)
10
+ image_size = self.size
11
+
12
+ # convert Array to CGSize
13
+ if target_size.is_a?(Array)
14
+ target_size = CGSizeMake(target_size[0], target_size[1])
15
+ end
16
+ # when target_size no CGSize set to image_size
17
+ unless target_size.is_a?(CGSize)
18
+ target_size = image_size
19
+ end
20
+
21
+ # do not upscale when requested
22
+ if !upscale and (target_size.width > image_size.width or target_size.height > image_size.height)
23
+ target_size = image_size
24
+ end
25
+
26
+ unless CGSizeEqualToSize(image_size, target_size)
27
+ width_factor = target_size.width / image_size.width
28
+ height_factor = target_size.height / image_size.height
29
+ if width_factor < height_factor
30
+ target_size.height = image_size.height * width_factor
31
+ else
32
+ target_size.width = image_size.width * height_factor
33
+ end
34
+ end
35
+
36
+ UIGraphicsBeginImageContext(target_size)
37
+ resize_rect = CGRectMake(0, 0, target_size.width, target_size.height)
38
+ self.drawInRect resize_rect
39
+ resized_image = UIGraphicsGetImageFromCurrentImageContext()
40
+ UIGraphicsEndImageContext()
41
+
42
+ resized_image
43
+ end
44
+
45
+ end
@@ -55,7 +55,10 @@ class UITextView
55
55
  end
56
56
 
57
57
  def placeholder_rect
58
- CGRectMake(self.contentInset.left + 10.0, self.contentInset.top, self.frame.size.width - self.contentInset.left - self.contentInset.right - 16.0, self.frame.size.height - self.contentInset.top - self.contentInset.bottom - 16.0)
58
+ x_offset = font.xHeight
59
+ y_offset = font.capHeight + font.descender
60
+
61
+ CGRectMake(self.contentInset.left + x_offset, self.contentInset.top + y_offset, self.frame.size.width - self.contentInset.left - self.contentInset.right - x_offset, self.frame.size.height - self.contentInset.top - self.contentInset.bottom - y_offset)
59
62
  end
60
63
 
61
64
  def placeholder_color
@@ -88,10 +88,18 @@ module Formotion
88
88
  # In a date/time or time picker, the minute interval can
89
89
  # be set. That allows picking by every 15 minutes, etc.
90
90
  :minute_interval,
91
+ #-Resize image when needed (size as Array [1500,1500])
92
+ :max_image_size,
93
+ # Font for String and Text rows
94
+ :font,
91
95
  # Display an inputAccessoryView when editing a StringRow.
92
96
  # OPTIONS: :done (a black translucent toolbar with a right-aligned "Done" button)
93
97
  # DEFAULT is nil
94
- :input_accessory
98
+ :input_accessory,
99
+ # Cell selection style
100
+ # OPTIONS: :blue, :gray, :none
101
+ # DEFAULT is :blue
102
+ :selection_style
95
103
  ]
96
104
  PROPERTIES.each {|prop|
97
105
  attr_accessor prop
@@ -257,6 +265,10 @@ module Formotion
257
265
  @text_alignment = const_int_get("UITextAlignment", alignment)
258
266
  end
259
267
 
268
+ def selection_style=(style)
269
+ @selection_style = const_int_get("UITableViewCellSelectionStyle", style || :blue)
270
+ end
271
+
260
272
  def editable=(editable)
261
273
  case editable
262
274
  when TrueClass
@@ -56,17 +56,26 @@ module Formotion
56
56
 
57
57
  # method gets triggered when tableView(tableView, didSelectRowAtIndexPath:indexPath)
58
58
  # in UITableViewDelegate is executed
59
- def on_select(tableView, tableViewDelegate)
59
+ def _on_select(tableView, tableViewDelegate)
60
60
  # row class should call super and proceed if false is return (not handled here)
61
61
  if row.on_tap_callback
62
62
  # Not all row types will want to define on_tap, but call it if so
63
- row.on_tap_callback.call(self.row)
64
- true
63
+ if row.on_tap_callback.call(self.row) != false
64
+ on_select(tableView, tableViewDelegate)
65
+ true
66
+ else
67
+ false
68
+ end
65
69
  else
66
- false
70
+ on_select(tableView, tableViewDelegate)
67
71
  end
68
72
  end
69
73
 
74
+ # Override in subclass
75
+ def on_select(tableView, tableViewDelegate)
76
+ false
77
+ end
78
+
70
79
  # called when the delete editing style was triggered tableView:commitEditingStyle:forRowAtIndexPath:
71
80
  def on_delete(tableView, tableViewDelegate)
72
81
  if row.on_delete_callback
@@ -11,6 +11,7 @@ module Formotion
11
11
  # for just this one UITableViewCell object, in order to
12
12
  # center it's labels horizontally.
13
13
  def build_cell(cell)
14
+ cell.selectionStyle = self.row.selection_style || UITableViewCellSelectionStyleBlue
14
15
  cell.swizzle(:layoutSubviews) do
15
16
  def layoutSubviews
16
17
  old_layoutSubviews
@@ -14,6 +14,7 @@ module Formotion
14
14
  # instantiate long-lived objects in them.
15
15
  # Maybe that logic should be moved elsewhere?
16
16
  def build_cell(cell)
17
+ cell.selectionStyle = self.row.selection_style || UITableViewCellSelectionStyleBlue
17
18
  update_cell_value(cell)
18
19
  observe(self.row, "value") do |old_value, new_value|
19
20
  update_cell_value(cell)
@@ -36,4 +37,4 @@ module Formotion
36
37
 
37
38
  end
38
39
  end
39
- end
40
+ end
@@ -1,8 +1,11 @@
1
1
  motion_require 'string_row'
2
+ motion_require 'multi_choice_row'
2
3
 
3
4
  module Formotion
4
5
  module RowType
5
6
  class DateRow < StringRow
7
+ include RowType::MultiChoiceRow
8
+
6
9
  # overwrite Character on_change method
7
10
  def on_change(text_field)
8
11
  end