ProMotion 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +1 -0
- data/ProMotion.gemspec +14 -14
- data/README.md +26 -46
- data/Rakefile +13 -8
- data/lib/ProMotion.rb +2 -12
- data/lib/ProMotion/cocoatouch/navigation_controller.rb +11 -11
- data/lib/ProMotion/cocoatouch/split_view_controller.rb +4 -4
- data/lib/ProMotion/cocoatouch/tab_bar_controller.rb +5 -5
- data/lib/ProMotion/cocoatouch/table_view_cell.rb +2 -0
- data/lib/ProMotion/containers/split_screen.rb +4 -0
- data/lib/ProMotion/containers/tabs.rb +10 -8
- data/lib/ProMotion/delegate/delegate.rb +3 -0
- data/lib/ProMotion/delegate/delegate_module.rb +5 -0
- data/lib/ProMotion/extensions/conversions.rb +4 -4
- data/lib/ProMotion/map/map_screen.rb +4 -0
- data/lib/ProMotion/map/map_screen_module.rb +1 -1
- data/lib/ProMotion/screen/screen.rb +3 -0
- data/lib/ProMotion/screen/screen_module.rb +25 -1
- data/lib/ProMotion/screen/screen_navigation.rb +3 -3
- data/lib/ProMotion/table/cell/table_view_cell_module.rb +19 -3
- data/lib/ProMotion/table/grouped_table_screen.rb +5 -0
- data/lib/ProMotion/table/table.rb +5 -0
- data/lib/ProMotion/table/table_screen.rb +4 -0
- data/lib/ProMotion/version.rb +1 -1
- data/lib/ProMotion/view/styling.rb +22 -9
- data/lib/ProMotion/web/web_screen.rb +4 -0
- data/lib/ProMotion/web/web_screen_module.rb +1 -1
- data/spec/functional/func_image_title_screen.rb +20 -0
- data/spec/functional/func_image_view_title_screen.rb +20 -0
- data/spec/functional/func_screen_spec.rb +4 -0
- data/spec/functional/func_split_screen_spec.rb +7 -0
- data/spec/functional/func_view_title_screen.rb +21 -0
- data/spec/functional/func_web_screen_spec.rb +3 -3
- data/spec/helpers/image_title_screen.rb +15 -0
- data/spec/helpers/image_view_title_screen.rb +15 -0
- data/spec/helpers/map_screen.rb +4 -2
- data/spec/helpers/view_title_screen.rb +15 -0
- data/spec/helpers/web_screen.rb +7 -6
- data/spec/unit/map_spec.rb +10 -9
- data/spec/unit/screen_helpers_spec.rb +11 -7
- data/spec/unit/tables/table_module_spec.rb +1 -1
- data/spec/unit/view_helper_spec.rb +23 -6
- data/spec/unit/web_spec.rb +5 -5
- metadata +56 -47
- data/lib/ProMotion/thirdparty/formotion_screen.rb +0 -92
- data/spec/helpers/table_screen_formotion.rb +0 -50
- data/spec/unit/tables/formotion_screen_spec.rb +0 -37
@@ -1,20 +1,20 @@
|
|
1
1
|
module ProMotion
|
2
2
|
module Conversions
|
3
|
-
|
3
|
+
|
4
4
|
# For converting, for example, from :contacts to UITabBarSystemItemContacts
|
5
5
|
# Unfortunately, this only works if the symbol is defined in your code.
|
6
6
|
# So, for now, we'll have to do it manually.
|
7
7
|
def convert_symbol(symbol, prefix)
|
8
8
|
Object.const_get("#{prefix}#{camel_case symbol}")
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def objective_c_method_name(str)
|
12
12
|
str.split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def camel_case(str)
|
16
16
|
str.split('_').map(&:capitalize).join
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
end
|
20
20
|
end
|
@@ -1,3 +1,8 @@
|
|
1
|
+
motion_require 'screen_navigation'
|
2
|
+
motion_require '../view/styling'
|
3
|
+
motion_require '../containers/tabs'
|
4
|
+
motion_require '../containers/split_screen'
|
5
|
+
|
1
6
|
module ProMotion
|
2
7
|
module ScreenModule
|
3
8
|
include ProMotion::ScreenNavigation
|
@@ -12,9 +17,11 @@ module ProMotion
|
|
12
17
|
raise StandardError.new("ERROR: Screens must extend UIViewController or a subclass of UIViewController.")
|
13
18
|
end
|
14
19
|
|
15
|
-
|
20
|
+
resolve_title
|
21
|
+
|
16
22
|
self.tab_bar_item = self.class.send(:get_tab_bar_item)
|
17
23
|
self.refresh_tab_bar_item if self.tab_bar_item
|
24
|
+
self.class.send(:get_title)
|
18
25
|
|
19
26
|
args.each { |k, v| self.send("#{k}=", v) if self.respond_to?("#{k}=") }
|
20
27
|
|
@@ -48,6 +55,18 @@ module ProMotion
|
|
48
55
|
@navigationController = nav
|
49
56
|
end
|
50
57
|
|
58
|
+
def resolve_title
|
59
|
+
if self.class.send(:get_title).kind_of? String
|
60
|
+
self.title = self.class.send(:get_title)
|
61
|
+
elsif self.class.send(:get_title).kind_of? UIView
|
62
|
+
self.navigationItem.titleView = self.class.send(:get_title)
|
63
|
+
elsif self.class.send(:get_title).kind_of? UIImage
|
64
|
+
self.navigationItem.titleView = UIImageView.alloc.initWithImage(self.class.send(:get_title))
|
65
|
+
else
|
66
|
+
PM.logger.warn("title expects string, UIView, or UIImage, but #{self.class.send(:get_title).class.to_s} given.")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
51
70
|
def add_nav_bar(args = {})
|
52
71
|
self.navigationController ||= begin
|
53
72
|
self.first_screen = true if self.respond_to?(:first_screen=)
|
@@ -120,6 +139,10 @@ module ProMotion
|
|
120
139
|
end
|
121
140
|
end
|
122
141
|
|
142
|
+
def parent_screen=(parent)
|
143
|
+
@parent_screen = WeakRef.new(parent)
|
144
|
+
end
|
145
|
+
|
123
146
|
def first_screen?
|
124
147
|
self.first_screen == true
|
125
148
|
end
|
@@ -282,6 +305,7 @@ module ProMotion
|
|
282
305
|
def title=(t)
|
283
306
|
@title = t
|
284
307
|
end
|
308
|
+
|
285
309
|
def get_title
|
286
310
|
@title ||= self.to_s
|
287
311
|
end
|
@@ -18,7 +18,7 @@ module ProMotion
|
|
18
18
|
open_root_screen screen
|
19
19
|
|
20
20
|
elsif args[:modal]
|
21
|
-
present_modal_view_controller screen, args[:animated]
|
21
|
+
present_modal_view_controller screen, args[:animated], args[:completion]
|
22
22
|
|
23
23
|
elsif args[:in_tab] && self.tab_bar
|
24
24
|
present_view_controller_in_tab_bar_controller screen, args[:in_tab]
|
@@ -117,8 +117,8 @@ module ProMotion
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
-
def present_modal_view_controller(screen, animated)
|
121
|
-
self.
|
120
|
+
def present_modal_view_controller(screen, animated, completion)
|
121
|
+
self.presentViewController((screen.navigationController || screen), animated:animated, completion:completion)
|
122
122
|
end
|
123
123
|
|
124
124
|
def present_view_controller_in_tab_bar_controller(screen, tab_name)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
motion_require '../../view/styling'
|
2
|
+
|
1
3
|
module ProMotion
|
2
4
|
module TableViewCellModule
|
3
5
|
include Styling
|
@@ -63,18 +65,22 @@ module ProMotion
|
|
63
65
|
|
64
66
|
def set_remote_image
|
65
67
|
if data_cell[:remote_image]
|
66
|
-
if self.imageView.respond_to?("setImageWithURL:
|
68
|
+
if self.imageView.respond_to?("setImageWithURL:placeholder:")
|
67
69
|
url = data_cell[:remote_image][:url]
|
68
70
|
url = NSURL.URLWithString(url) unless url.is_a?(NSURL)
|
69
71
|
placeholder = data_cell[:remote_image][:placeholder]
|
70
72
|
placeholder = UIImage.imageNamed(placeholder) if placeholder.is_a?(String)
|
71
73
|
|
72
74
|
self.image_size = data_cell[:remote_image][:size] if data_cell[:remote_image][:size] && self.respond_to?("image_size=")
|
73
|
-
self.imageView.setImageWithURL(url,
|
75
|
+
self.imageView.setImageWithURL(url, placeholder: placeholder)
|
74
76
|
self.imageView.layer.masksToBounds = true
|
75
77
|
self.imageView.layer.cornerRadius = data_cell[:remote_image][:radius] if data_cell[:remote_image].has_key?(:radius)
|
78
|
+
self.imageView.contentMode = map_content_mode_symbol(data_cell[:remote_image][:content_mode]) if data_cell[:remote_image].has_key?(:content_mode)
|
79
|
+
elsif self.imageView.respond_to?("setImageWithURL:placeholderImage:")
|
80
|
+
# TODO - Remove this in next major release
|
81
|
+
PM.logger.deprecated "The SDWebImage cocoapod is deprecated. Please replace it with 'JMImageCache'."
|
76
82
|
else
|
77
|
-
PM.logger.error "ProMotion Warning: to use remote_image with TableScreen you need to include the CocoaPod '
|
83
|
+
PM.logger.error "ProMotion Warning: to use remote_image with TableScreen you need to include the CocoaPod 'JMImageCache'."
|
78
84
|
end
|
79
85
|
end
|
80
86
|
self
|
@@ -152,5 +158,15 @@ module ProMotion
|
|
152
158
|
def set_selection_style
|
153
159
|
self.selectionStyle = UITableViewCellSelectionStyleNone if data_cell[:no_select]
|
154
160
|
end
|
161
|
+
|
162
|
+
def map_content_mode_symbol(symbol)
|
163
|
+
content_mode = {
|
164
|
+
scale_to_fill: UIViewContentModeScaleToFill,
|
165
|
+
scale_aspect_fit: UIViewContentModeScaleAspectFit,
|
166
|
+
scale_aspect_fill: UIViewContentModeScaleAspectFill,
|
167
|
+
mode_redraw: UIViewContentModeRedraw
|
168
|
+
}[symbol] if symbol.is_a?(Symbol)
|
169
|
+
content_mode || symbol
|
170
|
+
end
|
155
171
|
end
|
156
172
|
end
|
data/lib/ProMotion/version.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
motion_require '../extensions/conversions'
|
2
|
+
|
1
3
|
module ProMotion
|
2
4
|
module Styling
|
3
5
|
include Conversions
|
@@ -45,17 +47,28 @@ module ProMotion
|
|
45
47
|
element
|
46
48
|
end
|
47
49
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
50
|
+
def content_max(view, mode = :height)
|
51
|
+
return 0 if view.subviews.empty?
|
52
|
+
|
53
|
+
sizes = view.subviews.map do |sub_view|
|
54
|
+
if sub_view.isHidden
|
55
|
+
0
|
56
|
+
elsif mode == :height
|
57
|
+
sub_view.frame.origin.y + sub_view.frame.size.height
|
58
|
+
else
|
59
|
+
sub_view.frame.origin.x + sub_view.frame.size.width
|
56
60
|
end
|
57
61
|
end
|
58
|
-
|
62
|
+
|
63
|
+
sizes.max
|
64
|
+
end
|
65
|
+
|
66
|
+
def content_height(view)
|
67
|
+
content_max(view, :height)
|
68
|
+
end
|
69
|
+
|
70
|
+
def content_width(view)
|
71
|
+
content_max(view, :width)
|
59
72
|
end
|
60
73
|
|
61
74
|
def closest_parent(type, this_view = nil)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
describe "ProMotion::Screen UIImage title functionality" do
|
2
|
+
tests PM::Screen
|
3
|
+
|
4
|
+
# Override controller to properly instantiate
|
5
|
+
def controller
|
6
|
+
rotate_device to: :portrait, button: :bottom
|
7
|
+
@image_title_screen ||= ImageTitleScreen.new(nav_bar: true)
|
8
|
+
@root_screen = @image_title_screen
|
9
|
+
@image_title_screen.navigationController
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
@controller = nil
|
14
|
+
@root_screen = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should allow an image title" do
|
18
|
+
@root_screen.navigationItem.titleView.should.be.kind_of UIImageView
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
describe "ProMotion::Screen UIImageView title functionality" do
|
2
|
+
tests PM::Screen
|
3
|
+
|
4
|
+
# Override controller to properly instantiate
|
5
|
+
def controller
|
6
|
+
rotate_device to: :portrait, button: :bottom
|
7
|
+
@image_title_screen ||= ImageViewTitleScreen.new(nav_bar: true)
|
8
|
+
@root_screen = @image_title_screen
|
9
|
+
@image_title_screen.navigationController
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
@controller = nil
|
14
|
+
@root_screen = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should allow an image title" do
|
18
|
+
@root_screen.navigationItem.titleView.should.be.kind_of UIImageView
|
19
|
+
end
|
20
|
+
end
|
@@ -18,6 +18,10 @@ describe "ProMotion::Screen functional" do
|
|
18
18
|
view("Functional").should.be.kind_of UINavigationItemView
|
19
19
|
end
|
20
20
|
|
21
|
+
it "should allow a string title" do
|
22
|
+
views(UINavigationItemView).include?(UIImageView).should.not.be.true
|
23
|
+
end
|
24
|
+
|
21
25
|
it "should allow setting a left nav bar button" do
|
22
26
|
@root_screen.set_nav_bar_button :left, title: "Cool", action: :triggered_button
|
23
27
|
tap("Cool")
|
@@ -71,4 +71,11 @@ describe "Split screen functional" do
|
|
71
71
|
@detail.navigationItem.leftBarButtonItem.title.should == test_title
|
72
72
|
end
|
73
73
|
|
74
|
+
it "should override the default swipe action, that reveals the menu" do
|
75
|
+
rotate_device to: :portrait, button: :bottom
|
76
|
+
|
77
|
+
@controller = @app.open_split_screen @master, @detail, swipe: false
|
78
|
+
@app.home_screen.presentsWithGesture.should == false
|
79
|
+
end
|
80
|
+
|
74
81
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
describe "ProMotion::Screen UIView title functionality" do
|
2
|
+
tests PM::Screen
|
3
|
+
|
4
|
+
# Override controller to properly instantiate
|
5
|
+
def controller
|
6
|
+
rotate_device to: :portrait, button: :bottom
|
7
|
+
@image_title_screen ||= ViewTitleScreen.new(nav_bar: true)
|
8
|
+
@root_screen = @image_title_screen
|
9
|
+
@image_title_screen.navigationController
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
@controller = nil
|
14
|
+
@root_screen = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should allow an image title" do
|
18
|
+
@root_screen.navigationItem.titleView.should.not.be.kind_of UIImageView
|
19
|
+
@root_screen.navigationItem.titleView.should.be.kind_of UIView
|
20
|
+
end
|
21
|
+
end
|
@@ -23,7 +23,7 @@ describe "ProMotion::TestWebScreen functionality" do
|
|
23
23
|
@webscreen.set_content(file_name)
|
24
24
|
|
25
25
|
@loaded_file = File.read(File.join(NSBundle.mainBundle.resourcePath, file_name))
|
26
|
-
wait_for_change @webscreen, '
|
26
|
+
wait_for_change @webscreen, 'is_load_finished' do
|
27
27
|
@webscreen.html.delete("\n").should == @loaded_file.delete("\n")
|
28
28
|
end
|
29
29
|
end
|
@@ -33,7 +33,7 @@ describe "ProMotion::TestWebScreen functionality" do
|
|
33
33
|
to_return(body: %q{Google! <form action="/search">%}, content_type: "text/html")
|
34
34
|
|
35
35
|
@webscreen.open_url(NSURL.URLWithString("https://www.google.com/"))
|
36
|
-
wait_for_change @webscreen, '
|
36
|
+
wait_for_change @webscreen, 'is_load_finished' do
|
37
37
|
@webscreen.html.include?('<form action="/search"').should == true
|
38
38
|
end
|
39
39
|
end
|
@@ -41,7 +41,7 @@ describe "ProMotion::TestWebScreen functionality" do
|
|
41
41
|
it "should manipulate the webscreen contents with javascript" do
|
42
42
|
@webscreen.set_content('<h1 id="cool">Something Cool</h1>')
|
43
43
|
|
44
|
-
wait_for_change @webscreen, '
|
44
|
+
wait_for_change @webscreen, 'is_load_finished' do
|
45
45
|
@webscreen.evaluate('document.getElementById("cool").innerHTML = "Changed"')
|
46
46
|
@webscreen.html.should =~ /<h1 id="cool">Changed<\/h1>/
|
47
47
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class ImageTitleScreen < PM::Screen
|
2
|
+
attr_accessor :button_was_triggered
|
3
|
+
|
4
|
+
title UIImage.imageNamed('test.png')
|
5
|
+
|
6
|
+
def will_appear
|
7
|
+
self.button_was_triggered = false
|
8
|
+
add UILabel.alloc.initWithFrame([[ 10, 10 ], [ 300, 40 ]]),
|
9
|
+
text: "Label Here"
|
10
|
+
end
|
11
|
+
|
12
|
+
def triggered_button
|
13
|
+
self.button_was_triggered = true
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class ImageViewTitleScreen < PM::Screen
|
2
|
+
attr_accessor :button_was_triggered
|
3
|
+
|
4
|
+
title UIImageView.alloc.initWithImage(UIImage.imageNamed('test.png'))
|
5
|
+
|
6
|
+
def will_appear
|
7
|
+
self.button_was_triggered = false
|
8
|
+
add UILabel.alloc.initWithFrame([[ 10, 10 ], [ 300, 40 ]]),
|
9
|
+
text: "Label Here"
|
10
|
+
end
|
11
|
+
|
12
|
+
def triggered_button
|
13
|
+
self.button_was_triggered = true
|
14
|
+
end
|
15
|
+
end
|
data/spec/helpers/map_screen.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class TestMapScreen < PM::MapScreen
|
2
2
|
|
3
|
-
attr_accessor :infinite_loop_points
|
3
|
+
attr_accessor :infinite_loop_points, :request_complete
|
4
4
|
|
5
5
|
start_position latitude: 35.090648651123, longitude: -82.965972900391, radius: 4
|
6
6
|
title "Gorges State Park, NC"
|
@@ -43,7 +43,9 @@ class TestMapScreen < PM::MapScreen
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def lookup_infinite_loop
|
46
|
-
|
46
|
+
self.request_complete = false
|
47
|
+
self.look_up_address address: "1 Infinite Loop" do |points, error|
|
48
|
+
self.request_complete = true
|
47
49
|
self.infinite_loop_points = points
|
48
50
|
end
|
49
51
|
end
|