motion-form 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []