ProMotion 1.1.2 → 1.2.0
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 +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
|