mirror of
https://github.com/zhigang1992/ProMotion.git
synced 2026-01-12 22:49:55 +08:00
Added wiki docs to /docs in preparation for potential move to ReadTheDocs
This commit is contained in:
31
docs/API Reference - Command Line Tool.md
Normal file
31
docs/API Reference - Command Line Tool.md
Normal file
@@ -0,0 +1,31 @@
|
||||
ProMotion comes bundled with an executable called `promotion`. For now, it just creates a scaffold ProMotion project. We may extend it to include generators and other helpful utilities down the road.
|
||||
|
||||
#### promotion new `appname`
|
||||
|
||||
Creates a new ProMotion app in a new `appname` folder.
|
||||
|
||||
```shell
|
||||
$ gem install ProMotion
|
||||
Successfully installed ProMotion
|
||||
1 gem installed
|
||||
|
||||
$ promotion new mytestapp
|
||||
Creating new ProMotion iOS app mytestapp
|
||||
From github.com:jamonholmgren/promotion-template
|
||||
* branch master -> FETCH_HEAD
|
||||
a3f98a9..676fd71 master -> origin/master
|
||||
Create mytestapp
|
||||
Create mytestapp/.gitignore
|
||||
Create mytestapp/app/app_delegate.rb
|
||||
Create mytestapp/app/layouts/.gitkeep
|
||||
Create mytestapp/app/models/.gitkeep
|
||||
Create mytestapp/app/screens/help_screen.rb
|
||||
Create mytestapp/app/screens/home_screen.rb
|
||||
Create mytestapp/app/styles/.gitkeep
|
||||
Create mytestapp/app/views/.gitkeep
|
||||
Create mytestapp/Gemfile
|
||||
Create mytestapp/Rakefile
|
||||
Create mytestapp/resources/Default-568h@2x.png
|
||||
Create mytestapp/spec/main_spec.rb
|
||||
Create mytestapp/spec/screens/home_screen_spec.rb
|
||||
```
|
||||
161
docs/API Reference - ProMotion Delegate.md
Normal file
161
docs/API Reference - ProMotion Delegate.md
Normal file
@@ -0,0 +1,161 @@
|
||||
### Contents
|
||||
|
||||
* [Usage](?#usage)
|
||||
* [Methods](?#methods)
|
||||
* [Class Methods](?#class-methods)
|
||||
* [Accessors](?#accessors)
|
||||
|
||||
### Usage
|
||||
|
||||
The PM::Delegate gives you ProMotion's nice API for your AppDelegate class.
|
||||
|
||||
```ruby
|
||||
# app/app_delegate.rb
|
||||
class AppDelegate < PM::Delegate
|
||||
status_bar false, animation: :none
|
||||
|
||||
def on_load(app, options)
|
||||
open HomeScreen.new(nav_bar: true)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
If you need to inherit from a different AppDelegate superclass, do this:
|
||||
|
||||
```ruby
|
||||
class AppDelegate < JHMyParentDelegate
|
||||
include PM::DelegateModule
|
||||
status_bar false, animation: :none
|
||||
|
||||
def on_load(app, options)
|
||||
open HomeScreen.new(nav_bar: true)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
#### on_load(app, options)
|
||||
|
||||
Main method called when starting your app. Open your first screen, tab bar, or split view here.
|
||||
|
||||
```ruby
|
||||
def on_load(app, options)
|
||||
open HomeScreen
|
||||
end
|
||||
```
|
||||
|
||||
#### on_unload
|
||||
|
||||
Fires when the app is about to terminate. Don't do anything crazy here, but it's a last chance
|
||||
to save state if necessary.
|
||||
|
||||
```ruby
|
||||
def on_unload
|
||||
# Unloading!
|
||||
end
|
||||
```
|
||||
|
||||
#### will_load(app, options)
|
||||
|
||||
Fired just before the app loads. Not usually necessary.
|
||||
|
||||
#### on_activate
|
||||
|
||||
Fires when the app becomes active.
|
||||
|
||||
#### will_deactivate
|
||||
|
||||
Fires when the app is about to become inactive.
|
||||
|
||||
#### on_enter_background
|
||||
|
||||
Fires when the app enters the background.
|
||||
|
||||
#### will_enter_foreground
|
||||
|
||||
Fires just before the app enters the foreground.
|
||||
|
||||
#### open_tab_bar(*screens)
|
||||
|
||||
Opens a UITabBarController with the specified screens as the root view controller of the current app.
|
||||
iOS doesn't allow opening a UITabBar as a sub-view.
|
||||
|
||||
```ruby
|
||||
def on_load(app, options)
|
||||
open_tab_bar HomeScreen, AboutScreen, ThirdScreen, HelpScreen
|
||||
end
|
||||
```
|
||||
|
||||
#### open_split_screen(master, detail)
|
||||
|
||||
**iPad apps only**
|
||||
|
||||
Opens a UISplitScreenViewController with the specified screens as the root view controller of the current app
|
||||
|
||||
```ruby
|
||||
def on_load(app, options)
|
||||
open_split_screen MasterScreen, DetailScreen,
|
||||
icon: "split-icon", title: "Split Screen Title" # optional
|
||||
end
|
||||
```
|
||||
|
||||
#### on_open_url(args = {})
|
||||
|
||||
Fires when the application is opened via a URL (utilizing [application:openURL:sourceApplication:annotation:](http://developer.apple.com/library/ios/#documentation/uikit/reference/UIApplicationDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UIApplicationDelegate/application:openURL:sourceApplication:annotation:)).
|
||||
|
||||
```ruby
|
||||
def on_open_url(args = {})
|
||||
args[:url] # => the URL used to fire the app (NSURL)
|
||||
args[:source_app] # => the bundle ID of the app that is launching your app (string)
|
||||
args[:annotation] # => hash with annotation data from the source app
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Class Methods
|
||||
|
||||
#### status_bar
|
||||
|
||||
Class method that allows hiding or showing the status bar.
|
||||
|
||||
```ruby
|
||||
class AppDelegate < PM::Delegate
|
||||
status_bar true, animation: :none # :slide, :fade
|
||||
end
|
||||
```
|
||||
|
||||
#### tint_color
|
||||
|
||||
Class method that allows you to set the application's global tint color for iOS 7 apps.
|
||||
|
||||
```ruby
|
||||
class AppDelegate < ProMotion::Delegate
|
||||
tint_color UIColor.greenColor
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Accessors
|
||||
|
||||
#### window
|
||||
|
||||
References the UIWindow that is auto-created with the first `open`, `open_tab_bar`, or `open_split_screen` call.
|
||||
|
||||
```ruby
|
||||
def some_method
|
||||
self.window #=> UIWindow instance
|
||||
end
|
||||
```
|
||||
|
||||
#### home_screen
|
||||
|
||||
References the root screen for the app.
|
||||
|
||||
```ruby
|
||||
def some_method
|
||||
self.home_screen #=> PM::Screen instance
|
||||
end
|
||||
```
|
||||
79
docs/API Reference - ProMotion Logger.md
Normal file
79
docs/API Reference - ProMotion Logger.md
Normal file
@@ -0,0 +1,79 @@
|
||||
### Contents
|
||||
|
||||
* [Usage](?#usage)
|
||||
* [Methods](?#methods)
|
||||
* [Class Methods](?#class-methods)
|
||||
* [Accessors](?#accessors)
|
||||
|
||||
### Usage
|
||||
|
||||
The ProMotion logger handles debugging and informational output to the REPL. It is accessible from ProMotion.logger or PM.logger. You can also set a new logger by setting `PM.logger = MyLogger.new`.
|
||||
|
||||
```ruby
|
||||
def some_method
|
||||
PM.logger.error "My error"
|
||||
PM.logger.deprecated "Deprecation warning"
|
||||
PM.logger.warn "My warning"
|
||||
PM.logger.debug @some_object
|
||||
PM.logger.info "Some info #{@object}"
|
||||
PM.logger.log("My Custom Error", "My Message", :red)
|
||||
end
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
#### log(label, message_text, color)
|
||||
|
||||
Output a colored console message.
|
||||
|
||||
```ruby
|
||||
PM.logger.log("TESTING", "This is red!", :red)
|
||||
```
|
||||
|
||||
#### error(message)
|
||||
|
||||
Output a red colored console error.
|
||||
|
||||
```ruby
|
||||
PM.logger.error("This is an error")
|
||||
```
|
||||
|
||||
#### deprecated(message)
|
||||
|
||||
Output a yellow colored console deprecated.
|
||||
|
||||
```ruby
|
||||
PM.logger.deprecated("This is a deprecation warning.")
|
||||
```
|
||||
|
||||
#### warn(message)
|
||||
|
||||
Output a yellow colored console warning.
|
||||
|
||||
```ruby
|
||||
PM.logger.warn("This is a warning")
|
||||
```
|
||||
|
||||
#### debug(message)
|
||||
|
||||
Output a purple colored console debug message.
|
||||
|
||||
```ruby
|
||||
PM.logger.debug(@some_var)
|
||||
```
|
||||
|
||||
#### info(message)
|
||||
|
||||
Output a green colored console info message.
|
||||
|
||||
```ruby
|
||||
PM.logger.info("This is an info message")
|
||||
```
|
||||
|
||||
### Class Methods
|
||||
|
||||
**None.**
|
||||
|
||||
### Accessors
|
||||
|
||||
**None.**
|
||||
3
docs/API Reference - ProMotion MapScreen.md
Normal file
3
docs/API Reference - ProMotion MapScreen.md
Normal file
@@ -0,0 +1,3 @@
|
||||
**Note: PM::MapScreen has been extracted into its own gem, [ProMotion-map](https://github.com/clearsightstudio/ProMotion-map)**.
|
||||
|
||||
View documentation: https://github.com/clearsightstudio/ProMotion-map/blob/master/README.md
|
||||
3
docs/API Reference - ProMotion PushNotification.md
Normal file
3
docs/API Reference - ProMotion PushNotification.md
Normal file
@@ -0,0 +1,3 @@
|
||||
ProMotion::PushNotification has been extracted into the new [ProMotion-push](https://github.com/clearsightstudio/ProMotion-push) add-on gem.
|
||||
|
||||
Documentation: https://github.com/clearsightstudio/ProMotion-push/blob/master/README.md
|
||||
458
docs/API Reference - ProMotion Screen.md
Normal file
458
docs/API Reference - ProMotion Screen.md
Normal file
@@ -0,0 +1,458 @@
|
||||
### Contents
|
||||
|
||||
* [Usage](?#usage)
|
||||
* [Methods](?#methods)
|
||||
* [Class Methods](?#class-methods)
|
||||
* [Accessors](?#accessors)
|
||||
|
||||
### Usage
|
||||
|
||||
PM::Screen is the primary object in ProMotion and a subclass of UIViewController. It adds some abstraction to make your life easier while still allowing the full power of a UIViewController.
|
||||
|
||||
```ruby
|
||||
class HomeScreen < PM::Screen
|
||||
title "Home"
|
||||
tab_bar_item item: "home-screen-tab", title: "Home"
|
||||
status_bar :light
|
||||
|
||||
def on_load
|
||||
# set up subviews here
|
||||
add MyCustomView, frame: [[ 50, 50 ], [ 100, 100 ]]
|
||||
set_nav_bar_button :right, title: "Next", action: :go_to_next
|
||||
end
|
||||
|
||||
# custom method, triggered by tapping right nav bar button set above
|
||||
def go_to_next
|
||||
open NextScreen # opens in same navigation controller, assuming we're in one
|
||||
end
|
||||
|
||||
def will_appear
|
||||
# just before the view appears
|
||||
end
|
||||
|
||||
def on_appear
|
||||
# just after the view appears
|
||||
end
|
||||
|
||||
def will_disappear
|
||||
# just before the view disappears
|
||||
end
|
||||
|
||||
def on_disappear
|
||||
# just after the view disappears
|
||||
end
|
||||
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Methods
|
||||
|
||||
#### modal?
|
||||
|
||||
Returns if the screen was opened in a modal window.
|
||||
|
||||
```ruby
|
||||
m = ModalScreen.new
|
||||
open_modal m
|
||||
m.modal? # => true
|
||||
```
|
||||
|
||||
#### nav_bar?
|
||||
|
||||
Returns if the screen is currently contained in a navigation controller.
|
||||
|
||||
```ruby
|
||||
open s = HomeScreen.new(nav_bar: true)
|
||||
s.nav_bar? # => true
|
||||
```
|
||||
|
||||
#### will_appear
|
||||
|
||||
Runs before the screen appears.
|
||||
|
||||
```ruby
|
||||
def will_appear
|
||||
# just before the screen appears
|
||||
end
|
||||
```
|
||||
|
||||
#### on_appear
|
||||
|
||||
Runs when the screen has appeared.
|
||||
|
||||
```ruby
|
||||
def on_appear
|
||||
# screen has just appeared
|
||||
end
|
||||
```
|
||||
|
||||
#### will_present
|
||||
|
||||
Runs just before the screen is pushed onto the navigation controller.
|
||||
|
||||
```ruby
|
||||
def will_present
|
||||
# About to present
|
||||
end
|
||||
```
|
||||
|
||||
#### on_present
|
||||
|
||||
Runs just after the screen is pushed onto the navigation controller.
|
||||
|
||||
```ruby
|
||||
def on_present
|
||||
# Presented
|
||||
end
|
||||
```
|
||||
|
||||
#### will_disappear
|
||||
|
||||
Runs just before the screen disappears.
|
||||
|
||||
#### will_dismiss
|
||||
|
||||
Runs just before the screen is removed from its parent. Usually happens when getting popped off a navigation controller stack.
|
||||
|
||||
#### on_dismiss
|
||||
|
||||
Runs just after the screen is removed from its parent.
|
||||
|
||||
#### will_rotate(orientation, duration)
|
||||
|
||||
Runs just before the screen rotates.
|
||||
|
||||
#### set_nav_bar_button(side, args = {})
|
||||
|
||||
Set a nav bar button. `args` can be `image:`, `title:`, `system_item:`, `button:`, `custom_view:`.
|
||||
|
||||
You can also set arbitrary attributes in the hash and they'll be applied to the button.
|
||||
|
||||
```ruby
|
||||
set_nav_bar_button :left, {
|
||||
title: "Button Title",
|
||||
image: UIImage.imageNamed("left-nav"),
|
||||
system_item: :reply,
|
||||
tint_color: UIColor.blueColor,
|
||||
button: UIBarButtonItem.initWithTitle("My button", style: UIBarButtonItemStyleBordered, target: self, action: :tapped_button) # for custom button
|
||||
}
|
||||
```
|
||||
|
||||
`system_item` can be a `UIBarButtonSystemItem` or one of the following symbols:
|
||||
```ruby
|
||||
:done,:cancel,:edit,:save,:add,:flexible_space,:fixed_space,:compose,
|
||||
:reply,:action,:organize,:bookmarks,:search,:refresh,:stop,:camera,
|
||||
:trash,:play,:pause,:rewind,:fast_forward,:undo,:redo,:page_curl
|
||||
```
|
||||
|
||||
`custom_view` can be any custom `UIView` subclass you initialize yourself
|
||||
|
||||
Another example with arbitrary attributes:
|
||||
|
||||
```ruby
|
||||
set_nav_bar_button :right, {
|
||||
system_item: :add,
|
||||
action: :add_item,
|
||||
accessibility_label: "add item",
|
||||
background_color: UIImage.imageNamed("some-image")
|
||||
}
|
||||
```
|
||||
|
||||
And finally, you can also set the `:back` nav bar image on a screen and it will render a back arrow icon in the upper left part of the navigation. However, note that doing so will change the back button for all descendants of the screen you set the button on. This behavior is a little unintuitive, but is a result of the underlying Cocoa Touch APIs. For example:
|
||||
|
||||
```ruby
|
||||
class MyScreen < PM::Screen
|
||||
def on_init
|
||||
set_nav_bar_button :back, title: 'Cancel', style: :plain, action: :back
|
||||
end
|
||||
|
||||
def go_to_next_screen
|
||||
open MyScreenChild
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
The code above will add a "cancel" back button to `MyScreenChild` when it is opened as a descendant of `MyScreen`.
|
||||
|
||||
#### set_toolbar_items(buttons = [], animated = true)
|
||||
|
||||
Uses an array to set the navigation controllers toolbar items and shows the toolbar. Uses the same hash formatted parameters as `set_nav_bar_button`. When calling this method, the toolbar will automatically be shown (even if the screen was created without a toolbar). Use the `animated` parameter to specify if the toolbar showing should be animated or not.
|
||||
|
||||
```ruby
|
||||
# Will arrange one button on the left and another on the right
|
||||
set_toolbar_items [{
|
||||
title: "Button Title",
|
||||
action: :some_action
|
||||
}, {
|
||||
system_item: :flexible_space
|
||||
}, {
|
||||
title: "Another ButtonTitle",
|
||||
action: :some_other_action,
|
||||
target: some_other_object
|
||||
}]
|
||||
```
|
||||
|
||||
You can also pass your own initialized `UIBarButtonItem` as part of the array (instead of a hash object).
|
||||
|
||||
_EDGE FEATURE:_ You can pass `tint_color` with a `UIColor` to change the tint color of the button item.
|
||||
|
||||
#### title
|
||||
|
||||
Returns title of current screen.
|
||||
|
||||
```ruby
|
||||
class MyScreen < PM::Screen
|
||||
title "Mine"
|
||||
def on_load
|
||||
self.title # => "Mine"
|
||||
end
|
||||
```
|
||||
|
||||
#### title=(title)
|
||||
|
||||
Sets the text title of current screen instance.
|
||||
|
||||
```ruby
|
||||
class SomeScreen
|
||||
def on_load
|
||||
# This sets this instance's title
|
||||
title = "Something else"
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
#### app_delegate
|
||||
|
||||
Returns the AppDelegate. Alias of `UIApplication.sharedApplication.delegate`.
|
||||
|
||||
#### close(args = {})
|
||||
|
||||
Closes the current screen, passes `args` back to the previous screen's `on_return` method (if it exists).
|
||||
|
||||
```ruby
|
||||
class ChildScreen < PM::Screen
|
||||
def save_and_close
|
||||
save
|
||||
close({ saved: true })
|
||||
end
|
||||
end
|
||||
|
||||
class ParentScreen < PM::Screen
|
||||
def on_return(args={})
|
||||
if args[:saved]
|
||||
reload_data
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
If you want to close back to the root screen or any other screen in the navigation stack, use `to_screen:`:
|
||||
|
||||
```ruby
|
||||
class ChildScreen < PM::Screen
|
||||
def close_to_root
|
||||
close to_screen: self.navigation_controller.viewControllers.first
|
||||
# For the rootViewController, you can just use `:root`
|
||||
close to_screen: :root
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
#### open_root_screen(screen)
|
||||
|
||||
Closes all other open screens and opens `screen` as the root view controller.
|
||||
|
||||
```ruby
|
||||
def reset_this_app
|
||||
open_root_screen HomeScreen
|
||||
end
|
||||
```
|
||||
|
||||
#### open(screen, args = {})
|
||||
|
||||
Opens a screen, intelligently determining the context.
|
||||
|
||||
**Examples:**
|
||||
|
||||
```ruby
|
||||
# In app delegate
|
||||
open HomeScreen.new(nav_bar: true)
|
||||
|
||||
# In tab bar
|
||||
open HomeScreen.new(nav_bar: true), hide_tab_bar: true
|
||||
|
||||
# `modal: true` is the same as `open_modal`.
|
||||
open ModalScreen.new(nav_bar: true), modal: true, animated: true
|
||||
|
||||
# Opening a modal screen with transition or presentation styles
|
||||
open_modal ModalScreen.new(nav_bar: true,
|
||||
transition_style: UIModalTransitionStyleFlipHorizontal,
|
||||
presentation_style: UIModalPresentationFormSheet)
|
||||
|
||||
# From any screen (same as `open_root_screen`)
|
||||
open HomeScreen.new(nav_bar: true), close_all: true
|
||||
|
||||
# Opening a screen in a different tab or split view screen
|
||||
open DetailScreen.new, in_tab: "Tab name" # if you're in a tab bar
|
||||
open MasterScreen, in_master: true # if you're in a split view (opened in current navigation controller if not)
|
||||
open DetailScreen, in_detail: true # if you're in a split view (opened in current navigation controller if not)
|
||||
|
||||
# Opening a screen with a custom navigation_controller class. (Defaults to PM::NavigationController)
|
||||
class MyNavigationController < PM::NavigationController; end
|
||||
open HomeScreen.new(nav_bar: true, nav_controller: MyNavigationController), close_all: true
|
||||
|
||||
# Opens a screen with a navigation controller but with the navigation bar hidden
|
||||
open HomeScreen.new(nav_bar: true, hide_nav_bar: true) # Edge feature
|
||||
```
|
||||
|
||||
##### Setting screen accessors
|
||||
|
||||
Any writable attribute (accessor, setter methods etc.) in `screen` can also be set in the `new` hash argument.
|
||||
|
||||
```ruby
|
||||
class HomeScreen < PM::Screen
|
||||
def profile_button_tapped
|
||||
open ProfileScreen.new(user: @current_user)
|
||||
end
|
||||
end
|
||||
|
||||
class ProfileScreen < PM::Screen
|
||||
attr_accessor :user
|
||||
|
||||
def on_load
|
||||
puts user # => @current_user object
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
#### open_modal(screen, args = {})
|
||||
|
||||
Opens a modal screen. Same as `open HomeScreen, modal: true`
|
||||
|
||||
#### should_autorotate
|
||||
|
||||
(iOS 6+) return true/false if screen should rotate.
|
||||
Defaults to true.
|
||||
|
||||
#### should_rotate(orientation)
|
||||
|
||||
(iOS 5) Return true/false for rotation to orientation. Tries to resolve this automatically
|
||||
from your `UISupportedInterfaceOrientations` setting. You normally don't override this method.
|
||||
|
||||
#### supported_orientation?(orientation)
|
||||
|
||||
Returns whether `UISupportedInterfaceOrientations` includes the given orientation.
|
||||
|
||||
```ruby
|
||||
supported_orientation?(UIInterfaceOrientationMaskPortrait)
|
||||
supported_orientation?(UIInterfaceOrientationMaskLandscapeLeft)
|
||||
supported_orientation?(UIInterfaceOrientationMaskLandscapeRight)
|
||||
supported_orientation?(UIInterfaceOrientationMaskPortraitUpsideDown)
|
||||
```
|
||||
|
||||
#### supported_orientations
|
||||
|
||||
Returns the value for `UISupportedInterfaceOrientations`.
|
||||
|
||||
#### will_rotate(orientation, duration)
|
||||
|
||||
Runs just before the device is rotated.
|
||||
|
||||
#### on_rotate
|
||||
|
||||
Runs just after the device is rotated.
|
||||
|
||||
#### supported_device_families
|
||||
|
||||
Returns either `:iphone` or `:ipad`. Should probably be named `current_device_family` or something.
|
||||
|
||||
#### first_screen?
|
||||
|
||||
Boolean representing if this is the first screen in a navigation controller stack.
|
||||
|
||||
```ruby
|
||||
def on_appear
|
||||
self.first_screen? # => true | false
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Class Methods
|
||||
|
||||
#### title(new_title)
|
||||
|
||||
Sets the default text title for all of this screen's instances
|
||||
|
||||
```ruby
|
||||
class MyScreen < PM::Screen
|
||||
title "Some screen"
|
||||
# ...
|
||||
end
|
||||
```
|
||||
|
||||
#### title_view(new_title_view)
|
||||
|
||||
Sets an arbitrary view as the nav bar title.
|
||||
|
||||
```ruby
|
||||
class MyScreen < PM::Screen
|
||||
title_view UILabel.new
|
||||
# ...
|
||||
end
|
||||
```
|
||||
|
||||
#### title_image(new_image)
|
||||
|
||||
Sets an arbitrary image as the nav bar title.
|
||||
|
||||
```ruby
|
||||
class MyScreen < PM::Screen
|
||||
title_image "image.png"
|
||||
# ...
|
||||
end
|
||||
```
|
||||
|
||||
#### status_bar(style=nil, args={animation: UIStatusBarAnimationSlide})
|
||||
|
||||
Set the properties of the applications' status bar. Options for style are: `:none`, `:light` and `:default`. The animation argument should be a `UIStatusBarAnimation` (or `:none` / `:fade` / `:slide`) and is used to hide or show the status bar when appropriate and defaults to `:slide`.
|
||||
|
||||
```ruby
|
||||
class MyScreen < PM::Screen
|
||||
status_bar :none, {animation: :fade}
|
||||
# ...
|
||||
end
|
||||
|
||||
class MyScreenWithADarkColoredNavBar < PM::Screen
|
||||
status_bar :light
|
||||
# ...
|
||||
end
|
||||
```
|
||||
---
|
||||
|
||||
### Accessors
|
||||
|
||||
#### parent_screen
|
||||
|
||||
References the screen immediately before this one in a navigation controller *or* the presenting
|
||||
screen for modals. You should set this yourself if you're doing something funky like `addChildViewController`.
|
||||
|
||||
```ruby
|
||||
def on_appear
|
||||
self.parent_screen # => PM::Screen instance
|
||||
end
|
||||
```
|
||||
|
||||
#### view
|
||||
|
||||
The main view for this screen.
|
||||
|
||||
#### bounds
|
||||
|
||||
Alias for self.view.bounds
|
||||
|
||||
#### frame
|
||||
|
||||
Alias for self.view.frame
|
||||
69
docs/API Reference - ProMotion SplitScreen.md
Normal file
69
docs/API Reference - ProMotion SplitScreen.md
Normal file
@@ -0,0 +1,69 @@
|
||||
### Contents
|
||||
|
||||
* [Usage](?#usage)
|
||||
* [Methods](?#methods)
|
||||
* [Class Methods](?#class-methods)
|
||||
* [Accessors](?#accessors)
|
||||
|
||||
### Usage
|
||||
|
||||
```ruby
|
||||
class AppDelegate < PM::Delegate
|
||||
def on_load(app, options)
|
||||
open_split_screen MenuScreen.new(nav_bar: true), DetailScreen.new
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
#### open_split_screen(master, detail, args = {})
|
||||
|
||||
*iPad apps only*
|
||||
Opens a UISplitScreenViewController with the specified screens. Usually opened in the AppDelegate as the root view controller.
|
||||
|
||||
```ruby
|
||||
def on_load(app, options)
|
||||
open_split_screen MasterScreen, DetailScreen, {
|
||||
item: "split-icon", # tab bar item
|
||||
title: "Split Screen Title",
|
||||
button_title: "Some other title"
|
||||
}
|
||||
end
|
||||
```
|
||||
|
||||
#### create_split_screen(master, detail, args={})
|
||||
|
||||
Creates a `PM::SplitViewController` (a `UIViewController` subclass) and returns it. Good for tabbed interfaces.
|
||||
|
||||
```ruby
|
||||
def on_load(app, options)
|
||||
@split = create_split_screen(MenuScreen.new(nav_bar: true), DetailScreen)
|
||||
open_tab_screen @split, AboutScreen, ContactScreen
|
||||
end
|
||||
```
|
||||
|
||||
### Class Methods
|
||||
|
||||
*None for this module*
|
||||
|
||||
### Accessors
|
||||
|
||||
#### split_screen
|
||||
|
||||
References the containing split screen, if any.
|
||||
|
||||
```ruby
|
||||
# in AppDelegate#on_load...
|
||||
open_split_screen LeftScreen, RightScreen
|
||||
|
||||
# ...
|
||||
|
||||
class LeftScreen < PM::Screen
|
||||
def on_appear
|
||||
self.split_screen # => PM::SplitViewController instance
|
||||
self.split_screen.master_screen # => LeftScreen
|
||||
self.split_screen.detail_screen # => RightScreen
|
||||
end
|
||||
end
|
||||
```
|
||||
116
docs/API Reference - ProMotion Styling.md
Normal file
116
docs/API Reference - ProMotion Styling.md
Normal file
@@ -0,0 +1,116 @@
|
||||
PM::Styling is automatically included in many of the objects in ProMotion, such as `PM::Screen`, `PM::TableScreen`, and `PM::Delegate`. It gives you a simple way to apply a hash of attributes and values to a view (or any object that has setters, actually).
|
||||
|
||||
PM::Styling is *not* meant to be a full featured styling system. For that, you should use MotionKit or RMQ or some other styling system. This is just for simple applications.
|
||||
|
||||
### Contents
|
||||
|
||||
* [Usage](?#usage)
|
||||
* [Methods](?#methods)
|
||||
* [Class Methods](?#class-methods)
|
||||
* [Accessors](?#accessors)
|
||||
|
||||
### Usage
|
||||
|
||||
```ruby
|
||||
class MyScreen < PM::Screen
|
||||
def on_load
|
||||
set_attributes self.view, {
|
||||
background_color: hex_color("#FB3259")
|
||||
}
|
||||
add UILabel.new, {
|
||||
text: "My text",
|
||||
frame: [[ 50, 150 ], [ 200, 50 ]],
|
||||
background_color: rgba_color(32, 32, 32, 0.5)
|
||||
}
|
||||
add UIButton.new, {
|
||||
frame: [[ 50, 250 ], [ 200, 50 ]],
|
||||
"setTitle:forState:" => [ "My title", UIControlStateNormal ]
|
||||
}
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
#### add(view, attrs = {})
|
||||
|
||||
Adds the view to the screen after applying the attributes. Attributes are converted to camel case if necessary. `attrs` is usually either a hash, method call that returns a hash, or the name of a method call (in the form of a `:symbol`) that returns the hash.
|
||||
|
||||
```ruby
|
||||
add UIInputView.new, {
|
||||
background_color: UIColor.grayColor,
|
||||
accessibility_label: "My input view",
|
||||
frame: CGRectMake(10, 10, 300, 40)
|
||||
}
|
||||
|
||||
# or use a symbol which calls a method
|
||||
def my_input_style
|
||||
{
|
||||
background_color: UIColor.grayColor,
|
||||
accessibility_label: "My input view",
|
||||
frame: [[10, 10], [300, 40]],
|
||||
}
|
||||
end
|
||||
|
||||
add UIInputView.new, :my_input_style # will call my_input_style to get the hash
|
||||
```
|
||||
|
||||
#### remove(view)
|
||||
|
||||
Removes the view from the superview.
|
||||
|
||||
```ruby
|
||||
@input = UITextInput.new
|
||||
add @input
|
||||
remove @input
|
||||
```
|
||||
|
||||
#### hex_color(str)
|
||||
|
||||
Creates a UIColor from a hex string. The # is optional.
|
||||
|
||||
```ruby
|
||||
hex_color("#75D155") # => UIColor instance
|
||||
```
|
||||
|
||||
#### rgb_color(r, g, b)
|
||||
|
||||
Creates a UIColor from red, green, and blue levels.
|
||||
|
||||
```ruby
|
||||
rgb_color(23, 54, 21)
|
||||
```
|
||||
|
||||
#### rgba_color(r, g, b, a)
|
||||
|
||||
Creates a UIColor with alpha setting from red, green, blue, and alpha levels.
|
||||
|
||||
```ruby
|
||||
rgba_color(23, 54, 21, 0.25)
|
||||
```
|
||||
|
||||
#### content_height(view)
|
||||
|
||||
Returns the height necessary to contain all of the visible subviews for `view`.
|
||||
|
||||
```ruby
|
||||
add UILabel.new, { frame: [[ 0, 0 ], [ 150, 100 ]]
|
||||
content_height(self.view) # => 100
|
||||
```
|
||||
|
||||
#### content_width(view) - `edge`
|
||||
|
||||
Returns the width necessary to contain all of the visible subviews for `view`.
|
||||
|
||||
```ruby
|
||||
add UILabel.new, { frame: [[ 0, 0 ], [ 150, 100 ]]
|
||||
content_width(self.view) # => 150
|
||||
```
|
||||
|
||||
### Class Methods
|
||||
|
||||
*None for this module*
|
||||
|
||||
### Accessors
|
||||
|
||||
*None for this module*
|
||||
81
docs/API Reference - ProMotion Table - Cell Options.md
Normal file
81
docs/API Reference - ProMotion Table - Cell Options.md
Normal file
@@ -0,0 +1,81 @@
|
||||
<strong>Customizing:</strong> if you're getting crazy deep into styling your table cells,
|
||||
you really should be subclassing them and specifying that new class in <code>:cell_class</code>. But, if you *really* want to know what ProMotion can do, here's an example format using nearly all available options:
|
||||
|
||||
```ruby
|
||||
def table_data
|
||||
[{
|
||||
title: "Group Title",
|
||||
title_view: MyCustomSection,
|
||||
title_view_height: 50,
|
||||
cells: [{
|
||||
# Title
|
||||
title: "Full featured cell",
|
||||
subtitle: "This is my subtitle",
|
||||
|
||||
# Search: you can specify additional search terms
|
||||
search_text: "Will match title and these words too!",
|
||||
|
||||
# Tap action, passed arguments
|
||||
action: :tapped_cell_1,
|
||||
long_press_action: :long_pressed_cell_1, # requires `longpressable`
|
||||
arguments: { data: [ "lots", "of", "data" ] },
|
||||
|
||||
# The UITableViewCell
|
||||
cell_style: UITableViewCellStyleSubtitle,
|
||||
cell_identifier: "my-custom-cell-id", # ProMotion sets this for you intelligently
|
||||
cell_class: PM::TableViewCell,
|
||||
selection_style: UITableViewCellSelectionStyleGray, # or: :none, :blue, :gray, :default
|
||||
|
||||
# View attributes.
|
||||
height: 50, # manually changes the cell's height
|
||||
|
||||
# Cell properties. You can add any writeable properties you want in here and they'll
|
||||
# be applied to the cell instance with `set_attributes`.
|
||||
# Alias is `style:` (but this is discouraged and could be deprecated at some point)
|
||||
properties: { # (Edge change, use `style:` in ProMotion 2.0.x)
|
||||
masks_to_bounds: true,
|
||||
background_color: UIColor.whiteColor, # Creates a UIView for the backgroundView
|
||||
},
|
||||
|
||||
# Accessory views (new in 1.0)
|
||||
accessory: {
|
||||
view: :switch, # UIView or :switch
|
||||
value: true, # whether it's "checked" or not
|
||||
action: :accessory_switched,
|
||||
arguments: { some_arg: true } # :value is passed in if a hash
|
||||
},
|
||||
|
||||
# Accessory Type
|
||||
# Sets the UITableViewCell's accessoryType property
|
||||
# Accepts UITableViewCellAccessory or any of the following symbols:
|
||||
# :none, :disclosure_indicator, :disclosure_button, :checkmark, :default
|
||||
accessory_type: :none,
|
||||
|
||||
# Swipe-to-delete
|
||||
editing_style: :delete, # (can be :delete, :insert, or :none)
|
||||
|
||||
# Moveable Cell
|
||||
moveable: true # can also be false or :section
|
||||
|
||||
# Selection
|
||||
keep_selection: true, # specifies whether the cell automatically deselects after touch or not
|
||||
|
||||
# Images
|
||||
image: {
|
||||
image: "something", # PM will do `UIImage.imageNamed("something")` for you
|
||||
radius: 15 # radius is optional
|
||||
},
|
||||
# You can also specify an image with just a UIImage or a String
|
||||
# image: UIImage.imageNamed("something"),
|
||||
# image: "something",
|
||||
remote_image: { # remote image, requires JMImageCache CocoaPod
|
||||
url: "http://placekitten.com/200/300",
|
||||
placeholder: "some-local-image", # NOTE: this is required!
|
||||
size: 50,
|
||||
radius: 15,
|
||||
content_mode: :scale_aspect_fill
|
||||
}
|
||||
}]
|
||||
}]
|
||||
end
|
||||
```
|
||||
417
docs/API Reference - ProMotion TableScreen.md
Normal file
417
docs/API Reference - ProMotion TableScreen.md
Normal file
@@ -0,0 +1,417 @@
|
||||
### Contents
|
||||
|
||||
* [Usage](?#usage)
|
||||
* [Methods](?#methods)
|
||||
* [Class Methods](?#class-methods)
|
||||
* [Accessors](?#accessors)
|
||||
|
||||
### Usage
|
||||
|
||||
ProMotion::TableScreen allows you to easily create lists or "tables" as iOS calls them. It's a subclass of [UITableViewController](http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewController_Class/Reference/Reference.html) and has all the goodness of [PM::Screen](https://github.com/clearsightstudio/ProMotion/wiki/API-Reference:-ProMotion::Screen) with some additional magic to make the tables work beautifully.
|
||||
|
||||
|Table Screens|Grouped Tables|Searchable|Refreshable|
|
||||
|---|---|---|---|
|
||||
|||||
|
||||
|
||||
```ruby
|
||||
class TasksScreen < PM::TableScreen
|
||||
title "Tasks"
|
||||
refreshable
|
||||
searchable placeholder: "Search tasks"
|
||||
row_height :auto, estimated: 44
|
||||
|
||||
def on_load
|
||||
@tasks = []
|
||||
load_async
|
||||
end
|
||||
|
||||
def table_data
|
||||
[{
|
||||
cells: @tasks.map do |task|
|
||||
{
|
||||
title: task.title,
|
||||
subtitle: task.description,
|
||||
action: :edit_task,
|
||||
arguments: { task: task }
|
||||
}
|
||||
end
|
||||
}]
|
||||
end
|
||||
|
||||
def on_refresh
|
||||
load_async
|
||||
end
|
||||
|
||||
def load_async
|
||||
# Assuming we're loading tasks from some cloud service
|
||||
Task.async_load do |tasks|
|
||||
@tasks = tasks
|
||||
stop_refreshing
|
||||
update_table_data
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Example of a `PM::GroupedTableScreen`: https://gist.github.com/jamonholmgren/382a6cf9963c5f0b2248
|
||||
|
||||
### Methods
|
||||
|
||||
#### table_data
|
||||
|
||||
Method that is called to get the table's cell data and build the table.
|
||||
|
||||
It consists of an array of cell sections, each of which contain an array of cells.
|
||||
|
||||
```ruby
|
||||
def table_data
|
||||
[{
|
||||
title: "Northwest States",
|
||||
cells: [
|
||||
{ title: "Oregon", action: :visit_state, arguments: { state: @oregon }},
|
||||
{ title: "Washington", action: :visit_state, arguments: { state: @washington }}
|
||||
]
|
||||
}]
|
||||
end
|
||||
```
|
||||
|
||||
You'll often be iterating through a group of objects. You can use `.map` to easily build your table:
|
||||
|
||||
```ruby
|
||||
def table_data
|
||||
[{
|
||||
title: "States",
|
||||
cells:
|
||||
State.all.map do |state|
|
||||
{
|
||||
title: state.name,
|
||||
action: :visit_state,
|
||||
arguments: { state: state }
|
||||
}
|
||||
end
|
||||
}]
|
||||
end
|
||||
|
||||
def visit_state(args={})
|
||||
PM.logger.info args[:state] # => instance of State
|
||||
end
|
||||
```
|
||||
|
||||
View the [Reference: All available table_data options](https://github.com/clearsightstudio/ProMotion/wiki/Reference:-All-available-table_data-options) for an example with all available options.
|
||||
|
||||
#### Accessory Views
|
||||
|
||||
`TableScreen` supports the `:switch` accessory and custom accessory views.
|
||||
|
||||

|
||||
|
||||
Using Switches:
|
||||
|
||||
```ruby
|
||||
{
|
||||
title: "Switch With Action",
|
||||
accessory: {
|
||||
view: :switch,
|
||||
value: true, # switched on
|
||||
action: :foo
|
||||
}
|
||||
}, {
|
||||
title: "Switch with Action and Parameters",
|
||||
accessory: {
|
||||
view: :switch,
|
||||
action: :foo,
|
||||
arguments: { bar: 12 }
|
||||
}
|
||||
}, {
|
||||
title: "Switch with Cell Tap, Switch Action and Parameters",
|
||||
accessory: {
|
||||
view: :switch,
|
||||
action: :foo,
|
||||
arguments: { bar: 3 },
|
||||
},
|
||||
action: :fizz,
|
||||
arguments: { buzz: 10 }
|
||||
}
|
||||
```
|
||||
|
||||
Using a custom `accessory` view:
|
||||
|
||||
```ruby
|
||||
button1 = set_attributes UIButton.buttonWithType(UIButtonTypeRoundedRect), {
|
||||
"setTitle:forState:" => [ "A", UIControlStateNormal ]
|
||||
}
|
||||
button2 = set_attributes UIButton.buttonWithType(UIButtonTypeRoundedRect), {
|
||||
"setTitle:forState:" => [ "B", UIControlStateNormal ]
|
||||
}
|
||||
button1.frame = [[ 0, 0 ], [ 20, 20 ]]
|
||||
button2.frame = [[ 0, 0 ], [ 20, 20 ]]
|
||||
[{
|
||||
title: "",
|
||||
cells: [{
|
||||
title: "My Cell with custom button",
|
||||
accessory: { view: button1 }
|
||||
}, {
|
||||
title: "My Second Cell with another custom button",
|
||||
accessory: { view: button2 }
|
||||
}]
|
||||
}]
|
||||
```
|
||||
|
||||
*However*, adding custom accessory views like this is not recommended unless your use case is very simple. Instead, subclass `PM::TableViewCell` and provide setters that create the subviews or accessoryView that you want. You can find a blog post demonstrating how this is done here: http://jamonholmgren.com/creating-a-custom-uitableviewcell-with-promotion
|
||||
|
||||
#### update_table_data
|
||||
|
||||
Causes the table data to be refreshed, such as when a remote data source has
|
||||
been downloaded and processed.
|
||||
|
||||
```ruby
|
||||
class MyTableScreen < PM::TableScreen
|
||||
|
||||
def on_load
|
||||
MyItem.pull_from_server do |items|
|
||||
@table_data = [{
|
||||
cells: items.map do |item|
|
||||
{
|
||||
title: item.name,
|
||||
action: :tapped_item,
|
||||
arguments: { item: item }
|
||||
}
|
||||
end
|
||||
}]
|
||||
|
||||
update_table_data
|
||||
end
|
||||
end
|
||||
|
||||
def table_data
|
||||
@table_data ||= []
|
||||
end
|
||||
|
||||
def tapped_item(item)
|
||||
open ItemDetailScreen.new(item: item)
|
||||
end
|
||||
|
||||
end
|
||||
```
|
||||
|
||||
#### table_data_index
|
||||
|
||||
This method allows you to create a "jumplist", the index on the right side of the table
|
||||
|
||||
A good way to do this is to grab the first letter of the title of each section:
|
||||
|
||||
```ruby
|
||||
def table_data_index
|
||||
# Returns an array of the first letter of the title of each section.
|
||||
table_data.collect{ |section| (section[:title] || " ")[0] }
|
||||
end
|
||||
```
|
||||
|
||||
#### on_cell_deleted(cell)
|
||||
|
||||
If you specify `editing_style: :delete` in your cell, you can swipe to reveal a delete button on that cell. When you tap the button, the cell will be removed in an animated fashion and the cell will be removed from its respective `table_data` section.
|
||||
|
||||
If you need a callback for every cell that's deleted, you can implement the `on_cell_deleted(cell)` method, where `cell` is the attributes form the original cell data object. Returning `false` will cancel the delete action. Anything else will allow it to proceed.
|
||||
|
||||
Example:
|
||||
|
||||
```ruby
|
||||
def on_cell_deleted(cell)
|
||||
if cell[:arguments][:some_value] == "something"
|
||||
App.alert "Sorry, can't delete that row." # BubbleWrap alert
|
||||
false
|
||||
else
|
||||
RemoteObject.find(cell[:arguments][:id]).delete_remotely
|
||||
true # return anything *but* false to allow deletion in the UI
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
#### delete_row(indexpath, animation=nil)
|
||||
|
||||
You can call `delete_row(indexpath, animation)` to delete. Both the UI and the internal
|
||||
data hash are updated when you do this.
|
||||
|
||||
```ruby
|
||||
def my_delete_method(section, row)
|
||||
# the 2nd argument is optional. Defaults to :automatic
|
||||
delete_row(NSIndexPath.indexPathForRow(row, inSection:section), :fade)
|
||||
end
|
||||
```
|
||||
|
||||
#### table_header_view
|
||||
|
||||
You can give the table a custom header view (this is different from a section header view) by defining:
|
||||
|
||||
```ruby
|
||||
def table_header_view
|
||||
# Return a UIView subclass here and it will be set at the top of the table.
|
||||
end
|
||||
```
|
||||
|
||||
This is useful for information that needs to only be at the very top of a table.
|
||||
|
||||
---
|
||||
|
||||
### Class Methods
|
||||
|
||||
#### searchable(placeholder: "placeholder text")
|
||||
|
||||
Class method to make the current table searchable.
|
||||
|
||||
```ruby
|
||||
class MyTableScreen < PM::TableScreen
|
||||
searchable placeholder: "Search This Table"
|
||||
end
|
||||
```
|
||||
|
||||

|
||||
|
||||
You can prevent any table cell from being included in search results by setting the cell attribute `searchable` to `false` like this:
|
||||
|
||||
```ruby
|
||||
[{
|
||||
title: "This cell will appear in the search",
|
||||
},{
|
||||
title: "This cell will not",
|
||||
searchable: false
|
||||
}]
|
||||
```
|
||||
|
||||
You can supply additional textual data that you want to be searchable but not display anywhere on the cell by setting the cell attribute `search_text` to a string. Cells with `search_text` will display in search results if the search term matches either the `title` *or* the `search_text` attributes.
|
||||
|
||||
```ruby
|
||||
[{
|
||||
title: "Searchable via Title"
|
||||
},{
|
||||
title: "Searchable via Title",
|
||||
search_text: "and will match these words too!"
|
||||
}]
|
||||
```
|
||||
|
||||
If you need to know if the current table screen is being searched, `searching?` will return `true` if the user has entered into the search bar (even if there is no search results yet).
|
||||
|
||||
To get the text that a user has entered into the search bar, you can call `search_string` for what the data was actually searched against and `original_search_string` to get the actual text the user entered. These methods will return back a `String` or a falsey object (`nil` or `false`).
|
||||
|
||||
You can also implement methods in your `TableScreen` that are called when the search starts or ends:
|
||||
|
||||
```ruby
|
||||
def will_begin_search
|
||||
puts "the user tapped the search bar!"
|
||||
end
|
||||
|
||||
def will_end_search
|
||||
puts "the user tapped the 'cancel' button!"
|
||||
end
|
||||
```
|
||||
|
||||
#### row_height(height, options = {})
|
||||
|
||||
Class method to set the row height for each UITableViewCell. You can use iOS 8's 'automatic' row height feature by passing `:auto` as the first argument.
|
||||
|
||||
```ruby
|
||||
class MyTableScreen < PM::TableScreen
|
||||
row_height :auto, estimated: 44
|
||||
end
|
||||
```
|
||||
|
||||
#### refreshable(options = {})
|
||||
|
||||
Class method to make the current table have pull-to-refresh. All parameters are optional.
|
||||
If you do not specify a callback, it will assume you've implemented an <code>on_refresh</code>
|
||||
method in your tableview.
|
||||
|
||||

|
||||
|
||||
```ruby
|
||||
class MyTableScreen < PM::TableScreen
|
||||
|
||||
refreshable callback: :on_refresh,
|
||||
pull_message: "Pull to refresh",
|
||||
refreshing: "Refreshing data…",
|
||||
updated_format: "Last updated at %s",
|
||||
updated_time_format: "%l:%M %p"
|
||||
|
||||
def on_refresh
|
||||
MyItems.pull_from_server do |items|
|
||||
@my_items = items
|
||||
end_refreshing
|
||||
update_table_data
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
```
|
||||
|
||||
If you initiate a refresh event manually by calling `start_refreshing`, the table view will automatically scroll down to reveal the spinner at the top of the table.
|
||||
|
||||
#### indexable
|
||||
|
||||
This simply takes the first letter of each of your section titles and uses those for the "jumplist" on the right side of your table screen.
|
||||
|
||||
```ruby
|
||||
class MyTable < PM::TableScreen
|
||||
indexable
|
||||
|
||||
# ...
|
||||
end
|
||||
```
|
||||
|
||||
#### longpressable
|
||||
|
||||
This will allow you to specify an additional "long_press_action" on your table cells.
|
||||
|
||||
```ruby
|
||||
class MyTable < PM::TableScreen
|
||||
longpressable
|
||||
|
||||
def table_data
|
||||
[{
|
||||
cells: [{
|
||||
title: "Long press cell",
|
||||
action: :normal_action,
|
||||
long_press_action: :long_press_action,
|
||||
arguments: { foo: "Will be sent along with either action as arguments" }
|
||||
}]
|
||||
}]
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Accessors
|
||||
|
||||
You get all the normal accessors of `PM::Screen`, but no documented TableScreen accessors are available.
|
||||
|
||||
---
|
||||
|
||||
### Moveable cells
|
||||
|
||||
You can specify cells to be moveable in each individual cell hash. If you want the cells to only be moveable within their own section, define `moveable: :section` in each cell hash.
|
||||
|
||||
When you want the user to see the moveable drag handles, call `toggle_edit_mode` or `edit_mode(enabled:true)`.
|
||||
|
||||
Finally, define a method:
|
||||
|
||||
```ruby
|
||||
def on_cell_moved(args)
|
||||
# Do something here
|
||||
end
|
||||
```
|
||||
|
||||
The argument passed to `on_cell_moved` is a hash in the form of:
|
||||
|
||||
```ruby
|
||||
{
|
||||
:paths => {
|
||||
:from => #<NSIndexPath:0xb777380>,
|
||||
:to => #<NSIndexPath:0xb777390>
|
||||
},
|
||||
:cell => {
|
||||
:title => "Whatever",
|
||||
:moveable => true
|
||||
# Your other cell attributes
|
||||
}
|
||||
}
|
||||
```
|
||||
78
docs/API Reference - ProMotion Tabs.md
Normal file
78
docs/API Reference - ProMotion Tabs.md
Normal file
@@ -0,0 +1,78 @@
|
||||
`ProMotion::Tabs` is a module that is automatically included in `PM::Delegate` and `PM::Screen`. It includes methods and functionality dealing with `UITabBarController` and `UITabBarItem`.
|
||||
|
||||
* [Methods](?#methods)
|
||||
* [Class Methods](?#class-methods)
|
||||
* [Accessors](?#accessors)
|
||||
|
||||
### Methods
|
||||
|
||||
#### set_tab_bar_item(args)
|
||||
|
||||
**NOTE: `icon` and `system_icon` have been deprecated and replaced by `item` and `system_item`.**
|
||||
|
||||
Creates the tab that is shown in a tab bar item.
|
||||
Arguments: `{ item: "imagename", system_item: UITabBarSystemItemContacts, title: "tabtitle" }`
|
||||
|
||||
`item` can be a string, in which case it should exist in your resources folder. But `item` can also be a UIImage, if you prefer to create one yourself. Additionally, Apple adds a gradient to every `UITabBarItem`. In order to prevent this, or to control the state of the selected & unselected item, you can pass a hash into `item` like so (where variable `myUIImage` is an instance of `UIImage`):
|
||||
|
||||
```ruby
|
||||
set_tab_bar_item { item: { selected: my_image, unselected: my_image }, title: "tabtitle" }
|
||||
```
|
||||
|
||||
It's recommended to use this method in your `on_init` method OR set it using the class method `tab_bar_item` (below). `on_load` won't be called until you actually load the tab, which is too late.
|
||||
|
||||
```ruby
|
||||
def on_init
|
||||
set_tab_bar_item item: "custom_item_5", title: "Custom"
|
||||
set_tab_bar_item system_item: :more
|
||||
# :more, :favorites, :featured, :top_rated, :recents, :contacts,
|
||||
# :history, :bookmarks, :search, :downloads, :most_recent, :most_viewed
|
||||
end
|
||||
```
|
||||
|
||||
#### open_tab_bar(*screens)
|
||||
|
||||
Opens a UITabBarController with the specified screens as the **root view controller** of the current app.
|
||||
iOS doesn't allow opening a UITabBar as a sub-view. The current screen will be deallocated unless included
|
||||
as one of the screens in the tab bar.
|
||||
|
||||
```ruby
|
||||
def on_load(app, options)
|
||||
open_tab_bar HomeScreen, AboutScreen.new(nav_bar: true), ThirdScreen, HelpScreen
|
||||
end
|
||||
```
|
||||
|
||||
#### open_tab(tab)
|
||||
|
||||
Opens the tab where the "string" title matches the passed in `tab` string. You can also
|
||||
provide a number (starting at 0) and the tab with that index will be opened.
|
||||
|
||||
```ruby
|
||||
open_tab "About"
|
||||
|
||||
open_tab 3 # fourth tab is opened
|
||||
```
|
||||
|
||||
### Class Methods
|
||||
|
||||
#### tab_bar_item(args={})
|
||||
|
||||
Class method that sets the screen's default tab bar item.
|
||||
|
||||
```ruby
|
||||
class TabScreen < PM::Screen
|
||||
title "Tab"
|
||||
tab_bar_item title: "Tab Item", item: "list"
|
||||
end
|
||||
```
|
||||
|
||||
### Accessors
|
||||
|
||||
#### tab_bar
|
||||
|
||||
Contains a reference to the current screen's tab bar controller.
|
||||
|
||||
#### tab_bar_item
|
||||
|
||||
Contains the settings hash used to set up the tab bar item. If you set this manually,
|
||||
make sure to call `refresh_tab_bar_item` right afterward.
|
||||
133
docs/API Reference - ProMotion WebScreen.md
Normal file
133
docs/API Reference - ProMotion WebScreen.md
Normal file
@@ -0,0 +1,133 @@
|
||||
### Contents
|
||||
|
||||
* [Usage](?#usage)
|
||||
* [Methods](?#methods)
|
||||
* [Class Methods](?#class-methods)
|
||||
* [Accessors](?#accessors)
|
||||
|
||||
---
|
||||
|
||||
### Usage
|
||||
|
||||
*Has all the methods of PM::Screen*
|
||||
|
||||
Easily create a web-based view from an external URL, internal HTML file, or HTML string.
|
||||
|
||||
```ruby
|
||||
open MyWebScreen.new(nav_bar: true, external_links: false)
|
||||
```
|
||||
|
||||
```ruby
|
||||
class MyWebScreen < PM::WebScreen
|
||||
|
||||
title "Title of Screen"
|
||||
|
||||
def content
|
||||
# You can return:
|
||||
# 1. A reference to a file placed in your resources directory
|
||||
# 2. An instance of NSURL
|
||||
# 3. An arbitrary HTML string
|
||||
"AboutView.html"
|
||||
end
|
||||
|
||||
def load_started
|
||||
# Optional
|
||||
# Called when the request starts to load
|
||||
end
|
||||
|
||||
def load_finished
|
||||
# Optional
|
||||
# Called when the request is finished
|
||||
end
|
||||
|
||||
def load_failed(error)
|
||||
# Optional
|
||||
# "error" is an instance of NSError
|
||||
end
|
||||
|
||||
end
|
||||
```
|
||||
|
||||
#### Initialization Options
|
||||
|
||||
```ruby
|
||||
external_links: false
|
||||
```
|
||||
|
||||
**Default:** false
|
||||
**Behavior:** true causes all links clicked in the `WebScreen` to open in Safari (or Chrome).
|
||||
|
||||
```ruby
|
||||
detector_types: [:none, :phone, :link, :address, :event, :all]
|
||||
```
|
||||
|
||||
**Default:** :none
|
||||
**Behavior:** An array of any of the above values to specify what sort of detectors you'd like the webview to auto-link for you. [You can read more about `UIDataDetector`s here](http://developer.apple.com/library/ios/#documentation/uikit/reference/UIKitDataTypesReference/Reference/reference.html).
|
||||
|
||||
### Opening External Links in Chrome
|
||||
|
||||
If you want your users to have links open in the Google Chrome iOS app, simply add this to your `Rakefile`:
|
||||
|
||||
```ruby
|
||||
app.pods do
|
||||
pod 'OpenInChrome'
|
||||
end
|
||||
```
|
||||
|
||||
This will change the default behavior of your app to check and see if Chrome is installed and if so, open the link in Chrome. Otherwise, the links will open in Safari.
|
||||
|
||||
### Methods
|
||||
|
||||
#### set_content(content)
|
||||
|
||||
Causes the `WebScreen` to load new content (where `content` is a string reference to a local file in the `resources` directory or an `NSURL` or an arbitrary bit of HTML).
|
||||
|
||||
#### html
|
||||
|
||||
Returns the current HTML contained in the `WebScreen` as a string.
|
||||
|
||||
#### can_go_back
|
||||
|
||||
Returns a `boolean` if the user can navigate backwards (e.g., if there's anything in the history).
|
||||
|
||||
#### can_go_forward
|
||||
|
||||
Returns a `boolean` if the user can navigate forwards.
|
||||
|
||||
#### back
|
||||
|
||||
Navigates back one page.
|
||||
|
||||
#### forward
|
||||
|
||||
Navigates forward one page.
|
||||
|
||||
#### refresh
|
||||
|
||||
Refreshes the current URL. Alias: `reload`
|
||||
|
||||
#### stop
|
||||
|
||||
Cancels the current URL request and stops loading the page.
|
||||
|
||||
---
|
||||
|
||||
### Class Methods
|
||||
|
||||
None.
|
||||
|
||||
---
|
||||
|
||||
### Accessors
|
||||
|
||||
#### webview
|
||||
|
||||
Reference to the UIWebView that is automatically created.
|
||||
|
||||
#### external_links
|
||||
|
||||
TODO
|
||||
|
||||
#### detector_types
|
||||
|
||||
TODO
|
||||
65
docs/Add-On-Gems.md
Normal file
65
docs/Add-On-Gems.md
Normal file
@@ -0,0 +1,65 @@
|
||||
## ProMotion Add-On Gems
|
||||
|
||||
ProMotion's simple philosophy and community make it attractive to those wanting to extend its capabilities. Rather than add to the core gem itself, consider making an add-on gem! We'll list it here if you do.
|
||||
|
||||
### ProMotion-form
|
||||
|
||||
ProMotion-form provides a PM::FormScreen, similar to Formotion, but much lighter and more compatible with ProMotion.
|
||||
|
||||
GitHub: [https://github.com/clearsightstudio/ProMotion-form](https://github.com/clearsightstudio/ProMotion-form)
|
||||
|
||||
```ruby
|
||||
gem "ProMotion", "~> 2.0"
|
||||
gem "ProMotion-form"
|
||||
```
|
||||
|
||||

|
||||
|
||||
### ProMotion-map
|
||||
|
||||
ProMotion-map provides a PM::MapScreen, extracted from ProMotion core in 2.0+.
|
||||
|
||||
GitHub: [https://github.com/clearsightstudio/ProMotion-map](https://github.com/clearsightstudio/ProMotion-map)
|
||||
|
||||
```ruby
|
||||
gem "ProMotion", "~> 2.0"
|
||||
gem "ProMotion-map"
|
||||
```
|
||||
|
||||

|
||||
|
||||
### ProMotion-push
|
||||
|
||||
ProMotion-push is push notification support, extracted from ProMotion core in 2.0+.
|
||||
|
||||
GitHub: [https://github.com/clearsightstudio/ProMotion-push](https://github.com/clearsightstudio/ProMotion-push)
|
||||
|
||||
```ruby
|
||||
gem "ProMotion", "~> 2.0"
|
||||
gem "ProMotion-push"
|
||||
```
|
||||
|
||||
### ProMotion-menu
|
||||
|
||||
RubyMotion gem allowing you to easily setup a Facebook or Path style drawer menu easily with the ProMotion gem.
|
||||
|
||||
GitHub: [https://github.com/clearsightstudio/ProMotion-menu](https://github.com/clearsightstudio/ProMotion-menu)
|
||||
|
||||
```ruby
|
||||
gem "ProMotion", "~> 2.0"
|
||||
gem 'ProMotion-menu'
|
||||
```
|
||||
|
||||
### ProMotion-formotion
|
||||
|
||||
Provides a ProMotion::FormotionScreen.
|
||||
|
||||
GitHub: [https://github.com/rheoli/ProMotion-formotion](https://github.com/rheoli/ProMotion-formotion)
|
||||
|
||||
```ruby
|
||||
gem "ProMotion", "~> 2.0"
|
||||
gem "ProMotion-formotion"
|
||||
```
|
||||
|
||||
|
||||
|
||||
90
docs/Guide - Getting Started.md
Normal file
90
docs/Guide - Getting Started.md
Normal file
@@ -0,0 +1,90 @@
|
||||
ProMotion is designed to be as intuitive and Ruby-like as possible.
|
||||
|
||||
## Quick Setup (recommended)
|
||||
|
||||
Requirements:
|
||||
|
||||
* Licensed [RubyMotion](http://rubymotion.com) (2.29+ recommended)
|
||||
* Xcode with command line tools installed
|
||||
* Bundler (`gem install bundler`)
|
||||
* CRuby 2.0.0+ (for executable)
|
||||
|
||||
```bash
|
||||
gem install ProMotion #=> be sure to capitalize P and M here!
|
||||
promotion new myapp
|
||||
cd myapp
|
||||
bundle
|
||||
rake spec
|
||||
rake
|
||||
```
|
||||
|
||||
You should have a functioning ProMotion app!
|
||||
|
||||
## Manual Setup
|
||||
|
||||
Create a new RubyMotion project.
|
||||
|
||||
`motion create myapp`
|
||||
|
||||
Open the new folder in your favorite editor. Mine is Sublime, so I use `cd myapp; subl .` to open it.
|
||||
|
||||
Create a Gemfile and add the following lines:
|
||||
|
||||
```ruby
|
||||
source "https://rubygems.org"
|
||||
|
||||
gem "rake"
|
||||
gem "ProMotion", "~> 2.0.0"
|
||||
```
|
||||
|
||||
Run `bundle` in Terminal to install ProMotion.
|
||||
|
||||
```
|
||||
Fetching gem metadata from https://rubygems.org/....
|
||||
Resolving dependencies...
|
||||
Using bundler 1.6.2
|
||||
Using rake 10.3.2
|
||||
Using methadone 1.4.0
|
||||
Using ProMotion 2.0.0
|
||||
Your bundle is complete!
|
||||
Use `bundle show [gemname]` to see where a bundled gem is installed.
|
||||
```
|
||||
|
||||
Go into your app/app_delegate.rb file and replace *everything* with the following:
|
||||
|
||||
```ruby
|
||||
class AppDelegate < PM::Delegate
|
||||
def on_load(app, options)
|
||||
open HomeScreen.new(nav_bar: true)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Create a folder in `/app` named `screens`. Create a file in that folder named `home_screen.rb`.
|
||||
|
||||
Now drop in this code in that file:
|
||||
|
||||
```ruby
|
||||
class HomeScreen < PM::Screen
|
||||
title "Home"
|
||||
|
||||
def on_load
|
||||
set_attributes self.view, {
|
||||
background_color: hex_color("#FFFFFF")
|
||||
}
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Run `rake`. You should now see the simulator open with your home screen and a navigation bar. Congrats!
|
||||
|
||||
### Next steps
|
||||
|
||||
* Read through the rest of the API documentation on the right sidebar.
|
||||
|
||||
Here are a few tutorials to follow.
|
||||
|
||||
* [Getting Started with MotionKit and ProMotion](http://jamonholmgren.com/getting-started-with-motionkit-and-promotion)
|
||||
* [Building an ESPN App Using RubyMotion, ProMotion, and TDD](http://jamonholmgren.com/building-an-espn-app-using-rubymotion-promotion-and-tdd)
|
||||
|
||||
|
||||
66
docs/Guide - Making Your Own Screens.md
Normal file
66
docs/Guide - Making Your Own Screens.md
Normal file
@@ -0,0 +1,66 @@
|
||||
You can make your own `PM::Screen` from a custom view controller easily.
|
||||
|
||||
### Custom UIViewController
|
||||
|
||||
Due to a RubyMotion limitation, we can't override built-in methods with a module. Here are the main methods you'll want to override. You should be able to just copy & paste most of the code below (customize the `self.new` method).
|
||||
|
||||
```ruby
|
||||
class EventsScreen < JHAwesomeViewController
|
||||
include ProMotion::ScreenModule
|
||||
|
||||
# Customize this method for your preferred initializer
|
||||
|
||||
def self.new(args = {})
|
||||
s = self.alloc.initWithAwesomeName(args[:name])
|
||||
s.screen_init(args) # Important for ProMotion stuff!
|
||||
s
|
||||
end
|
||||
|
||||
# Highly recommended that you include these methods below
|
||||
|
||||
def loadView
|
||||
self.respond_to?(:load_view) ? self.load_view : super
|
||||
end
|
||||
|
||||
def viewDidLoad
|
||||
super
|
||||
self.view_did_load if self.respond_to?(:view_did_load)
|
||||
end
|
||||
|
||||
def viewWillAppear(animated)
|
||||
super
|
||||
self.view_will_appear(animated) if self.respond_to?("view_will_appear:")
|
||||
end
|
||||
|
||||
def viewDidAppear(animated)
|
||||
super
|
||||
self.view_did_appear(animated) if self.respond_to?("view_did_appear:")
|
||||
end
|
||||
|
||||
def viewWillDisappear(animated)
|
||||
self.view_will_disappear(animated) if self.respond_to?("view_will_disappear:")
|
||||
super
|
||||
end
|
||||
|
||||
def viewDidDisappear(animated)
|
||||
self.view_did_disappear(animated) if self.respond_to?("view_did_disappear:")
|
||||
super
|
||||
end
|
||||
|
||||
def shouldAutorotateToInterfaceOrientation(orientation)
|
||||
self.should_rotate(orientation)
|
||||
end
|
||||
|
||||
def shouldAutorotate
|
||||
self.should_autorotate
|
||||
end
|
||||
|
||||
def willRotateToInterfaceOrientation(orientation, duration:duration)
|
||||
self.will_rotate(orientation, duration)
|
||||
end
|
||||
|
||||
def didRotateFromInterfaceOrientation(orientation)
|
||||
self.on_rotate
|
||||
end
|
||||
end
|
||||
```
|
||||
1
docs/Guide - Push Notifications.md
Normal file
1
docs/Guide - Push Notifications.md
Normal file
@@ -0,0 +1 @@
|
||||
[View the PM::PushNotification](https://github.com/clearsightstudio/ProMotion/wiki/API-Reference:-ProMotion::PushNotification) documentation.
|
||||
7
docs/Guide - Styling Your Views.md
Normal file
7
docs/Guide - Styling Your Views.md
Normal file
@@ -0,0 +1,7 @@
|
||||
By [Jamon Holmgren](http://twitter.com/jamonholmgren), ProMotion creator and owner of [ClearSight Studio](http://www.clearsightstudio.com/)
|
||||
|
||||
**NOTE: This guide has been deprecated. We recommend using a styling/layout library like [MotionKit](https://github.com/rubymotion/motion-kit) or [RMQ](https://github.com/infinitered/rmq).**
|
||||
|
||||
Here's a better guide: [http://jamonholmgren.com/getting-started-with-motionkit-and-promotion](http://jamonholmgren.com/getting-started-with-motionkit-and-promotion)
|
||||
|
||||
Old article, for reference, is in the deprecated repo: [https://github.com/jamonholmgren/promotion-styling](https://github.com/jamonholmgren/promotion-styling)
|
||||
48
docs/Home.md
Normal file
48
docs/Home.md
Normal file
@@ -0,0 +1,48 @@
|
||||
## Welcome to the ProMotion wiki!
|
||||
|
||||
Documentation is targeting ProMotion 2.2.0. Any exceptions will be noted.
|
||||
|
||||
If you have a problem with *any* of the documentation, *please* [open an issue](https://github.com/clearsightstudio/ProMotion/issues) so we can resolve it quickly.
|
||||
|
||||
### Getting Started
|
||||
|
||||
#### [Getting Started with ProMotion](https://github.com/clearsightstudio/ProMotion/wiki/Guide:-Getting-Started)
|
||||
|
||||
Everything you need to know to install ProMotion and create your first iPhone app.
|
||||
|
||||
### Goal/Philosophy/Roadmap
|
||||
|
||||
ProMotion's goal is to create a **memorable**, **simple**, **intuitive**, and **enjoyable** API for
|
||||
rapidly developing screen-based iPhone and iPad apps.
|
||||
|
||||
* **Memorable:** The API should be easy to memorize. Developers shouldn't have to be digging through documentation all the time to build out iOS apps.
|
||||
* **Simple:** The API should utilize simple language, such as `open`, `close`, `add`, `remove`. Cocoa Touch is far too verbose.
|
||||
* **Intuitive:** The API should make sense, even to developers unfamiliar with ProMotion.
|
||||
* **Enjoyable:** The API should make developers feel like they're programming with purpose rather than implementing boilerplate. It should make iPhone and iPad development fun.
|
||||
|
||||
The philosophy behind ProMotion is to be a **friendly and welcoming community** to new iOS/RubyMotion developers. Many new ProMotion developers come from the web development world (Ruby on Rails, PHP) and have a lot of questions. Others come from non-English-speaking countries and may have difficulty understanding the documentation. **The more experienced ProMotion developers are encouraged to answer new developers' questions in good humor and with encouragement and patience.**
|
||||
|
||||
The current roadmap is to continue evolving the code's quality, performance, and maintainability. No major new features are currently planned. Most new features will be implemented in the form of [add-on gems](./Add-On-Gems), of which there are several already.
|
||||
|
||||
I don't want ProMotion to become bloated with little-used features. The features we've implemented so far have been commonly used ones that aren't easily available in other compatible and popular RubyMotion libraries. We will carefully consider pull requests, but the measure of whether something is accepted or not depends not only on its code quality but also its relevance and future maintainability.
|
||||
|
||||
*Visit the links in the sidebar to learn more about ProMotion's API.*
|
||||
|
||||
## Primary Contributors
|
||||
|
||||
|Contributor|Twitter|
|
||||
|---|---|
|
||||
|Jamon Holmgren|[@jamonholmgren](https://twitter.com/jamonholmgren)|
|
||||
|Mark Rickert|[@markrickert](https://twitter.com/markrickert)|
|
||||
|Silas J. Matson|[@silasjmatson](https://twitter.com/silasjmatson)|
|
||||
|Ryan Linton|[@ryanlntn](https://twitter.com/ryanlntn)|
|
||||
|
||||
## Alumni
|
||||
|
||||
Matt Brewer [@macfanatic](https://twitter.com/macfanatic)
|
||||
|
||||
Many others contribute every day!
|
||||
|
||||
|
||||
|
||||
|
||||
165
docs/Migration Guide - ProMotion-1.2-to-2.0.md
Normal file
165
docs/Migration Guide - ProMotion-1.2-to-2.0.md
Normal file
@@ -0,0 +1,165 @@
|
||||
ProMotion 2.0 is mostly backwards-compatible to ProMotion 1.2, but there are a few things to look for in your app when you upgrade. Follow this guide and you shouldn't have any issues.
|
||||
|
||||
First, update your Gemfile:
|
||||
|
||||
```ruby
|
||||
gem "ProMotion", "~> 2.0"
|
||||
```
|
||||
|
||||
### PM::MapScreen and PM::PushNotification
|
||||
|
||||
If you're using a MapScreen or push notifications in your app, add either or both of these gems to your Gemfile right after ProMotion:
|
||||
|
||||
```ruby
|
||||
gem "ProMotion-map"
|
||||
gem "ProMotion-push"
|
||||
```
|
||||
|
||||
If you were using PM::FormotionScreen, you can try using the ProMotion-formotion gem. Some people have had trouble with this third party gem, so if you have difficulty, feel free to open an issue there (I watch that repo). Another option is to convert over to the new [ProMotion-form](https://github.com/clearsightstudio/ProMotion-form) gem which is much more compatible with ProMotion.
|
||||
|
||||
## PM::Screen changes
|
||||
|
||||
### Check to make sure your `title`s are only strings
|
||||
|
||||
* `title` now only accepts a string. If you want to set an image or view, use `title_image` and `title_view`.
|
||||
|
||||
```ruby
|
||||
class MyScreen < PM::Screen
|
||||
title UILabel.new # don't do this
|
||||
title UIImage.imageNamed("my-title") # don't do this
|
||||
title "String" # good
|
||||
title_view UILabel.new # good
|
||||
title_image UIImage.imageNamed("my-title") # good
|
||||
end
|
||||
```
|
||||
|
||||
### Look for `on_create` and change to `on_init`
|
||||
|
||||
* Don't use `on_create` anymore. `on_init` is called about the same time that `on_create` used to be.
|
||||
* Remove any calls to `super` in the new `on_init`.
|
||||
|
||||
```ruby
|
||||
class MyScreen < PM::Screen
|
||||
# bad
|
||||
def on_create
|
||||
# other stuff
|
||||
super
|
||||
end
|
||||
|
||||
# good
|
||||
def on_init
|
||||
# other stuff
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Look for `set_nav_bar_right_button` and `set_nav_bar_left_button`
|
||||
|
||||
* Use `set_nav_bar_button :left` and `set_nav_bar_button :right` instead.
|
||||
|
||||
```ruby
|
||||
# Bad
|
||||
set_nav_bar_right_button "Help", action: :help
|
||||
# Good
|
||||
set_nav_bar_button :right, title: "Help", action: :help
|
||||
```
|
||||
|
||||
### Look for any `present_modal_view_controller` calls
|
||||
|
||||
* You really shouldn't have been using this undocumented method, and its API has changed. Instead, use `open_modal`.
|
||||
|
||||
### Look for any `on_load` methods that set the view
|
||||
|
||||
* We've moved `on_load` to fire after the view is created
|
||||
* If you need to set the root view, do so in the new `load_view` method instead
|
||||
|
||||
```ruby
|
||||
def on_load
|
||||
self.view = UIView.new # bad
|
||||
end
|
||||
|
||||
def load_view
|
||||
self.view = UIView.new # good
|
||||
end
|
||||
|
||||
def on_load
|
||||
self.view.backgroundColor = UIColor.redColor # good
|
||||
end
|
||||
```
|
||||
|
||||
## PM::TableScreen changes
|
||||
|
||||
### In table cells, move arbitrary styling attributes into a `style:` hash
|
||||
|
||||
* We now only apply attributes in the `style:` hash to the cell.
|
||||
* `background_color` is still applied due to some weirdness in UIKit's handling of cell background colors.
|
||||
|
||||
```ruby
|
||||
def table_data
|
||||
[{
|
||||
cells: [{
|
||||
# stays the same
|
||||
title: "My title",
|
||||
background_color: UIColor.blackColor,
|
||||
|
||||
# bad -- these won't be applied to the cell
|
||||
accessibility_label: "My label",
|
||||
background_view: MyBGView.new,
|
||||
|
||||
# good -- these will be applied to the cell
|
||||
style: {
|
||||
accessibility_label: "My label",
|
||||
background_view: MyBGView.new,
|
||||
}
|
||||
}]
|
||||
}]
|
||||
end
|
||||
```
|
||||
|
||||
### Look for any `subviews:` in your table hashes
|
||||
|
||||
* We no longer support this feature
|
||||
* Instead, subclass `PM::TableViewCell` and make your own subviews there
|
||||
|
||||
### Look for cell tap actions that rely on the `[:cell]` data being auto-passed in
|
||||
|
||||
* We no longer include the `[:cell]` data in the argument hash passed through on tap.
|
||||
* If you need this info, replicate it in the `arguments:` hash yourself.
|
||||
|
||||
```ruby
|
||||
def table_data
|
||||
[{
|
||||
cells: [{
|
||||
title: "My title",
|
||||
action: :some_action,
|
||||
arguments: { my_title: "My title" }
|
||||
}]
|
||||
}]
|
||||
end
|
||||
|
||||
def some_action(args={})
|
||||
puts args[:cell][:title] # Bad -- won't work
|
||||
puts args[:my_title] # Good
|
||||
end
|
||||
```
|
||||
|
||||
## PM::Styling changes
|
||||
|
||||
### Look for add_element, add_view, remove_element, remove_view
|
||||
|
||||
* These aliases have been removed. Use `add` and `remove` instead.
|
||||
|
||||
### Removed easy attributes
|
||||
|
||||
* Not too many people knew about these, but there were some `margin:` helpers and whatnot in PM::Styling (`add` and `set_attributes`). These have been removed.
|
||||
* If your views are not visible or screwed up, you were probably relying on one of these. File an issue and I'll help you migrate.
|
||||
|
||||
## Problems?
|
||||
|
||||
Get in touch by filing an issue. We'll be there to help you out!
|
||||
|
||||
Jamon Holmgren
|
||||
August 2, 2014
|
||||
|
||||
|
||||
|
||||
125
docs/ProMotion Apps.md
Normal file
125
docs/ProMotion Apps.md
Normal file
@@ -0,0 +1,125 @@
|
||||
### RubyMotion Yelp
|
||||
|
||||
[View Source on GitHub](https://github.com/faizaanshamsi/rubymotion_yelp)
|
||||
|
||||
[](https://github.com/faizaanshamsi/rubymotion_yelp)
|
||||
|
||||
> Simple Yelp search using Rubymotion. My First Rubymotion app!
|
||||
>
|
||||
> Uses Yelp API v1.0 so search by location. Allows you to filter results in a table view. Clicking on a results will redirect you to the mobile yelp page.
|
||||
|
||||
By [@faizaanshamsi](https://twitter.com/faizaanshamsi).
|
||||
|
||||
### Brewers Association Styles
|
||||
|
||||
[](http://www.mohawkapps.com/app/brewers-association-styles/)
|
||||
|
||||
[](https://itunes.apple.com/us/app/brewers-association-styles/id670470983?mt=8&uo=4&at=10l4yY&ct=promotionwiki)
|
||||
|
||||
Brewers Association Styles (by [Mohawk Apps](http://www.mohawkapps.com/)) is the _UNOFFICIAL_ go-to guide for all your beer style guide needs! The complete Brewers Association 2013 style guidelines in your pocket! The app is free (as in beer) and [open source](https://github.com/MohawkApps/BAStyleGuide).
|
||||
|
||||
### RainCloud
|
||||
|
||||
[](http://www.raincloudalerts.com/)
|
||||
|
||||
[](https://itunes.apple.com/us/app/raincloud/id632130365?mt=8)
|
||||
|
||||
RainCloud (by [@forrestgrant](https://twitter.com/forrestgrant)) is a free iPhone app that notifies you when critical cloud infrastructure services and APIs have downtime, performance issues, and other similar failures.
|
||||
|
||||
### Coowl
|
||||
|
||||
[](https://itunes.apple.com/us/app/coowl/id657397623)
|
||||
|
||||
[](https://itunes.apple.com/us/app/coowl/id657397623)
|
||||
|
||||
Coowl (by [@puelocesar](https://twitter.com/puelocesar)) is a photo editing/effects app with a really well done menu system and sharing mechanism.
|
||||
|
||||
### BigDay! Reminder App
|
||||
|
||||
[](https://itunes.apple.com/us/app/bigday!/id571756685?ls=1&mt=8)
|
||||
|
||||
This was the genesis of ProMotion. [ClearSight Studio](http://www.clearsightstudio.com/) ([Jamon Holmgren](http://twitter.com/jamonholmgren)'s company) built the app for Kijome Software, a small app investment company. We extracted ProMotion from that code.
|
||||
|
||||
### TipCounter App
|
||||
|
||||
[](https://itunes.apple.com/us/app/tip-counter/id418749608?mt=8&ls=1)
|
||||
|
||||
[](https://itunes.apple.com/us/app/tip-counter/id418749608?mt=8&ls=1)
|
||||
|
||||
[TipCounter](http://www.tipcounterapp.com) was built by [Matt Brewer](https://github.com/macfanatic/) for bartenders and servers to easily track their tips and analyze income. Used ProMotion and the development was a lot of fun!
|
||||
|
||||
### BraillED
|
||||
|
||||
[](https://itunes.apple.com/us/app/brailled/id839690467?mt=8)
|
||||
|
||||
[](https://itunes.apple.com/us/app/brailled/id839690467?mt=8)
|
||||
|
||||
Explore the braille alphabet in a high contrast app designed specifically for the visually impaired. Audio cues and device vibrations aid in learning.
|
||||
|
||||
[BraillED](http://www.brailledapp.com) was created by [Matt Brewer](https://github.com/macfanatic/) and uses ProMotion, [motion-speech](https://github.com/macfanatic/motion-speech), [motion-launchpad](https://github.com/macfanatic/motion-launchpad), and more.
|
||||
|
||||
### Winston-Salem Crime Map
|
||||
|
||||
[](http://www.mohawkapps.com/app/winston-salem-crime-map/)
|
||||
|
||||
[](https://itunes.apple.com/us/app/winston-salem-crime-map/id472546582?mt=8&uo=4&at=10l4yY&ct=promotionwiki)
|
||||
|
||||
Have an interest in crime statistics and locations? Live in Winston-Salem, NC? This hyper-local and [open source](https://github.com/MohawkApps/WSCrime) RubyMotion app uses a mixture of custom UIViewControllers and ProMotion for ease of setting attributes and adding views. Check it out [on the App Store](https://itunes.apple.com/us/app/winston-salem-crime-map/id472546582?mt=8&uo=4&at=10l4yY&ct=promotionwiki) or [fork it and contribute](https://github.com/MohawkApps/WSCrime)!
|
||||
|
||||
### BJCP Styles (OFFICIAL)
|
||||
|
||||
[](http://www.mohawkapps.com/app/bjcp-styles/)
|
||||
|
||||
[](https://itunes.apple.com/us/app/bjcp-styles/id293788663?mt=8&uo=4&at=10l4yY&ct=promotionwiki)
|
||||
|
||||
Now you have a full copy of the BJCP Style Guidelines at your finger tips! Whether you're a beer judge, a homebrewer, or an enthusiast, this free app will come in handy whenever you want a quick lookup of a style description.
|
||||
|
||||
Features include:
|
||||
* Quick jump to a specific category using the index on the right.
|
||||
* Full-text search of all guidelines!
|
||||
* SRM spectrum graphic for each style!
|
||||
* Swipe left and right for access to the next and previous style. (iPad only)
|
||||
|
||||
This application is open source! [Check out the source code](https://github.com/MohawkApps/BJCPStyleGuide)!
|
||||
|
||||
### Beer Judge
|
||||
|
||||
[](http://www.mohawkapps.com/app/beerjudge/)
|
||||
|
||||
[](https://itunes.apple.com/us/app/beer-judge/id666120064?mt=8&uo=4&at=10l4yY&ct=promotionwiki)
|
||||
|
||||
This app is the perfect companion for you at beer competitions!
|
||||
|
||||
* Use the Flavor Wheel to explore and help identify different off flavors and aromas in a beer.
|
||||
* Tap and drag around the SRM Spectrum to identify the closest SRM to the beer you're judging.
|
||||
* Use your device's camera to help you estimate a beer's SRM using the SRM Analysis tool! (SRM Analysis tool requires a device with camera capability.)
|
||||
|
||||
This application is open source! [Check out the source code](https://github.com/MohawkApps/BeerJudge)!
|
||||
|
||||
### Odorik
|
||||
|
||||
[](https://itunes.apple.com/us/app/odorik/id682721789?mt=8)
|
||||
|
||||
[](https://itunes.apple.com/us/app/odorik/id682721789?ls=1&mt=8)
|
||||
|
||||
Odorik is an iOS application that allows you comfortably set up callbacks through your account with Czech VOIP provider of the same name, [Odorik.cz](http://Odorik.cz) (run by miniTEL s.r.o.).
|
||||
|
||||
It's open source!
|
||||
|
||||
[https://github.com/wejn/Odorik](https://github.com/wejn/Odorik)
|
||||
|
||||
More information: [http://wejn.com/ios/odorik/](http://wejn.com/ios/odorik/)
|
||||
|
||||
|
||||
### Your app here
|
||||
|
||||
Tweet [@jamonholmgren](https://twitter.com/jamonholmgren) if you built an app in ProMotion and want it included here!
|
||||
22
docs/Tutorials, Screencasts, Articles, Presentations.md
Normal file
22
docs/Tutorials, Screencasts, Articles, Presentations.md
Normal file
@@ -0,0 +1,22 @@
|
||||
## Tutorials
|
||||
|
||||
* [Getting Started with MotionKit and ProMotion](http://jamonholmgren.com/getting-started-with-motionkit-and-promotion)
|
||||
* [Building an ESPN app with ProMotion and TDD](http://jamonholmgren.com/building-an-espn-app-using-rubymotion-promotion-and-tdd)
|
||||
|
||||
## Screencasts
|
||||
|
||||
*MotionInMotion requires a paid subscription, but is well worth the money)*
|
||||
|
||||
* MotionInMotion episode 8: [ProMotion](https://motioninmotion.tv/screencasts/8)
|
||||
* MotionInMotion episode 9: [ProMotion + Formotion](https://motioninmotion.tv/screencasts/9)
|
||||
|
||||
## Articles
|
||||
|
||||
* [ClearSight blog: ProMotion for non-geeks](http://clearsightstudio.com/blog/2014/05/15/promotion-for-non-geeks/)
|
||||
|
||||
## Presentations
|
||||
|
||||
* Jamon Holmgren's talk at RubyMotion #inspect2014: [http://confreaks.com/videos/3813-inspect-going-pro-with-promotion-from-prototype-to-production](http://confreaks.com/videos/3813-inspect-going-pro-with-promotion-from-prototype-to-production) (video)
|
||||
* Jamon Holmgren's appearance on MotionMeetup: [https://www.youtube.com/watch?v=rf7h-3AiMRQ](https://www.youtube.com/watch?v=rf7h-3AiMRQ) (video)
|
||||
* Wouter de Vos: "RubyMotion and ProMotion" [http://www.slideshare.net/wrdevos/20140121-ruby-motionamsrb](http://www.slideshare.net/wrdevos/20140121-ruby-motionamsrb) (slides)
|
||||
* mediatainment: [https://speakerdeck.com/mediatainment/rubymotion-with-promotion-and-teacup](https://speakerdeck.com/mediatainment/rubymotion-with-promotion-and-teacup) (slides)
|
||||
Reference in New Issue
Block a user