motion-wizard 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 +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +74 -0
- data/Rakefile +1 -0
- data/lib/motion-wizard.rb +9 -0
- data/lib/motion-wizard/animation_strategy/base_animation_strategy.rb +25 -0
- data/lib/motion-wizard/animation_strategy/ios7_slide_left_to_right.rb +18 -0
- data/lib/motion-wizard/animation_strategy/ios7_slide_right_to_left.rb +18 -0
- data/lib/motion-wizard/animation_strategy/left_to_right.rb +10 -0
- data/lib/motion-wizard/animation_strategy/none.rb +11 -0
- data/lib/motion-wizard/animation_strategy/right_to_left.rb +10 -0
- data/lib/motion-wizard/animation_strategy/slide_animation.rb +21 -0
- data/lib/motion-wizard/controllers/content_controller.rb +17 -0
- data/lib/motion-wizard/controllers/wizard_view_controller.rb +143 -0
- data/lib/motion-wizard/lib/forwardable.rb +12 -0
- data/lib/motion-wizard/views/index_item_view.rb +53 -0
- data/lib/motion-wizard/views/wizard_navigation_bar.rb +55 -0
- data/motion-wizard.gemspec +22 -0
- data/samples/wizard-1/.gitignore +16 -0
- data/samples/wizard-1/Gemfile +8 -0
- data/samples/wizard-1/Rakefile +18 -0
- data/samples/wizard-1/app/app_delegate.rb +8 -0
- data/samples/wizard-1/app/controllers/steps_view_controller.rb +92 -0
- data/samples/wizard-1/app/controllers/wizard_1_view_controller.rb +28 -0
- data/samples/wizard-1/app/views/styles/steps.rb +128 -0
- data/samples/wizard-1/app/views/styles/wizard_1_view_controller.rb +42 -0
- data/samples/wizard-1/resources/Default-568h@2x.png +0 -0
- data/samples/wizard-1/spec/main_spec.rb +9 -0
- data/samples/wizard-2/.gitignore +16 -0
- data/samples/wizard-2/Gemfile +8 -0
- data/samples/wizard-2/Rakefile +22 -0
- data/samples/wizard-2/app/app_delegate.rb +10 -0
- data/samples/wizard-2/app/controllers/steps_view_controller.rb +59 -0
- data/samples/wizard-2/app/controllers/wizard_2_view_controller.rb +29 -0
- data/samples/wizard-2/app/views/my_custom_index_item_view.rb +25 -0
- data/samples/wizard-2/app/views/styles/handlers.rb +7 -0
- data/samples/wizard-2/app/views/styles/index_item.rb +36 -0
- data/samples/wizard-2/app/views/styles/steps.rb +67 -0
- data/samples/wizard-2/app/views/styles/wizard_view_controller.rb +4 -0
- data/samples/wizard-2/resources/Default-568h@2x.png +0 -0
- data/samples/wizard-2/resources/background-568h@2x.png +0 -0
- data/samples/wizard-2/resources/background.png +0 -0
- data/samples/wizard-2/resources/background@2x.png +0 -0
- data/samples/wizard-2/resources/button.png +0 -0
- data/samples/wizard-2/spec/main_spec.rb +9 -0
- data/wizard-1.gif +0 -0
- data/wizard-2.gif +0 -0
- metadata +120 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
module MotionWizard
|
2
|
+
class IndexItem < UIView
|
3
|
+
attr_reader :label, :label_wrapper
|
4
|
+
|
5
|
+
def init
|
6
|
+
super
|
7
|
+
create_label
|
8
|
+
create_label_wrapper
|
9
|
+
@label_wrapper.addSubview(@label)
|
10
|
+
addSubview(@label_wrapper)
|
11
|
+
|
12
|
+
initialize_callbacks
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_label
|
17
|
+
@label = UILabel.alloc.init
|
18
|
+
@label.textAlignment = NSTextAlignmentCenter
|
19
|
+
@label.origin = [0, 0]
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_label_wrapper
|
23
|
+
@label_wrapper = UIView.alloc.init
|
24
|
+
@label_wrapper.origin = [0, 0]
|
25
|
+
@label_wrapper.backgroundColor = UIColor.clearColor
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize_callbacks
|
29
|
+
when_selected do
|
30
|
+
@original_text = @label.text
|
31
|
+
@label.text = "[#{@label.text}]"
|
32
|
+
end
|
33
|
+
|
34
|
+
when_unselected { @label.text = @original_text}
|
35
|
+
end
|
36
|
+
|
37
|
+
def when_selected(&block)
|
38
|
+
@when_selected = block
|
39
|
+
end
|
40
|
+
|
41
|
+
def when_unselected(&block)
|
42
|
+
@when_unselected = block
|
43
|
+
end
|
44
|
+
|
45
|
+
def select
|
46
|
+
@when_selected.call
|
47
|
+
end
|
48
|
+
|
49
|
+
def unselect
|
50
|
+
@when_unselected.call
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module MotionWizard
|
2
|
+
class WizardNavigationBar < UIView
|
3
|
+
def init_with_number_of_steps(number_of_steps, wizard_controller)
|
4
|
+
self.init
|
5
|
+
@number_of_steps = number_of_steps
|
6
|
+
@index_items = []
|
7
|
+
@wizard_controller = WeakRef.new(wizard_controller)
|
8
|
+
create_index_items
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_index_items
|
13
|
+
@number_of_steps.times do |i|
|
14
|
+
index_item = @wizard_controller.create_index_item_at(i)
|
15
|
+
@index_items << index_item
|
16
|
+
addSubview(index_item)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def select(index)
|
21
|
+
@index_items[@selected_step].unselect if @selected_step && @index_items[@selected_step].respond_to?(:unselect)
|
22
|
+
@selected_step = index
|
23
|
+
@index_items[@selected_step].select if @selected_step && @index_items[@selected_step].respond_to?(:select)
|
24
|
+
end
|
25
|
+
|
26
|
+
def setFrame(frame)
|
27
|
+
super
|
28
|
+
resize_indexes
|
29
|
+
end
|
30
|
+
|
31
|
+
def reset!
|
32
|
+
remove_all_index_items
|
33
|
+
create_index_items
|
34
|
+
resize_indexes
|
35
|
+
end
|
36
|
+
|
37
|
+
def remove_all_index_items
|
38
|
+
@index_items.each{|i| i.removeFromSuperview}
|
39
|
+
@index_items.clear
|
40
|
+
end
|
41
|
+
|
42
|
+
def resize_indexes
|
43
|
+
return unless @number_of_steps
|
44
|
+
index_width = (self.frame.size.width).to_f / @number_of_steps
|
45
|
+
@index_items.each_with_index do |index_item, i|
|
46
|
+
index_item.frame = [[index_width*i, 0], [index_width, self.size.height]]
|
47
|
+
setup_index_item_at(index_item, i)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def setup_index_item_at(index_item, i)
|
52
|
+
@wizard_controller.setup_index_item_at(index_item, i)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "motion-wizard"
|
7
|
+
spec.version = "0.1"
|
8
|
+
spec.authors = ["Ignacio Piantanida"]
|
9
|
+
spec.email = ["ijpiantanida@gmail.com"]
|
10
|
+
spec.description = "An small library to create wizard like views controllers"
|
11
|
+
spec.summary = "An small library to create wizard like views"
|
12
|
+
spec.homepage = "https://github.com/ijpiantanida/motion-wizard"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
21
|
+
spec.add_development_dependency "rake"
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
$:.unshift("/Library/RubyMotion/lib")
|
3
|
+
require 'motion/project/template/ios'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'bundler'
|
7
|
+
Bundler.require
|
8
|
+
require 'sugarcube-repl'
|
9
|
+
require 'sugarcube-color'
|
10
|
+
require 'sugarcube-events'
|
11
|
+
require 'sugarcube-constants'
|
12
|
+
rescue LoadError
|
13
|
+
end
|
14
|
+
|
15
|
+
Motion::Project::App.setup do |app|
|
16
|
+
# Use `rake config' to see complete project settings.
|
17
|
+
app.name = 'wizard-1'
|
18
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class AppDelegate
|
2
|
+
def application(application, didFinishLaunchingWithOptions: launchOptions)
|
3
|
+
@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
|
4
|
+
@window.rootViewController = Wizard1ViewController.alloc.init
|
5
|
+
@window.makeKeyAndVisible
|
6
|
+
true
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
class Step1ViewController < UIViewController
|
2
|
+
stylesheet :step_1
|
3
|
+
|
4
|
+
layout :step do
|
5
|
+
@text_field = subview(UITextField, :text_field)
|
6
|
+
@button = subview(UIButton, :button)
|
7
|
+
end
|
8
|
+
|
9
|
+
def viewWillAppear(animated)
|
10
|
+
super
|
11
|
+
@button.on(:touch){ self.next(step_1_text: @text_field.text) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def viewWillDisappear(animated)
|
15
|
+
super
|
16
|
+
@button.off(:touch)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Step2ViewController < UIViewController
|
21
|
+
stylesheet :step_2
|
22
|
+
|
23
|
+
layout :step do
|
24
|
+
@text_field = subview(UITextField, :text_field)
|
25
|
+
@next_button = subview(UIButton, :next_button)
|
26
|
+
@back_button = subview(UIButton, :back_button)
|
27
|
+
end
|
28
|
+
|
29
|
+
def viewWillAppear(animated)
|
30
|
+
super
|
31
|
+
@next_button.on(:touch) {self.next(step_2_text: @text_field.text)}
|
32
|
+
@back_button.on(:touch) {self.previous}
|
33
|
+
end
|
34
|
+
|
35
|
+
def viewWillDisappear(animated)
|
36
|
+
super
|
37
|
+
@next_button.off(:touch)
|
38
|
+
@back_button.off(:touch)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Step3ViewController < UIViewController
|
43
|
+
stylesheet :step_3
|
44
|
+
|
45
|
+
layout :step do
|
46
|
+
subview(UILabel, :label)
|
47
|
+
@next_button = subview(UIButton, :next_button)
|
48
|
+
@back_button = subview(UIButton, :back_button)
|
49
|
+
end
|
50
|
+
|
51
|
+
def viewWillAppear(animated)
|
52
|
+
super
|
53
|
+
@next_button.on(:touch) {self.next}
|
54
|
+
@back_button.on(:touch) {self.previous}
|
55
|
+
end
|
56
|
+
|
57
|
+
def viewWillDisappear(animated)
|
58
|
+
super
|
59
|
+
@next_button.off(:touch)
|
60
|
+
@back_button.off(:touch)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class Step4ViewController < UIViewController
|
65
|
+
stylesheet :step_4
|
66
|
+
|
67
|
+
layout :step do
|
68
|
+
subview(UILabel, :label)
|
69
|
+
@step_1_data = subview(UILabel, :step_1_data)
|
70
|
+
@step_2_data = subview(UILabel, :step_2_data)
|
71
|
+
@reset_button = subview(UIButton, :reset_button)
|
72
|
+
@finish_button = subview(UIButton, :finish_button)
|
73
|
+
@start_over_button = subview(UIButton, :start_over_button)
|
74
|
+
end
|
75
|
+
|
76
|
+
def viewWillAppear(animated)
|
77
|
+
super
|
78
|
+
@step_1_data.text = "Step 1: #{self.wizard_data[:step_1_text]}"
|
79
|
+
@step_2_data.text = "Step 2: #{self.wizard_data[:step_2_text]}"
|
80
|
+
|
81
|
+
@start_over_button.on(:touch) {self.go_to_step(0)}
|
82
|
+
@reset_button.on(:touch) {self.reset!}
|
83
|
+
@finish_button.on(:touch) {self.next}
|
84
|
+
end
|
85
|
+
|
86
|
+
def viewWillDisappear(animated)
|
87
|
+
super
|
88
|
+
@start_over_button.off(:touch)
|
89
|
+
@reset_button.off(:touch)
|
90
|
+
@finish_button.off(:touch)
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class Wizard1ViewController < MotionWizard::WizardViewController
|
2
|
+
steps Step1ViewController,
|
3
|
+
Step2ViewController,
|
4
|
+
Step3ViewController,
|
5
|
+
Step4ViewController
|
6
|
+
|
7
|
+
stylesheet :wizard_view_controller
|
8
|
+
|
9
|
+
layout :wizard_view_controller
|
10
|
+
|
11
|
+
def setup_index_item_at(index_item, index)
|
12
|
+
layout(index_item, :index_item)
|
13
|
+
index_item.when_selected{ index_item.animate_to_stylename(:index_item_selected) }
|
14
|
+
index_item.when_unselected do
|
15
|
+
UIView.animateWithDuration(0.5,
|
16
|
+
animations: -> {
|
17
|
+
layout(index_item, :index_item)
|
18
|
+
}, completion: ->(_){
|
19
|
+
layout(index_item, :index_item_unselected)
|
20
|
+
})
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def when_finished
|
26
|
+
App.alert("Now you can do whatever you like with this #{wizard_data}")
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
Teacup::Stylesheet.new :steps do
|
2
|
+
style :step,
|
3
|
+
backgroundColor: :white.uicolor
|
4
|
+
|
5
|
+
style :big_button,
|
6
|
+
size: ["100% - 40", 35],
|
7
|
+
center_x: "50%",
|
8
|
+
backgroundColor: [103,189,71].uicolor
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
Teacup::Stylesheet.new :step_1 do
|
13
|
+
import :steps
|
14
|
+
|
15
|
+
style :text_field,
|
16
|
+
placeholder: "Put some text here",
|
17
|
+
size: ["100% - 40", 35],
|
18
|
+
top: 130,
|
19
|
+
center_x: "50%",
|
20
|
+
textAlignment: NSTextAlignmentCenter,
|
21
|
+
contentVerticalAlignment: UIControlContentVerticalAlignmentCenter,
|
22
|
+
layer: {
|
23
|
+
borderWidth: 1,
|
24
|
+
cornerRadius: 5
|
25
|
+
}
|
26
|
+
|
27
|
+
style :button,
|
28
|
+
extends: :big_button,
|
29
|
+
title: "And tap here...",
|
30
|
+
top: 180
|
31
|
+
end
|
32
|
+
|
33
|
+
Teacup::Stylesheet.new :step_2 do
|
34
|
+
import :steps
|
35
|
+
|
36
|
+
style :text_field,
|
37
|
+
placeholder: "Also add some text here",
|
38
|
+
size: ["100% - 40", 35],
|
39
|
+
top: 130,
|
40
|
+
center_x: "50%",
|
41
|
+
textAlignment: NSTextAlignmentCenter,
|
42
|
+
contentVerticalAlignment: UIControlContentVerticalAlignmentCenter,
|
43
|
+
layer: {
|
44
|
+
borderWidth: 1,
|
45
|
+
cornerRadius: 5
|
46
|
+
}
|
47
|
+
|
48
|
+
style :base_button,
|
49
|
+
size: ["50% - 40", 35],
|
50
|
+
backgroundColor: [103,189,71].uicolor
|
51
|
+
|
52
|
+
style :next_button,
|
53
|
+
extends: :base_button,
|
54
|
+
title: ">",
|
55
|
+
origin: ["50% + 10", 180]
|
56
|
+
|
57
|
+
style :back_button,
|
58
|
+
extends: :base_button,
|
59
|
+
title: "<",
|
60
|
+
origin: [20, 180]
|
61
|
+
end
|
62
|
+
|
63
|
+
Teacup::Stylesheet.new :step_3 do
|
64
|
+
import :steps
|
65
|
+
|
66
|
+
style :label,
|
67
|
+
text: "Not much to do around here",
|
68
|
+
size: ["100% - 40", 35],
|
69
|
+
top: 130,
|
70
|
+
center_x: "50%",
|
71
|
+
textAlignment: NSTextAlignmentCenter,
|
72
|
+
textColor: [103,189,71].uicolor
|
73
|
+
|
74
|
+
style :base_button,
|
75
|
+
size: ["50% - 40", 35],
|
76
|
+
backgroundColor: [103,189,71].uicolor
|
77
|
+
|
78
|
+
style :next_button,
|
79
|
+
extends: :base_button,
|
80
|
+
title: ">",
|
81
|
+
origin: ["50% + 10", 180]
|
82
|
+
|
83
|
+
style :back_button,
|
84
|
+
extends: :base_button,
|
85
|
+
title: "<",
|
86
|
+
origin: [20, 180]
|
87
|
+
end
|
88
|
+
|
89
|
+
Teacup::Stylesheet.new :step_4 do
|
90
|
+
import :steps
|
91
|
+
|
92
|
+
style :label,
|
93
|
+
text: "End of the journey",
|
94
|
+
size: ["100% - 40", 35],
|
95
|
+
top: 130,
|
96
|
+
center_x: "50%",
|
97
|
+
textAlignment: NSTextAlignmentCenter,
|
98
|
+
textColor: [103,189,71].uicolor
|
99
|
+
|
100
|
+
style :data,
|
101
|
+
size: ["100% - 40", 35],
|
102
|
+
center_x: "50%",
|
103
|
+
textAlignment: NSTextAlignmentCenter,
|
104
|
+
textColor: [103,189,71].uicolor
|
105
|
+
|
106
|
+
style :step_1_data,
|
107
|
+
extends: :data,
|
108
|
+
top: 180
|
109
|
+
|
110
|
+
style :step_2_data,
|
111
|
+
extends: :data,
|
112
|
+
top: 220
|
113
|
+
|
114
|
+
style :reset_button,
|
115
|
+
extends: :big_button,
|
116
|
+
title: "Reset!",
|
117
|
+
top: 320
|
118
|
+
|
119
|
+
style :start_over_button,
|
120
|
+
extends: :big_button,
|
121
|
+
title: "Start over!",
|
122
|
+
top: 360
|
123
|
+
|
124
|
+
style :finish_button,
|
125
|
+
extends: :big_button,
|
126
|
+
title: "Finish",
|
127
|
+
top: 400
|
128
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
Teacup::Stylesheet.new :wizard_view_controller do
|
2
|
+
style :wizard_view_controller,
|
3
|
+
backgroundColor: :white.uicolor
|
4
|
+
|
5
|
+
style :index_item,
|
6
|
+
height: 10,
|
7
|
+
center_y: "100%",
|
8
|
+
backgroundColor: [103,189,71].uicolor,
|
9
|
+
label_wrapper:{
|
10
|
+
backgroundColor: [103,189,71].uicolor,
|
11
|
+
size: [50, 50],
|
12
|
+
center: ["50%", "50%"],
|
13
|
+
layer: {
|
14
|
+
cornerRadius: 25
|
15
|
+
}
|
16
|
+
},
|
17
|
+
label: {
|
18
|
+
backgroundColor: :clear.uicolor,
|
19
|
+
textColor: :white.uicolor,
|
20
|
+
size: ["100%", 20],
|
21
|
+
center: ["50%", "50%"]
|
22
|
+
}
|
23
|
+
|
24
|
+
style :index_item_unseleted,
|
25
|
+
extends: :index_item,
|
26
|
+
layer: {
|
27
|
+
borderWidth: 0
|
28
|
+
}
|
29
|
+
|
30
|
+
style :index_item_selected,
|
31
|
+
label_wrapper:{
|
32
|
+
backgroundColor: :white.uicolor,
|
33
|
+
layer: {
|
34
|
+
borderWidth: 2,
|
35
|
+
borderColor: [103,189,71].uicolor.CGColor
|
36
|
+
}
|
37
|
+
},
|
38
|
+
label: {
|
39
|
+
textColor: [103,189,71].uicolor
|
40
|
+
}
|
41
|
+
|
42
|
+
end
|