ProMotion 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. data/.gitignore +0 -1
  2. data/Gemfile +1 -1
  3. data/README.md +336 -92
  4. data/Rakefile +1 -1
  5. data/lib/ProMotion.rb +14 -0
  6. data/lib/ProMotion/app_delegate.rb +63 -0
  7. data/lib/ProMotion/cocoatouch/NavigationController.rb +4 -0
  8. data/lib/ProMotion/cocoatouch/TableViewCell.rb +16 -0
  9. data/lib/ProMotion/cocoatouch/TableViewController.rb +50 -0
  10. data/lib/ProMotion/cocoatouch/ViewController.rb +52 -0
  11. data/lib/ProMotion/helpers/console.rb +24 -0
  12. data/lib/ProMotion/helpers/measure_helper.rb +20 -0
  13. data/lib/ProMotion/helpers/system_helper.rb +29 -0
  14. data/lib/ProMotion/helpers/tab_bar.rb +115 -0
  15. data/lib/ProMotion/helpers/view_helper.rb +39 -0
  16. data/lib/ProMotion/pro_motion.rb +3 -0
  17. data/lib/ProMotion/screen_helpers/_tables/_searchable_table.rb +66 -0
  18. data/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb +265 -0
  19. data/lib/ProMotion/screen_helpers/_tables/grouped_table.rb +13 -0
  20. data/lib/ProMotion/screen_helpers/_tables/plain_table.rb +14 -0
  21. data/lib/ProMotion/screen_helpers/screen_elements.rb +43 -0
  22. data/lib/ProMotion/screen_helpers/screen_navigation.rb +106 -0
  23. data/lib/ProMotion/screen_helpers/screen_tabs.rb +92 -0
  24. data/lib/ProMotion/screens/_screen_module.rb +222 -0
  25. data/lib/ProMotion/screens/_table_screen_module.rb +30 -0
  26. data/lib/ProMotion/screens/screen.rb +7 -0
  27. data/lib/ProMotion/screens/table_screen.rb +15 -0
  28. data/lib/ProMotion/version.rb +3 -0
  29. metadata +43 -63
  30. data/app/app_delegate.rb +0 -5
  31. data/app/screens/home_screen.rb +0 -21
  32. data/app/screens/test_screen.rb +0 -26
data/.gitignore CHANGED
@@ -1,5 +1,4 @@
1
1
  /target
2
- /lib
3
2
  /classes
4
3
  /checkouts
5
4
  pom.xml
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in ProMotion.gemspec
4
4
  gemspec
data/README.md CHANGED
@@ -3,13 +3,50 @@
3
3
  ProMotion introduces a new object called "Screens". Screens have a one-to-one relationship
4
4
  with your app's designed screens.
5
5
 
6
- NEW video tutorial! Go watch it here: http://www.clearsightstudio.com/insights/tutorial-make-youtube-video-app-rubymotion-promotion/
6
+ ## Table of contents
7
7
 
8
- Check out the tutorial here: http://www.clearsightstudio.com/insights/ruby-motion-promotion-tutorial
8
+ 1. [Tutorials](#tutorials)
9
+ * [Screencasts](#screencasts)
10
+ * [Sample Apps](#sample-apps)
11
+ 1. **[Getting Started](#getting-started)**
12
+ * [Setup](#setup)
13
+ 1. [What's New?](#whats-new)
14
+ 1. [Usage](#usage)
15
+ * [Creating a basic screen](#creating-a-basic-screen)
16
+ * [Loading your first screen](#loading-your-first-screen)
17
+ * [Creating a tab bar](#creating-a-tab-bar)
18
+ * [Adding navigation bar buttons](#add-navigation-bar-buttons)
19
+ * [Opening and closing screens](#opening-and-closing-screens)
20
+ * [Adding view elements](#adding-view-elements)
21
+ * [Table screens](#table-screens)
22
+ * [Using your own UIViewController](#using-your-own-uiviewcontroller)
23
+ 1. [Reference](#reference)
24
+ 1. **[Help](#help)**
25
+ 1. [Contributing](#contributing)
26
+
27
+ ## Tutorials
28
+
29
+ Version 0.3 tutorial, will be updated soon but most of it still applies:
30
+
31
+ http://www.clearsightstudio.com/insights/ruby-motion-promotion-tutorial
32
+
33
+ ### Screencasts
34
+
35
+ Video tutorial with 0.4.
36
+
37
+ http://www.clearsightstudio.com/insights/tutorial-make-youtube-video-app-rubymotion-promotion/
38
+
39
+ ### Sample apps
9
40
 
10
41
  Sample app here: https://github.com/jamonholmgren/promotion-tutorial
11
42
 
12
- Typical app file structure:
43
+ Also, check out the free [BigDay! Reminder app](https://itunes.apple.com/us/app/bigday!/id571756685?ls=1&mt=8) on the
44
+ App Store to see what's possible. ClearSight Studio built the app for Kijome Software, a small app investment company.
45
+
46
+ ## Getting Started
47
+
48
+ ProMotion is designed to be as intuitive and Ruby-like as possible. For example, here is a
49
+ typical app folder structure:
13
50
 
14
51
  app/
15
52
  screens/
@@ -26,7 +63,79 @@ Typical app file structure:
26
63
  save_event_button_view.rb
27
64
  app_delegate.rb
28
65
 
29
- ## What's New in 0.4.0?
66
+ ### Setup
67
+
68
+ Create a new RubyMotion project.
69
+
70
+ `motion create myapp`
71
+
72
+ Open it in your favorite editor, then go into your Rakefile and add the following to the top:
73
+
74
+ ```ruby
75
+ # -*- coding: utf-8 -*-
76
+ $:.unshift("/Library/RubyMotion/lib")
77
+ require 'motion/project'
78
+ require "rubygems"
79
+ require 'bundler'
80
+ Bundler.require
81
+ ```
82
+
83
+
84
+ Create a Gemfile and add the following lines:
85
+
86
+ ```ruby
87
+ source 'https://rubygems.org'
88
+ gem "ProMotion", "~> 0.4.1"
89
+ ```
90
+
91
+ Run `bundle install` in Terminal to install ProMotion.
92
+
93
+ Go into your app/app_delegate.rb file and add the following:
94
+
95
+ ```ruby
96
+ class AppDelegate < ProMotion::AppDelegateParent
97
+ def on_load(app, options)
98
+ open HomeScreen.new(nav_bar: true)
99
+ end
100
+ end
101
+ ```
102
+
103
+ Create a folder in `/app` named `screens`. Create a file in that folder named `home_screen.rb`.
104
+
105
+ Now drop in this code:
106
+
107
+ ```ruby
108
+ class HomeScreen < ProMotion::Screen
109
+ title "Home"
110
+
111
+ def on_load
112
+ self.view.backgroundColor = UIColor.whiteColor
113
+ end
114
+ end
115
+ ```
116
+
117
+
118
+ Run `rake`. You should now see the simulator open with your home screen and a navigation bar like the image below. Congrats!
119
+
120
+ ![ProMotion Home Screen](http://clearsightstudio.github.com/ProMotion/img/ProMotion/home-screen.png)
121
+
122
+
123
+ ## What's New?
124
+
125
+ ### Version 0.5.0
126
+
127
+ Version 0.5.0 is mostly a documentation and consistency release. It should be backwards-compatible
128
+ with 0.4.0.
129
+
130
+ * Rearranged internal folders to make a lot more sense
131
+ * More complete API documentation
132
+ * Refactored camelCase methods and configs to under_score
133
+ * Set `should_autorotate` to true by default
134
+ * Changed `open_screen` to `open` (`open_screen` still works for backwards compatibility)
135
+ * `add_element` is now `add` (and `remove_element` is `remove`)
136
+ * Removed built-in app (will release some sample apps soon, including a "Kitchen Sink" one)
137
+
138
+ ### Version 0.4.0
30
139
 
31
140
  * Screens are now UIViewControllers (they used to contain UIViewControllers, but that got too funky) so you can do normal UIViewController stuff with them
32
141
  * Screen functionality can also be inherited as a module in your own UIViewController, but you need to provide your own methods for viewDidLoad and whatnot.
@@ -41,50 +150,53 @@ Typical app file structure:
41
150
  * Better documentation (still needs work), better error messages
42
151
  * Deprecation warnings EVERYWHERE for older apps (upgrade already!)
43
152
 
44
- ## Usage
45
-
46
- Loading your home screen:
47
153
 
48
- ```ruby
49
- # In /app/app_delegate.rb
50
- class AppDelegate < ProMotion::AppDelegate
51
- def on_load(app, options)
52
- open MyHomeScreen.new(nav_bar: true)
53
- end
54
- end
55
- ```
154
+ ## Usage
56
155
 
57
- Creating a basic screen:
156
+ ### Creating a basic screen
58
157
 
59
158
  ```ruby
60
159
  class HomeScreen < ProMotion::Screen
61
160
  title "Home"
62
161
 
63
162
  def on_load
64
- # Set up the elements in your view with add_element:
65
- @label = add_element UILabel.alloc.initWithFrame(CGRectMake(5, 5, 20, 20)), {
66
- text: "This is awesome!",
67
- font: UIFont.systemFontOfSize(18)
68
- }
163
+ # Load data
164
+ end
165
+
166
+ def will_appear
167
+ # Set up the elements in your view with add_view
168
+ @label = add_view UILabel.alloc.initWithFrame(CGRectMake(5, 5, 20, 20))
69
169
  end
70
170
 
71
171
  def on_appear
72
- # Refresh the data if you want
172
+ # Everything's loaded and visible
73
173
  end
74
174
  end
75
175
  ```
76
176
 
77
- Creating a tabbed bar with multiple screens. This will set the tab bar as the root view controller for your app,
78
- so keep that in mind. It can be done from the AppDelegate#on_load or from a screen.
177
+ ### Loading your first screen
79
178
 
80
- ### Creating a tab bar with several screens
179
+ ```ruby
180
+ # In /app/app_delegate.rb
181
+ class AppDelegate < ProMotion::AppDelegate
182
+ def on_load(app, options)
183
+ open MyHomeScreen.new(nav_bar: true)
184
+ end
185
+ end
186
+ ```
187
+
188
+ ### Creating a tab bar
189
+
190
+ Creating a tabbed bar with multiple screens. This will set the tab bar as the root view controller for your app,
191
+ so keep that in mind. It can be done from the AppDelegate#on_load or from a screen (that screen will go away, though).
81
192
 
82
193
  ```ruby
83
194
  def on_load(app, options)
84
195
  @home = MyHomeScreen.new(nav_bar: true)
85
196
  @settings = SettingsScreen.new
86
197
  @contact = ContactScreen.new(nav_bar: true)
87
- @tab_bar = open_tab_bar @home, @settings, @contact
198
+
199
+ open_tab_bar @home, @settings, @contact
88
200
  end
89
201
  ```
90
202
 
@@ -96,31 +208,32 @@ def on_load
96
208
  set_tab_bar_item title: "Tab Name Goes Here", icon: "icons/tab_icon.png" # in resources/icons folder
97
209
 
98
210
  # or...
99
- set_tab_bar_item title: "Contacts", system_icon: UITabBarSystemItemContacts
211
+ set_tab_bar_item system_icon: UITabBarSystemItemContacts
100
212
  end
101
213
  ```
102
214
 
103
- ### Adding view elements
104
-
105
- Any view item (UIView, UIButton, custom UIView subclasses, etc) can be used with add_element.
106
- The second argument is a hash of settings that get applied to the
107
- element before it is dropped into the view.
215
+ To programmatically switch to a different tab, use `open_tab`.
108
216
 
109
217
  ```ruby
110
- @label = add_element UILabel.alloc.initWithFrame(CGRectMake(5, 5, 20, 20)), {
111
- text: "This is awesome!",
112
- font: UIFont.systemFontOfSize(18)
113
- }
218
+ def some_action
219
+ open_tab "Contacts"
220
+ end
114
221
  ```
115
222
 
116
- Add nav_bar buttons:
223
+ ### Add navigation bar buttons
224
+
225
+ These two methods add the buttons to the top navigation bar of a screen. The `action:` lets you specify a method to
226
+ call when that button is tapped, and you can pass in a UIBarButton style using `type:`.
117
227
 
118
228
  ```ruby
119
229
  set_nav_bar_right_button "Save", action: :save_something, type: UIBarButtonItemStyleDone
120
230
  set_nav_bar_left_button "Cancel", action: :return_to_some_other_screen, type: UIBarButtonItemStylePlain
121
231
  ```
122
232
 
123
- Open a new screen:
233
+ ### Opening and closing screens
234
+
235
+ If the user taps something and you want to open a new screen, it's easy. Just use `open` and pass in the screen class
236
+ or an instance of that screen.
124
237
 
125
238
  ```ruby
126
239
  def settings_button_tapped
@@ -133,10 +246,10 @@ def settings_button_tapped
133
246
  end
134
247
  ```
135
248
 
136
- Open a new screen as a modal:
249
+ You can also open a screen as a modal.
137
250
 
138
251
  ```ruby
139
- open SettingsScreen, modal: true
252
+ open SettingsScreen.new, modal: true
140
253
  ```
141
254
 
142
255
  You can pass in arguments to other screens if they have accessors:
@@ -160,7 +273,16 @@ end
160
273
 
161
274
  ```
162
275
 
163
- Close a screen (modal or in a nav controller), passing back arguments to the previous screen's "on_return" method:
276
+ Closing a screen is as easy as can be.
277
+
278
+ ```ruby
279
+ # User taps a button, indicating they want to close this screen.
280
+ def close_screen_tapped
281
+ close
282
+ end
283
+ ```
284
+
285
+ You can close a screen (modal or in a nav controller) and pass back arguments to the previous screen's "on_return" method:
164
286
 
165
287
  ```ruby
166
288
  class ItemScreen < ProMotion::Screen
@@ -182,23 +304,34 @@ class MainScreen < ProMotion::Screen
182
304
  end
183
305
  ```
184
306
 
185
- The helper add_element takes any view object and adds it to the current view. You can also use
186
- the helper ProMotion::ViewHelper.set_attributes(view, attributes) to do the same thing without adding
187
- it to the current view. Screens include this helper by default.
307
+ ### Adding view elements
308
+
309
+ Any view item (UIView, UIButton, custom UIView subclasses, etc) can be added to the current view with `add_view`.
310
+ `add_view` accepts a second argument which is a hash of attributes that get applied to the element before it is
311
+ dropped into the view.
188
312
 
189
313
  ```ruby
190
- @element = add_element UIView.alloc.initWithFrame(CGRectMake(0, 0, 20, 20)), {
314
+ @label = add_view UILabel.alloc.initWithFrame(CGRectMake(5, 5, 20, 20)), {
315
+ text: "This is awesome!",
316
+ font: UIFont.systemFontOfSize(18)
317
+ }
318
+
319
+ @element = add_view UIView.alloc.initWithFrame(CGRectMake(0, 0, 20, 20)), {
191
320
  backgroundColor: UIColor.whiteColor
192
321
  }
322
+ ```
193
323
 
324
+ The `set_attributes` method is identical to add_view except that it does not add it to the current view.
325
+
326
+ ```ruby
194
327
  @element = set_attributes UIView.alloc.initWithFrame(CGRectMake(0, 0, 20, 20)), {
195
328
  backgroundColor: UIColor.whiteColor
196
329
  }
197
330
  ```
198
331
 
199
- You can create sectioned table screens easily. TableScreen, SectionedTableScreen, GroupedTableScreen.
200
- This is loosely based on [motion-table](https://github.com/clearsightstudio/motion-table) (there are a
201
- few minor differences). We will eventually combine the two.
332
+ ### Table Screens
333
+
334
+ You can create sectioned table screens easily with TableScreen, SectionedTableScreen, and GroupedTableScreen.
202
335
 
203
336
  ```ruby
204
337
  class SettingsScreen < ProMotion::GroupedTableScreen
@@ -210,7 +343,7 @@ class SettingsScreen < ProMotion::GroupedTableScreen
210
343
  end
211
344
 
212
345
  # table_data is automatically called. Use this format in the return value.
213
- # Grouped tables are the same as plain tables
346
+ # It's an array of cell groups, each cell group consisting of a title and an array of cells.
214
347
  def table_data
215
348
  [{
216
349
  title: "Your Account",
@@ -230,12 +363,15 @@ class SettingsScreen < ProMotion::GroupedTableScreen
230
363
 
231
364
  # This method allows you to create a "jumplist", the index on the right side of the table
232
365
  def table_data_index
233
- return ["A", "B", "C"]
366
+ # Ruby magic to make an alphabetical array of letters.
367
+ # Try this in Objective-C and tell me you want to go back.
368
+ return ("A".."Z").to_a
234
369
  end
235
370
 
236
- # Your table cells, when tapped, will execute the corresponding actions and pass in arguments:
237
- def edit_profile(arguments)
238
- # ...
371
+ # Your table cells, when tapped, will execute the corresponding actions
372
+ # and pass in the specified arguments.
373
+ def edit_profile(args={})
374
+ puts args[:id] # => 3
239
375
  end
240
376
  end
241
377
  ```
@@ -247,16 +383,19 @@ your Rakefile and doing this:
247
383
  cells: [
248
384
  {
249
385
  title: "Cell with image",
250
- remoteImage: { url: "http://placekitten.com/200/300", placeholder: "some-local-image" }
386
+ remote_image: { url: "http://placekitten.com/200/300", placeholder: "some-local-image" }
251
387
  }
252
388
  ]
253
389
  ```
254
390
 
255
- ## Using your own UIViewController or Formotion
391
+ ### Using your own UIViewController
392
+
393
+ Sometimes you want to inherit from a different UIViewController other than that provided by ProMotion,
394
+ such as when using [Formotion](https://github.com/clayallsopp/formotion). **RubyMotion doesn't currently
395
+ allow us to override built-in methods when including them as a module.** And we really need to override
396
+ `viewDidLoad` and others.
256
397
 
257
- Sometimes you want to inherit from a different UIViewController than that provided by ProMotion,
258
- such as when using [Formotion](https://github.com/clayallsopp/formotion). RubyMotion doesn't currently allow us to override built-in methods
259
- when including as a module, so there's a workaround for that.
398
+ Fortunately, there's a workaround for that.
260
399
 
261
400
  ```ruby
262
401
  class EventsScreen < Formotion::FormController # Can also be < UIViewController
@@ -307,8 +446,7 @@ class EventsScreen < Formotion::FormController # Can also be < UIViewController
307
446
  end
308
447
  ```
309
448
 
310
- # Reference
311
- (not comprehensive yet...working on this)
449
+ ## Reference
312
450
 
313
451
  <table>
314
452
  <tr>
@@ -321,6 +459,11 @@ end
321
459
  <td>is_modal?</td>
322
460
  <td>Returns if the screen was opened in a modal window.</td>
323
461
  </tr>
462
+ <tr>
463
+ <td>&nbsp;</td>
464
+ <td>self</td>
465
+ <td>Returns the Screen which is a subclass of UIViewController or UITableViewController</td>
466
+ </tr>
324
467
  <tr>
325
468
  <td>&nbsp;</td>
326
469
  <td>has_nav_bar?</td>
@@ -346,6 +489,8 @@ end
346
489
  <td>will_appear</td>
347
490
  <td>
348
491
  Callback for before the screen appears.<br />
492
+ This is a good place to put your view constructors, but be careful that
493
+ you don't add things more than on subsequent screen loads.
349
494
  </td>
350
495
  </tr>
351
496
  <tr>
@@ -389,29 +534,15 @@ end
389
534
  <td>&nbsp;</td>
390
535
  <td>should_autorotate</td>
391
536
  <td>
392
- iOS 5 return true/false if screen should rotate<br />
537
+ (iOS 6) return true/false if screen should rotate.<br />
538
+ Defaults to true.
393
539
  </td>
394
540
  </tr>
395
541
  <tr>
396
542
  <td>&nbsp;</td>
397
543
  <td>should_rotate(orientation)</td>
398
544
  <td>
399
- Return true/false for rotation to orientation.<br />
400
- </td>
401
- </tr>
402
- <tr>
403
- <td>&nbsp;</td>
404
- <td>supported_orientation?(orientation)</td>
405
- <td>
406
- Returns true/false if orientation is in NSBundle.mainBundle.infoDictionary["UISupportedInterfaceOrientations"].<br />
407
- Shouldn't need to override this.
408
- </td>
409
- </tr>
410
- <tr>
411
- <td>&nbsp;</td>
412
- <td>supported_orientations</td>
413
- <td>
414
- Returns supported orientation mask<br />
545
+ (iOS 5) Return true/false for rotation to orientation.<br />
415
546
  </td>
416
547
  </tr>
417
548
  <tr>
@@ -426,6 +557,16 @@ end
426
557
  <td>title=(title)</td>
427
558
  <td>
428
559
  Sets title of current screen.<br />
560
+ You can also set the title like this (not in a method, though):<br />
561
+ <pre><code>
562
+ class SomeScreen
563
+ title "Some screen"
564
+
565
+ def on_load
566
+ # ...
567
+ end
568
+ end
569
+ </code></pre>
429
570
  </td>
430
571
  </tr>
431
572
  <tr>
@@ -433,16 +574,24 @@ end
433
574
  ScreenElements<br />
434
575
  Included in Screen by default
435
576
  </td>
436
- <td>add_element(view, attrs = {})</td>
577
+ <td>add(view, attrs = {})</td>
437
578
  <td>
438
579
  Adds the view to the screen after applying the attributes.<br />
580
+ (alias: `add_element`, `add_view`)<br />
581
+ Example:
582
+ <code>
583
+ add_view UIInputView.alloc.initWithFrame(CGRectMake(10, 10, 300, 40)), {
584
+ backgroundColor: UIColor.grayColor
585
+ }
586
+ </code>
439
587
  </td>
440
588
  </tr>
441
589
  <tr>
442
590
  <td>&nbsp;</td>
443
- <td>remove_element</td>
591
+ <td>remove(view)</td>
444
592
  <td>
445
593
  Removes the view from the superview and sets it to nil<br />
594
+ (alias: `remove_element`, `remove_view`)
446
595
  </td>
447
596
  </tr>
448
597
  <tr>
@@ -463,7 +612,7 @@ end
463
612
  <td>&nbsp;</td>
464
613
  <td>view</td>
465
614
  <td>
466
- Accessor for self.view<br />
615
+ The main view for this screen.<br />
467
616
  </td>
468
617
  </tr>
469
618
  <tr>
@@ -524,14 +673,14 @@ end
524
673
  <td>&nbsp;</td>
525
674
  <td>close(args = {})</td>
526
675
  <td>
527
- Closes the current screen, passes args back to the previous screen's on_return method<br />
676
+ Closes the current screen, passes args back to the previous screen's <code>on_return</code> method<br />
528
677
  </td>
529
678
  </tr>
530
679
  <tr>
531
680
  <td>&nbsp;</td>
532
681
  <td>open_root_screen(screen)</td>
533
682
  <td>
534
- Closes all other open screens and opens `screen` at the root.<br />
683
+ Closes all other open screens and opens <code>screen</code> as the root view controller.<br />
535
684
  </td>
536
685
  </tr>
537
686
  <tr>
@@ -539,32 +688,127 @@ end
539
688
  <td>open(screen, args = {})</td>
540
689
  <td>
541
690
  Pushes the screen onto the navigation stack or opens in a modal<br />
542
- argument options :hide_tab_bar, :modal, any accessors in `screen`
691
+ Argument options:<br />
692
+ <code>nav_bar: true|false</code> (note: this has no effect if you're already in a navigation controller)<br />
693
+ <code>hide_tab_bar: true|false</code><br />
694
+ <code>modal: true|false</code><br />
695
+ <code>close_all: true|false</code> (closes all open screens and opens as root)<br />
696
+ <code>animated: true:false</code> (currently only affects modals)<br />
697
+ <code>in_tab: "Tab name"</code> (if you're in a tab bar)<br />
698
+ any accessors in <code>screen</code>
699
+ </td>
700
+ </tr>
701
+ <tr>
702
+ <td>&nbsp;</td>
703
+ <td>open_tab_bar(*screens)</td>
704
+ <td>
705
+ Open a UITabBarController with the specified screens as the root view controller of the current app<br />
543
706
  </td>
544
707
  </tr>
545
708
  <tr>
546
709
  <td>&nbsp;</td>
547
710
  <td>open_tab(tab)</td>
548
711
  <td>
549
- Opens the tab where the "string" title is equal to the passed in tab<br />
712
+ Opens the tab where the "string" title matches the passed in tab<br />
550
713
  </td>
551
714
  </tr>
715
+
552
716
  <tr>
717
+ <td>TableScreen</td>
553
718
  <td>&nbsp;</td>
554
- <td>open_tab_bar(*screens)</td>
719
+ <td>*Has all the methods of Screen*</td>
720
+ </tr>
721
+ <tr>
722
+ <td>&nbsp;</td>
723
+ <td>self</td>
724
+ <td>Returns the current UITableViewController (not UITableView)</td>
725
+ </tr>
726
+ <tr>
727
+ <td>&nbsp;</td>
728
+ <td>searchable(placeholder: "placeholder text")</td>
729
+ <td>Class method to make the current table searchable.</td>
730
+ </tr>
731
+ <tr>
732
+ <td>&nbsp;</td>
733
+ <td colspan="2">
734
+ <h3>table_data</h3>
735
+ Method that is called to get the table's cell data and build the table.<br />
736
+ Example format using nearly all available options.<br />
737
+ <strong>Note...</strong> if you're getting crazy deep into styling your table cells,
738
+ you really should be subclassing them and specifying that new class in <code>:cell_class</code>
739
+ and then providing <code>:cell_class_attributes</code> to customize it.<br /><br />
740
+ <strong>Performance note...</strong> It's best to build this array in a different method
741
+ and store it in something like <code>@table_data</code>. Then your <code>table_data</code>
742
+ method just returns that.
743
+
744
+ <pre><code>
745
+ def table_data
746
+ [{
747
+ title: "Table cell group 1",
748
+ cells: [{
749
+ title: "Simple cell",
750
+ action: :this_cell_tapped,
751
+ arguments: { id: 4 }
752
+ }, {
753
+ title: "Crazy Full Featured Cell",
754
+ subtitle: "This is way too huge..see note",
755
+ arguments: { data: [ "lots", "of", "data" ] },
756
+ action: :tapped_cell_1,
757
+ cell_style: UITableViewCellStyleSubtitle,
758
+ cell_identifier: "Cell",
759
+ cell_class: ProMotion::TableViewCell,
760
+ masks_to_bounds: true,
761
+ background_color: UIColor.whiteColor,
762
+ selection_style: UITableViewCellSelectionStyleGray,
763
+ cell_class_attributes: {
764
+ # any Obj-C attributes to set on the cell
765
+ backgroundColor: UIColor.whiteColor
766
+ },
767
+ accessory: :switch, # currently only :switch is supported
768
+ accessory_view: @some_accessory_view,
769
+ accessory_type: UITableViewCellAccessoryCheckmark,
770
+ accessory_checked: true, # whether it's "checked" or not
771
+ image: { image: UIImage.imageNamed("something"), radius: 15 },
772
+ remote_image: { # remote image, requires SDWebImage CocoaPod
773
+ url: "http://placekitten.com/200/300", placeholder: "some-local-image",
774
+ size: 50, radius: 15
775
+ },
776
+ subviews: [ @some_view, @some_other_view ] # arbitrary views added to the cell
777
+ }]
778
+ }, {
779
+ title: "Table cell group 2",
780
+ cells: [{
781
+ title: "Log out",
782
+ action: :log_out
783
+ }]
784
+ }]
785
+ end
786
+ </code></pre>
787
+ <img src="http://clearsightstudio.github.com/ProMotion/img/ProMotion/full-featured-table-screen.png" />
788
+ </td>
789
+ </tr>
790
+ <tr>
791
+ <td>&nbsp;</td>
792
+ <td>update_table_data</td>
555
793
  <td>
556
- Open a UITabBarController with the specified screens as the root view controller of the current app<br />
794
+ Causes the table data to be refreshed, such as when a remote data source has
795
+ been downloaded and processed.<br />
557
796
  </td>
558
797
  </tr>
559
- </table>
560
798
 
561
- ### What about MVC?
799
+ <tr>
800
+ <td>Console</td>
801
+ <td>log(log, with_color:color)</td>
802
+ <td>
803
+ Class method to output a colored console message.<br />
804
+ Example: <code>ProMotion::Console.log("This is red!", with_color: ProMotion::Console::RED_COLOR)</code>
805
+ </td>
806
+ </tr>
807
+ </table>
562
808
 
563
- I'm a big believer in MVC (I'm a Rails developer, too). I found that most of the time working in RubyMotion seems to happen
564
- in the ViewControllers and views are mainly custom elements. This pattern is probably best for navigation controller and
565
- tab bar based apps.
809
+ ## Help
566
810
 
567
- Feedback welcome via twitter @jamonholmgren or email jamon@clearsightstudio.com.
811
+ If you need help, feel free to ping me on twitter @jamonholmgren or email jamon@clearsightstudio.com, or open a ticket on GitHub.
568
812
 
569
813
  ## Contributing
570
814