motion-form 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 62b070da82951513aecbfda093cfbc243beb1768
4
+ data.tar.gz: 24a8bea72a87cfdeb04d08d121f0fe63ccb6be1a
5
+ SHA512:
6
+ metadata.gz: 46285b557f7bbb68a6ded12d7e139ec8d8293330fb68f96614854b7cf073dfd5d83400293d1d8209618925fc070b53cbc8141e007602938be1b60d2cfaa9db89
7
+ data.tar.gz: b9d211dd2c64ff3054a7425b521f4a54205431f8983b5a170b4ca723ecdc7505d2bc9a540f28a4dd6dc2b401a054fad9d68551600d79dd6d3cce5aeec039223b
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # motion-form
2
+
3
+ RubyMotion forms made easy.
4
+
5
+ motion-form is heavily inspired by the gem simple_form for Rails.
6
+
7
+ It aims to bring a simple, yet flexible DSL to the tedious task of creating iOS forms.
8
+
9
+ ![Screenshot](https://github.com/dblandin/motion-form/blob/master/img/screenshot.png?raw=true)
10
+
11
+ ## Usage
12
+
13
+ ```ruby
14
+ form = MotionForm.form_for(view) do |f|
15
+ f.section 'Profile' do |section|
16
+ section.input :name, icon: :contact
17
+ section.input :username, icon: :user
18
+ section.input :pinterest, icon: :pinterest
19
+ section.input :twitter, icon: :twitter
20
+ section.input :website, icon: :website
21
+ section.input :bio, icon: :info
22
+ end
23
+
24
+ f.section 'Account' do |section|
25
+ section.button :change_email, icon: :email, action: push_email_controller
26
+ section.button :change_password, icon: :lock, action: push_password_controller
27
+ end
28
+ end
29
+
30
+ def push_email_controller
31
+ # push controller
32
+ end
33
+
34
+ def push_password_controller
35
+ # push controller
36
+ end
37
+ ```
38
+
39
+ ## Installation
40
+
41
+ Add this line to your application's Gemfile:
42
+
43
+ gem 'motion-form'
44
+
45
+ And then execute:
46
+
47
+ $ bundle
48
+
49
+ Or install it yourself as:
50
+
51
+ $ gem install motion-form
52
+
53
+ ## Contributing
54
+
55
+ 1. Fork it
56
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
57
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
58
+ 4. Push to the branch (`git push origin my-new-feature`)
59
+ 5. Create new Pull Request
@@ -0,0 +1,8 @@
1
+ unless defined?(Motion::Project::Config)
2
+ raise "This file must be required within a RubyMotion project Rakefile."
3
+ end
4
+
5
+ lib_dir_path = File.dirname(File.expand_path(__FILE__))
6
+ Motion::Project::App.setup do |app|
7
+ app.files.unshift(Dir.glob(File.join(lib_dir_path, "project/**/*.rb")))
8
+ end
@@ -0,0 +1,31 @@
1
+ class BaseCell < UITableViewCell
2
+ attr_accessor :key
3
+
4
+ class << self
5
+ def has_value?
6
+ false
7
+ end
8
+ end
9
+
10
+ def initWithStyle(style, reuseIdentifier: reuse_identifier)
11
+ super.tap do |cell|
12
+ cell.selectionStyle = UITableViewCellSelectionStyleNone
13
+ cell.contentView.addSubview(text_field)
14
+ cell.selectedBackgroundView = selected_background_view
15
+ end
16
+ end
17
+
18
+ def selected_background_view
19
+ UIView.alloc.initWithFrame(bounds).tap do |view|
20
+ view.backgroundColor = 'FFCDCB'.to_color
21
+ end
22
+ end
23
+
24
+ def notification_center
25
+ NSNotificationCenter.defaultCenter
26
+ end
27
+
28
+ def post(notification)
29
+ notification_center.postNotificationName(notification, object: self, userInfo: notification_payload)
30
+ end
31
+ end
@@ -0,0 +1,52 @@
1
+ class ButtonCell < TextFieldCell
2
+ IDENTIFIER = 'ButtonCell'
3
+
4
+ class << self
5
+ def has_value?
6
+ false
7
+ end
8
+ end
9
+
10
+ def initWithStyle(style, reuseIdentifier: reuse_identifier)
11
+ super.tap do |cell|
12
+ cell.selectionStyle = UITableViewCellSelectionStyleGray
13
+ cell.text_field.enabled = false
14
+
15
+ cell.add_right_view
16
+ cell.add_tap_recognizer
17
+ end
18
+ end
19
+
20
+ def add_tap_recognizer
21
+ addGestureRecognizer(tap_recognizer)
22
+ end
23
+
24
+ def tap_recognizer
25
+ UITapGestureRecognizer.alloc.initWithTarget(self, action: 'tapped:')
26
+ end
27
+
28
+ def tapped(recognizer)
29
+ post('FormCellWasTapped')
30
+ end
31
+
32
+ def add_right_view
33
+ text_field.rightView = right_view
34
+ text_field.rightViewMode = UITextFieldViewModeAlways
35
+ end
36
+
37
+ def right_view
38
+ @right_view ||= IconView.alloc.init.tap do |icon|
39
+ icon.name = :forward_arrow
40
+ end
41
+ end
42
+
43
+ def layoutSubviews
44
+ super
45
+
46
+ right_view.frame = [[size.width - 56, 0], [36, 43]]
47
+ end
48
+
49
+ def notification_payload
50
+ { key: key }
51
+ end
52
+ end
@@ -0,0 +1,63 @@
1
+ class TextFieldCell < BaseCell
2
+ IDENTIFIER = 'TextFieldCell'
3
+
4
+ class << self
5
+ def has_value?
6
+ true
7
+ end
8
+ end
9
+
10
+ def label=(label)
11
+ text_field.placeholder = label
12
+ end
13
+
14
+ def icon=(icon)
15
+ left_view.name = icon
16
+ end
17
+
18
+ def text_field
19
+ @text_field ||= UITextField.alloc.init.tap do |field|
20
+ field.autocorrectionType = UITextAutocorrectionTypeNo
21
+ field.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight
22
+ field.backgroundColor = UIColor.clearColor
23
+ field.clearButtonMode = UITextFieldViewModeWhileEditing
24
+ field.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter
25
+ field.leftView = left_view
26
+ field.leftViewMode = UITextFieldViewModeAlways
27
+ field.textColor = UIColor.grayColor
28
+
29
+ field.delegate = self
30
+ end
31
+ end
32
+
33
+ def left_view
34
+ @left_view ||= IconView.alloc.init
35
+ end
36
+
37
+ def value
38
+ text_field.text
39
+ end
40
+
41
+ def layoutSubviews
42
+ text_field.frame = [[10, 0], [300, 43]]
43
+ left_view.frame = [[0, 0], [36, 43]]
44
+ end
45
+
46
+ def textFieldDidBeginEditing(text_field)
47
+ post('FormCellDidBeginEditing')
48
+ end
49
+
50
+ def textFieldDidEndEditing(text_field)
51
+ post('FormCellDidEndEditing')
52
+ end
53
+
54
+ def textFieldShouldReturn(text_field)
55
+ text_field.resignFirstResponder
56
+
57
+ true
58
+ end
59
+
60
+ def notification_payload
61
+ { key: key, value: value, text_field: text_field }
62
+ end
63
+ end
@@ -0,0 +1,17 @@
1
+ module MotionForm
2
+ class FormController < UIViewController
3
+ attr_reader :form
4
+
5
+ def viewDidLoad
6
+ super
7
+
8
+ setup_form
9
+ end
10
+
11
+ private
12
+
13
+ def setup_form
14
+ @form = MotionForm.form_for(view)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,123 @@
1
+ module MotionForm
2
+ class Base < UITableView
3
+ attr_reader :keyboard_avoiding_delegate
4
+
5
+ def init
6
+ initWithFrame(frame, style: UITableViewStylePlain).tap do |f|
7
+ f.register_cells
8
+ f.separatorStyle = UITableViewCellSeparatorStyleNone
9
+
10
+ f.dataSource = self
11
+ f.delegate = self
12
+
13
+ @keyboard_avoiding_delegate = Motion::KeyboardAvoiding.new(f)
14
+ listen
15
+ end
16
+ end
17
+
18
+ def listen
19
+ observers << notification_center.addObserver(self, selector: 'did_begin_editing:', name: 'FormCellDidBeginEditing', object: nil)
20
+ observers << notification_center.addObserver(self, selector: 'did_end_editing:', name: 'FormCellDidEndEditing', object: nil)
21
+ end
22
+
23
+ def did_begin_editing(notification)
24
+ unless window.nil?
25
+ keyboard_avoiding_delegate.textFieldDidBeginEditing(notification.userInfo[:text_field])
26
+ end
27
+ end
28
+
29
+ def did_end_editing(notification)
30
+ unless window.nil?
31
+ keyboard_avoiding_delegate.textFieldDidEndEditing(notification.userInfo[:text_field])
32
+ end
33
+ end
34
+
35
+ def observers
36
+ @observers ||= []
37
+ end
38
+
39
+ def notification_center
40
+ NSNotificationCenter.defaultCenter
41
+ end
42
+
43
+ def section(title = '')
44
+ build_section(title).tap do |section|
45
+ yield section
46
+ end
47
+ end
48
+
49
+ def build_section(title)
50
+ MotionForm::Section.new(title).tap do |section|
51
+ sections << section
52
+ end
53
+ end
54
+
55
+ def sections
56
+ @sections ||= []
57
+ end
58
+
59
+ def register_cells
60
+ MotionForm.registered_cells.each do |klass|
61
+ registerClass(klass, forCellReuseIdentifier: klass::IDENTIFIER)
62
+ end
63
+ end
64
+
65
+ def numberOfSectionsInTableView(table_view)
66
+ sections.count
67
+ end
68
+
69
+ def tableView(table_view, numberOfRowsInSection: section_index)
70
+ sections[section_index].rows.count
71
+ end
72
+
73
+ def tableView(table_view, didSelectRowAtIndexPath: index_path)
74
+ section = sections[index_path.section]
75
+ row = section.rows[index_path.row]
76
+ end
77
+
78
+ def tableView(table_view, viewForHeaderInSection: section)
79
+ unless sections[section].title.blank?
80
+ SectionHeaderView.alloc.initWithFrame([[0, 0], [size.width, 44.0]]).tap do |header|
81
+ header.text = table_view.tableView(table_view, titleForHeaderInSection: section)
82
+ end
83
+ end
84
+ end
85
+
86
+ def tableView(table_view, titleForHeaderInSection: section)
87
+ sections[section].title
88
+ end
89
+
90
+ def tableView(table_view, heightForHeaderInSection: section)
91
+ if sections[section].title.blank?
92
+ 0.0
93
+ else
94
+ 44.0
95
+ end
96
+ end
97
+
98
+ def rows
99
+ sections.map(&:rows).flatten
100
+ end
101
+
102
+ def tableView(table_view, cellForRowAtIndexPath: index_path)
103
+ section = sections[index_path.section]
104
+ row = section.rows[index_path.row]
105
+
106
+ table_view.dequeueReusableCellWithIdentifier(row.cell_identifier).tap do |cell|
107
+ row.update_cell(cell)
108
+ end
109
+ end
110
+
111
+ def render
112
+ Hash[render_values]
113
+ end
114
+
115
+ def render_values
116
+ value_rows.map { |row| [row.key, row.value] }
117
+ end
118
+
119
+ def value_rows
120
+ rows.select { |row| row.has_value? }
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,113 @@
1
+ class KeyboardAvoidingDelegate
2
+ KEYBOARD_ANIMATION_DURATION = 0.3
3
+ MINIMUM_SCROLL_FRACTION = 0.2
4
+ MAXIMUM_SCROLL_FRACTION = 0.8
5
+ PORTRAIT_KEYBOARD_HEIGHT = 216.0
6
+ LANDSCAPE_KEYBOARD_HEIGHT = 162.0
7
+
8
+ attr_accessor :view, :animated_distance, :active_text_field
9
+
10
+ def initialize(view)
11
+ self.view = view
12
+
13
+ add_tap_recognizer
14
+ listen_to_notifications
15
+ end
16
+
17
+ def listen_to_notifications
18
+ observers << notification_center.addObserver(self, selector: 'did_begin_editing:', name: 'FormCellDidBeginEditing', object: nil)
19
+ observers << notification_center.addObserver(self, selector: 'did_end_editing:', name: 'FormCellDidEndEditing', object: nil)
20
+ end
21
+
22
+ def notification_center
23
+ NSNotificationCenter.defaultCenter
24
+ end
25
+
26
+ def did_begin_editing(notification)
27
+ textFieldDidBeginEditing(notification.userInfo[:text_field])
28
+ end
29
+
30
+ def did_end_editing(notification)
31
+ textFieldDidEndEditing(notification.userInfo[:text_field])
32
+ end
33
+
34
+ def observers
35
+ @observers ||= []
36
+ end
37
+
38
+ def remove_all_observers
39
+ observers.each do |observer|
40
+ notification_center.removeObserver(observer)
41
+ end
42
+ end
43
+
44
+ def dealloc
45
+ remove_all_observers
46
+ end
47
+
48
+ def add_tap_recognizer
49
+ view.addGestureRecognizer(tap_recognizer)
50
+ end
51
+
52
+ def tap_recognizer
53
+ UITapGestureRecognizer.alloc.initWithTarget(self, action: 'dismiss_keyboard')
54
+ end
55
+
56
+ def dismiss_keyboard
57
+ active_text_field.resignFirstResponder if active_text_field
58
+ end
59
+
60
+ def textFieldDidBeginEditing(text_field)
61
+ self.active_text_field = text_field
62
+
63
+ text_field_rect = view.window.convertRect(text_field.bounds, fromView: text_field)
64
+ view_rect = view.window.convertRect(view.bounds, fromView: view)
65
+ midline = text_field_rect.origin.y + 0.5 * text_field_rect.size.height
66
+ numerator = midline - view_rect.origin.y - MINIMUM_SCROLL_FRACTION * view_rect.size.height
67
+ denominator = (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION) * view_rect.size.height
68
+ height_fraction = numerator / denominator
69
+
70
+ if height_fraction < 0.0
71
+ height_fraction = 0.0
72
+ elsif height_fraction > 1.0
73
+ height_fraction = 1.0
74
+ end
75
+
76
+ orientation = UIApplication.sharedApplication.statusBarOrientation
77
+ if orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown
78
+ self.animated_distance = (PORTRAIT_KEYBOARD_HEIGHT * height_fraction).floor
79
+ else
80
+ self.animated_distance = (LANDSCAPE_KEYBOARD_HEIGHT * height_fraction).floor
81
+ end
82
+
83
+ view_frame = view.frame
84
+ view_frame.origin.y -= animated_distance
85
+
86
+ UIView.beginAnimations(nil, context: nil)
87
+ UIView.setAnimationBeginsFromCurrentState(true)
88
+ UIView.setAnimationDuration(KEYBOARD_ANIMATION_DURATION)
89
+
90
+ view.setFrame(view_frame)
91
+
92
+ UIView.commitAnimations
93
+ end
94
+
95
+ def textFieldDidEndEditing(text_field)
96
+ view_frame = view.frame
97
+ view_frame.origin.y += animated_distance
98
+
99
+ UIView.beginAnimations(nil, context: nil)
100
+ UIView.setAnimationBeginsFromCurrentState(true)
101
+ UIView.setAnimationDuration(KEYBOARD_ANIMATION_DURATION)
102
+
103
+ view.setFrame(view_frame)
104
+
105
+ UIView.commitAnimations
106
+ end
107
+
108
+ def textFieldShouldReturn(text_field)
109
+ text_field.resignFirstResponder
110
+
111
+ true
112
+ end
113
+ end
@@ -0,0 +1,32 @@
1
+ module MotionForm
2
+ class << self
3
+ attr_accessor :icon_font
4
+
5
+ def config
6
+ yield self
7
+ end
8
+
9
+ def form_for(view)
10
+ MotionForm::Base.new.tap do |form|
11
+
12
+ yield form if block_given?
13
+
14
+ form.frame = view.bounds
15
+
16
+ view.addSubview(form)
17
+ end
18
+ end
19
+
20
+ def register_cell(cell)
21
+ registered_cells << cell
22
+ end
23
+
24
+ def registered_cells
25
+ @registered_cells ||= included_cells
26
+ end
27
+
28
+ def included_cells
29
+ [TextFieldCell, ButtonCell]
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,43 @@
1
+ class BaseRow
2
+ attr_reader :icon, :key, :options
3
+
4
+ def initialize(key, options)
5
+ @key = key
6
+ @options = options
7
+
8
+ @icon = options.fetch(:icon, nil)
9
+ @value = options.fetch(:value, nil)
10
+ end
11
+
12
+ def observers
13
+ @observers ||= []
14
+ end
15
+
16
+ def remove_all_observers
17
+ observers.each do |observer|
18
+ notification_center.removeObserver(observer)
19
+ end
20
+ end
21
+
22
+ def notification_center
23
+ NSNotificationCenter.defaultCenter
24
+ end
25
+
26
+ def cell_identifier
27
+ cell_type::IDENTIFIER
28
+ end
29
+
30
+ def has_value?
31
+ cell_type.has_value?
32
+ end
33
+
34
+ def update_cell(cell)
35
+ cell.key = key
36
+ cell.label = name
37
+ cell.icon = icon
38
+ end
39
+
40
+ def name
41
+ key.to_s.titleize
42
+ end
43
+ end
@@ -0,0 +1,27 @@
1
+ class ButtonRow < TextFieldRow
2
+ attr_reader :on_tap_callback
3
+
4
+ def initialize(key, options)
5
+ super
6
+
7
+ @on_tap_callback = options.fetch(:action, lambda {})
8
+ end
9
+
10
+ def cell_type
11
+ ButtonCell
12
+ end
13
+
14
+ def accessory
15
+ options.fetch(:accessory, nil)
16
+ end
17
+
18
+ def listen
19
+ observers << notification_center.addObserver(self, selector: 'tapped:', name: 'FormCellWasTapped', object: nil)
20
+ end
21
+
22
+ def tapped(notification)
23
+ if notification.userInfo[:key] == key
24
+ on_tap_callback.call
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ class TextFieldRow < BaseRow
2
+ attr_accessor :value
3
+
4
+ def initialize(key, options)
5
+ super
6
+
7
+ listen
8
+ end
9
+
10
+ def listen
11
+ observers << notification_center.addObserver(self, selector: 'did_end_editing:', name: 'FormCellDidEndEditing', object: nil)
12
+ end
13
+
14
+ def did_end_editing(notification)
15
+ self.value = notification.userInfo[:value] if notification.userInfo[:key] == key
16
+ end
17
+
18
+ def textFieldDidEndEditing(text_field)
19
+ self.value = text_field.text
20
+ end
21
+
22
+ def cell_type
23
+ TextFieldCell
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ class MotionForm
2
+ class Section
3
+ attr_reader :title
4
+
5
+ def initialize(title = '')
6
+ @title = title
7
+ end
8
+
9
+ def input(key, options = {})
10
+ rows << TextFieldRow.new(key, options)
11
+ end
12
+
13
+ def button(key, options = {})
14
+ rows << ButtonRow.new(key, options)
15
+ end
16
+
17
+ def rows
18
+ @rows ||= []
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ class String
2
+ def titleize
3
+ gsub('_', ' ').split(/(\W)/).map(&:capitalize).join
4
+ end
5
+
6
+ def blank?
7
+ self == ''
8
+ end
9
+ end
@@ -0,0 +1,38 @@
1
+ class IconView < UILabel
2
+ attr_reader :name
3
+
4
+ def init
5
+ super.tap do |view|
6
+ view.font = MotionForm.icon_font
7
+ view.backgroundColor = UIColor.clearColor
8
+ view.textColor = UIColor.grayColor
9
+ view.textAlignment = NSTextAlignmentCenter
10
+ end
11
+ end
12
+
13
+ def name=(name)
14
+ @name = name
15
+
16
+ self.text = hex
17
+ end
18
+
19
+ def hex
20
+ unicode ? unicode.hex.chr(Encoding::UTF_8) : ''
21
+ end
22
+
23
+ def unicode
24
+ icon_mappings[name]
25
+ end
26
+
27
+ def icon_mappings
28
+ @_icon_mappings ||= BW::JSON.parse(json_data.to_str)
29
+ end
30
+
31
+ def json_data
32
+ NSData.dataWithContentsOfFile(json_path)
33
+ end
34
+
35
+ def json_path
36
+ NSBundle.mainBundle.pathForResource('font_icons', ofType: 'json')
37
+ end
38
+ end
@@ -0,0 +1,17 @@
1
+ class PaddedLabel < UILabel
2
+ def drawTextInRect(rect)
3
+ insets = UIEdgeInsets.new(0, padding, 0, padding)
4
+
5
+ padded_rect = UIEdgeInsetsInsetRect(rect, insets)
6
+
7
+ super(padded_rect)
8
+ end
9
+
10
+ def padding=(padding)
11
+ @padding = padding
12
+ end
13
+
14
+ def padding
15
+ @padding || 0
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ class SectionHeaderView < UIView
2
+ def initWithFrame(frame)
3
+ super.tap do |view|
4
+ view.addSubview(section_title)
5
+ end
6
+ end
7
+
8
+ def text=(text)
9
+ section_title.text = text
10
+ end
11
+
12
+ def section_title
13
+ @section_title ||= PaddedLabel.alloc.initWithFrame(bounds).tap do |label|
14
+ label.padding = 10
15
+ label.backgroundColor = UIColor.redColor
16
+ label.adjustsFontSizeToFitWidth = true
17
+ label.textColor = UIColor.whiteColor
18
+ label.font = UIFont.fontWithName('Helvetica Neue', size: 20.0)
19
+ end
20
+ end
21
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: motion-form
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Devon Blandin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: motion-keyboard-avoiding
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: RubyMotion Forms made easy.
42
+ email:
43
+ - dblandin@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - README.md
49
+ - lib/motion-form.rb
50
+ - lib/project/cells/base_cell.rb
51
+ - lib/project/cells/button_cell.rb
52
+ - lib/project/cells/text_field_cell.rb
53
+ - lib/project/controllers/form_controller.rb
54
+ - lib/project/form/base.rb
55
+ - lib/project/keyboard_avoiding_delegate.rb
56
+ - lib/project/motion-form.rb
57
+ - lib/project/rows/base_row.rb
58
+ - lib/project/rows/button_row.rb
59
+ - lib/project/rows/text_field_row.rb
60
+ - lib/project/section/section.rb
61
+ - lib/project/string.rb
62
+ - lib/project/views/icon_view.rb
63
+ - lib/project/views/padded_label.rb
64
+ - lib/project/views/section_header_view.rb
65
+ homepage: https://github.com/dblandin/motion-form
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.0.0
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: Simple DSL for RubyMotion form creation
89
+ test_files: []