ProMotion 1.2.1 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +36 -10
- data/lib/ProMotion.rb +11 -2
- data/lib/ProMotion/cocoatouch/ns_string.rb +5 -0
- data/lib/ProMotion/cocoatouch/ns_url.rb +5 -0
- data/lib/ProMotion/cocoatouch/tab_bar_controller.rb +5 -7
- data/lib/ProMotion/cocoatouch/table_view_cell.rb +0 -16
- data/lib/ProMotion/cocoatouch/table_view_controller.rb +2 -3
- data/lib/ProMotion/cocoatouch/view_controller.rb +3 -6
- data/lib/ProMotion/delegate/delegate.rb +0 -3
- data/lib/ProMotion/delegate/delegate_module.rb +24 -20
- data/lib/ProMotion/{containers → ipad}/split_screen.rb +30 -32
- data/lib/ProMotion/{logger.rb → logger/logger.rb} +6 -5
- data/lib/ProMotion/screen/nav_bar_module.rb +126 -0
- data/lib/ProMotion/screen/screen.rb +0 -3
- data/lib/ProMotion/screen/screen_module.rb +54 -177
- data/lib/ProMotion/screen/screen_navigation.rb +29 -40
- data/lib/ProMotion/{view → styling}/styling.rb +17 -47
- data/lib/ProMotion/table/cell/table_view_cell_module.rb +76 -123
- data/lib/ProMotion/table/data/table_data.rb +1 -1
- data/lib/ProMotion/table/extensions/longpressable.rb +24 -0
- data/lib/ProMotion/table/extensions/refreshable.rb +1 -0
- data/lib/ProMotion/table/grouped_table_screen.rb +0 -5
- data/lib/ProMotion/table/table.rb +63 -83
- data/lib/ProMotion/table/table_screen.rb +0 -4
- data/lib/ProMotion/{containers → tabs}/tabs.rb +20 -21
- data/lib/ProMotion/version.rb +1 -1
- data/lib/ProMotion/web/web_screen.rb +0 -4
- data/lib/ProMotion/web/web_screen_module.rb +8 -5
- data/spec/functional/func_screen_spec.rb +14 -18
- data/spec/functional/func_split_screen_spec.rb +2 -2
- data/spec/functional/func_table_screen_spec.rb +54 -40
- data/spec/functional/func_web_screen_spec.rb +12 -17
- data/spec/helpers/test_helper.rb +27 -0
- data/spec/unit/delegate_spec.rb +4 -67
- data/spec/unit/image_title_screen.rb +9 -0
- data/spec/unit/image_view_title_screen.rb +9 -0
- data/spec/unit/load_view_spec.rb +27 -0
- data/spec/unit/main_spec.rb +0 -6
- data/spec/unit/screen_helpers_spec.rb +23 -17
- data/spec/unit/screen_spec.rb +21 -17
- data/spec/unit/searchable_table_spec.rb +55 -0
- data/spec/unit/split_screen_in_tab_bar_spec.rb +5 -5
- data/spec/unit/split_screen_spec.rb +4 -4
- data/spec/unit/tab_bar_spec.rb +79 -0
- data/spec/unit/tab_spec.rb +11 -5
- data/spec/unit/tables/table_module_spec.rb +22 -8
- data/spec/unit/tables/table_screen_spec.rb +1 -1
- data/spec/unit/tables/table_view_cell_spec.rb +16 -16
- data/spec/unit/view_helper_spec.rb +6 -81
- data/spec/unit/view_title_screen.rb +10 -0
- data/spec/unit/web_spec.rb +31 -37
- metadata +37 -111
- data/.gitignore +0 -33
- data/.travis.yml +0 -4
- data/CONTRIBUTING.md +0 -20
- data/Gemfile +0 -5
- data/LICENSE +0 -22
- data/ProMotion.gemspec +0 -30
- data/Rakefile +0 -66
- data/app/app_delegate.rb +0 -7
- data/app/screens/basic_screen.rb +0 -15
- data/lib/ProMotion/delegate/delegate_notifications.rb +0 -70
- data/lib/ProMotion/extensions/conversions.rb +0 -20
- data/lib/ProMotion/map/map_screen.rb +0 -10
- data/lib/ProMotion/map/map_screen_annotation.rb +0 -65
- data/lib/ProMotion/map/map_screen_module.rb +0 -212
- data/lib/ProMotion/push_notification/push_notification.rb +0 -58
- data/resources/WebScreen.html +0 -6
- data/resources/list.png +0 -0
- data/resources/test.png +0 -0
- data/spec/functional/func_image_title_screen.rb +0 -20
- data/spec/functional/func_image_view_title_screen.rb +0 -20
- data/spec/functional/func_map_screen_spec.rb +0 -162
- data/spec/functional/func_searchable_table_spec.rb +0 -56
- data/spec/functional/func_tab_bar_spec.rb +0 -78
- data/spec/functional/func_view_title_screen.rb +0 -21
- data/spec/helpers/basic_screen.rb +0 -3
- data/spec/helpers/custom_title_view.rb +0 -4
- data/spec/helpers/detail_screen.rb +0 -3
- data/spec/helpers/dummy_class.rb +0 -3
- data/spec/helpers/functional_screen.rb +0 -15
- data/spec/helpers/home_screen.rb +0 -19
- data/spec/helpers/image_title_screen.rb +0 -15
- data/spec/helpers/image_view_title_screen.rb +0 -15
- data/spec/helpers/map_screen.rb +0 -53
- data/spec/helpers/master_screen.rb +0 -3
- data/spec/helpers/present_screen.rb +0 -26
- data/spec/helpers/screen_module_view_controller.rb +0 -55
- data/spec/helpers/tab_screen.rb +0 -4
- data/spec/helpers/table_screen.rb +0 -117
- data/spec/helpers/table_screen_indexable.rb +0 -18
- data/spec/helpers/table_screen_refreshable.rb +0 -11
- data/spec/helpers/table_screen_searchable.rb +0 -72
- data/spec/helpers/test_delegate.rb +0 -34
- data/spec/helpers/test_delegate_colors.rb +0 -17
- data/spec/helpers/view_title_screen.rb +0 -15
- data/spec/helpers/web_screen.rb +0 -23
- data/spec/unit/map_spec.rb +0 -71
@@ -1,9 +1,5 @@
|
|
1
|
-
motion_require '../extensions/conversions'
|
2
|
-
|
3
1
|
module ProMotion
|
4
2
|
module Styling
|
5
|
-
include Conversions
|
6
|
-
|
7
3
|
def set_attributes(element, args = {})
|
8
4
|
args = get_attributes_from_symbol(args)
|
9
5
|
args.each { |k, v| set_attribute(element, k, v) }
|
@@ -13,7 +9,9 @@ module ProMotion
|
|
13
9
|
def set_attribute(element, k, v)
|
14
10
|
return element unless element
|
15
11
|
|
16
|
-
if v.is_a?(Hash) && element.respond_to?(k)
|
12
|
+
if !element.is_a?(CALayer) && v.is_a?(Hash) && element.respond_to?("#{k}=")
|
13
|
+
element.send("#{k}=", v)
|
14
|
+
elsif v.is_a?(Hash) && element.respond_to?(k)
|
17
15
|
sub_element = element.send(k)
|
18
16
|
set_attributes(sub_element, v) if sub_element
|
19
17
|
elsif element.respond_to?("#{k}=")
|
@@ -22,35 +20,13 @@ module ProMotion
|
|
22
20
|
element.send("#{k}", *v)
|
23
21
|
else
|
24
22
|
# Doesn't respond. Check if snake case.
|
25
|
-
if k.to_s.include?("_")
|
26
|
-
set_attribute(element, objective_c_method_name(k), v)
|
27
|
-
end
|
23
|
+
set_attribute(element, camelize(k), v) if k.to_s.include?("_")
|
28
24
|
end
|
29
25
|
element
|
30
26
|
end
|
31
27
|
|
32
|
-
def set_easy_attributes(parent, element, args={})
|
33
|
-
attributes = {}
|
34
|
-
|
35
|
-
if args[:resize]
|
36
|
-
attributes[:autoresizingMask] = UIViewAutoresizingNone
|
37
|
-
args[:resize].each { |r| attributes[:autoresizingMask] |= map_resize_symbol(r) }
|
38
|
-
end
|
39
|
-
|
40
|
-
args[:left] = args.delete(:x) if args[:x]
|
41
|
-
args[:top] = args.delete(:y) if args[:y]
|
42
|
-
if [:left, :top, :width, :height].select{ |a| args[a] && args[a] != :auto }.length == 4
|
43
|
-
attributes[:frame] = CGRectMake(args[:left], args[:top], args[:width], args[:height])
|
44
|
-
end
|
45
|
-
|
46
|
-
set_attributes element, attributes
|
47
|
-
element
|
48
|
-
end
|
49
|
-
|
50
28
|
def content_max(view, mode = :height)
|
51
|
-
|
52
|
-
|
53
|
-
sizes = view.subviews.map do |sub_view|
|
29
|
+
view.subviews.map do |sub_view|
|
54
30
|
if sub_view.isHidden
|
55
31
|
0
|
56
32
|
elsif mode == :height
|
@@ -58,9 +34,7 @@ module ProMotion
|
|
58
34
|
else
|
59
35
|
sub_view.frame.origin.x + sub_view.frame.size.width
|
60
36
|
end
|
61
|
-
end
|
62
|
-
|
63
|
-
sizes.max
|
37
|
+
end.max.to_f
|
64
38
|
end
|
65
39
|
|
66
40
|
def content_height(view)
|
@@ -71,8 +45,9 @@ module ProMotion
|
|
71
45
|
content_max(view, :width)
|
72
46
|
end
|
73
47
|
|
48
|
+
# iterate up the view hierarchy to find the parent element
|
49
|
+
# of "type" containing this view
|
74
50
|
def closest_parent(type, this_view = nil)
|
75
|
-
# iterate up the view hierarchy to find the parent element of "type" containing this view
|
76
51
|
this_view ||= view_or_self.superview
|
77
52
|
while this_view != nil do
|
78
53
|
return this_view if this_view.is_a? type
|
@@ -84,23 +59,16 @@ module ProMotion
|
|
84
59
|
def add(element, attrs = {})
|
85
60
|
add_to view_or_self, element, attrs
|
86
61
|
end
|
87
|
-
alias :add_element :add
|
88
|
-
alias :add_view :add
|
89
62
|
|
90
63
|
def remove(elements)
|
91
64
|
Array(elements).each(&:removeFromSuperview)
|
92
65
|
end
|
93
|
-
alias :remove_element :remove
|
94
|
-
alias :remove_view :remove
|
95
66
|
|
96
67
|
def add_to(parent_element, elements, attrs = {})
|
97
68
|
attrs = get_attributes_from_symbol(attrs)
|
98
69
|
Array(elements).each do |element|
|
99
70
|
parent_element.addSubview element
|
100
|
-
if attrs && attrs.length > 0
|
101
|
-
set_attributes(element, attrs)
|
102
|
-
set_easy_attributes(parent_element, element, attrs)
|
103
|
-
end
|
71
|
+
set_attributes(element, attrs) if attrs && attrs.length > 0
|
104
72
|
end
|
105
73
|
elements
|
106
74
|
end
|
@@ -130,14 +98,16 @@ module ProMotion
|
|
130
98
|
raise ArgumentError
|
131
99
|
end
|
132
100
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
101
|
+
raise ArgumentError unless colors.size == 3
|
102
|
+
rgb_color(colors[0], colors[1], colors[2])
|
103
|
+
end
|
104
|
+
|
105
|
+
# Turns a snake_case string into a camelCase string.
|
106
|
+
def camelize(str)
|
107
|
+
str.split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
|
138
108
|
end
|
139
109
|
|
140
|
-
|
110
|
+
protected
|
141
111
|
|
142
112
|
def get_attributes_from_symbol(attrs)
|
143
113
|
return attrs if attrs.is_a?(Hash)
|
@@ -1,5 +1,3 @@
|
|
1
|
-
motion_require '../../view/styling'
|
2
|
-
|
3
1
|
module ProMotion
|
4
2
|
module TableViewCellModule
|
5
3
|
include Styling
|
@@ -10,163 +8,118 @@ module ProMotion
|
|
10
8
|
self.table_screen = WeakRef.new(screen)
|
11
9
|
self.data_cell = data_cell
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
check_deprecated_styles
|
12
|
+
set_styles
|
13
|
+
set_title
|
16
14
|
set_subtitle
|
17
15
|
set_image
|
18
16
|
set_remote_image
|
19
|
-
|
20
|
-
set_details
|
21
|
-
set_styles
|
17
|
+
set_accessory_view
|
22
18
|
set_selection_style
|
23
|
-
|
24
|
-
self
|
25
19
|
end
|
26
20
|
|
27
|
-
|
28
|
-
data_cell_attributes = data_cell.dup
|
29
|
-
[:image, :accessory_action, :editing_style].each { |k| data_cell_attributes.delete(k) }
|
30
|
-
set_attributes self, data_cell_attributes
|
31
|
-
self
|
32
|
-
end
|
21
|
+
protected
|
33
22
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
switch_view.addTarget(self.table_screen, action: "accessory_toggled_switch:", forControlEvents:UIControlEventValueChanged)
|
40
|
-
switch_view.on = !!data_cell[:accessory][:value]
|
41
|
-
self.accessoryView = switch_view
|
42
|
-
elsif data_cell[:accessory][:view]
|
43
|
-
self.accessoryView = data_cell[:accessory][:view]
|
44
|
-
self.accessoryView.autoresizingMask = UIViewAutoresizingFlexibleWidth
|
45
|
-
end
|
46
|
-
else
|
47
|
-
self.accessoryView = nil
|
23
|
+
# TODO: Remove this in ProMotion 2.1. Just for migration purposes.
|
24
|
+
def check_deprecated_styles
|
25
|
+
whitelist = [ :title, :subtitle, :image, :remote_image, :accessory, :selection_style, :action, :arguments, :cell_style, :cell_class, :cell_identifier, :editing_style, :search_text, :keep_selection, :height ]
|
26
|
+
if (data_cell.keys - whitelist).length > 0
|
27
|
+
PM.logger.deprecated("In #{self.table_screen.class.to_s}#table_data, you should set :#{(data_cell.keys - whitelist).join(", :")} in a `styles:` hash. See TableScreen documentation.")
|
48
28
|
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_styles
|
32
|
+
set_attributes self, data_cell[:style] if data_cell[:style]
|
33
|
+
end
|
49
34
|
|
50
|
-
|
35
|
+
def set_title
|
36
|
+
set_attributed_text(self.textLabel, data_cell[:title])
|
51
37
|
end
|
52
38
|
|
53
39
|
def set_subtitle
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
self.detailTextLabel.text = data_cell[:subtitle]
|
59
|
-
end
|
60
|
-
self.detailTextLabel.backgroundColor = UIColor.clearColor
|
61
|
-
self.detailTextLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth
|
62
|
-
end
|
63
|
-
self
|
40
|
+
return unless data_cell[:subtitle] && self.detailTextLabel
|
41
|
+
set_attributed_text(self.detailTextLabel, data_cell[:subtitle])
|
42
|
+
self.detailTextLabel.backgroundColor = UIColor.clearColor
|
43
|
+
self.detailTextLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth
|
64
44
|
end
|
65
45
|
|
66
46
|
def set_remote_image
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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'."
|
82
|
-
else
|
83
|
-
PM.logger.error "ProMotion Warning: to use remote_image with TableScreen you need to include the CocoaPod 'JMImageCache'."
|
84
|
-
end
|
85
|
-
end
|
86
|
-
self
|
47
|
+
return unless data_cell[:remote_image] && jm_image_cache?
|
48
|
+
|
49
|
+
self.imageView.image = remote_placeholder
|
50
|
+
JMImageCache.sharedCache.imageForURL(data_cell[:remote_image][:url].to_url, completionBlock:proc { |downloaded_image|
|
51
|
+
self.imageView.image = downloaded_image
|
52
|
+
self.setNeedsLayout
|
53
|
+
})
|
54
|
+
|
55
|
+
self.imageView.layer.masksToBounds = true
|
56
|
+
self.imageView.layer.cornerRadius = data_cell[:remote_image][:radius] if data_cell[:remote_image][:radius]
|
57
|
+
self.imageView.contentMode = map_content_mode_symbol(data_cell[:remote_image][:content_mode]) if data_cell[:remote_image][:content_mode]
|
87
58
|
end
|
88
59
|
|
89
60
|
def set_image
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
61
|
+
return unless data_cell[:image]
|
62
|
+
cell_image = data_cell[:image].is_a?(Hash) ? data_cell[:image][:image] : data_cell[:image]
|
63
|
+
cell_image = UIImage.imageNamed(cell_image) if cell_image.is_a?(String)
|
64
|
+
self.imageView.layer.masksToBounds = true
|
65
|
+
self.imageView.image = cell_image
|
66
|
+
self.imageView.layer.cornerRadius = data_cell[:image][:radius] if data_cell[:image].is_a?(Hash) && data_cell[:image][:radius]
|
67
|
+
end
|
94
68
|
|
95
|
-
|
96
|
-
|
97
|
-
|
69
|
+
def set_accessory_view
|
70
|
+
return self.accessoryView = nil unless data_cell[:accessory] && data_cell[:accessory][:view]
|
71
|
+
if data_cell[:accessory][:view] == :switch
|
72
|
+
self.accessoryView = switch_view
|
73
|
+
else
|
74
|
+
self.accessoryView = data_cell[:accessory][:view]
|
75
|
+
self.accessoryView.autoresizingMask = UIViewAutoresizingFlexibleWidth
|
98
76
|
end
|
99
|
-
self
|
100
77
|
end
|
101
78
|
|
102
|
-
def
|
103
|
-
|
104
|
-
Array(data_cell[:subviews]).each do |view|
|
105
|
-
# Remove an existing view at that tag number
|
106
|
-
tag_number += 1
|
107
|
-
existing_view = self.viewWithTag(tag_number)
|
108
|
-
existing_view.removeFromSuperview if existing_view
|
109
|
-
|
110
|
-
# Add the subview if it exists
|
111
|
-
if view
|
112
|
-
view.tag = tag_number
|
113
|
-
self.addSubview view
|
114
|
-
end
|
115
|
-
end
|
116
|
-
self
|
79
|
+
def set_selection_style
|
80
|
+
self.selectionStyle = map_selection_style_symbol(data_cell[:selection_style]) if data_cell[:selection_style]
|
117
81
|
end
|
118
82
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
83
|
+
private
|
84
|
+
|
85
|
+
def jm_image_cache?
|
86
|
+
return true if self.imageView.respond_to?("setImageWithURL:placeholder:")
|
87
|
+
PM.logger.error "ProMotion Warning: to use remote_image with TableScreen you need to include the CocoaPod 'JMImageCache'."
|
88
|
+
false
|
124
89
|
end
|
125
90
|
|
126
|
-
def
|
127
|
-
|
128
|
-
|
129
|
-
self.contentView.subviews.each do |view|
|
130
|
-
if view.is_a? UILabel
|
131
|
-
ui_label = true
|
132
|
-
view.text = data_cell[:styles][:label][:text]
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
unless ui_label == true
|
137
|
-
label ||= UILabel.alloc.initWithFrame(CGRectZero)
|
138
|
-
set_attributes label, data_cell[:styles][:label]
|
139
|
-
self.contentView.addSubview label
|
140
|
-
end
|
141
|
-
|
142
|
-
# TODO: What is this and why is it necessary?
|
143
|
-
self.textLabel.textColor = UIColor.clearColor
|
144
|
-
else
|
145
|
-
cell_title = data_cell[:title]
|
146
|
-
cell_title ||= ""
|
147
|
-
self.textLabel.backgroundColor = UIColor.clearColor
|
148
|
-
if cell_title.is_a? NSAttributedString
|
149
|
-
self.textLabel.attributedText = cell_title
|
150
|
-
else
|
151
|
-
self.textLabel.text = cell_title
|
152
|
-
end
|
153
|
-
end
|
91
|
+
def remote_placeholder
|
92
|
+
UIImage.imageNamed(data_cell[:remote_image][:placeholder]) if data_cell[:remote_image][:placeholder].is_a?(String)
|
93
|
+
end
|
154
94
|
|
155
|
-
|
95
|
+
def switch_view
|
96
|
+
switch = UISwitch.alloc.initWithFrame(CGRectZero)
|
97
|
+
switch.setAccessibilityLabel(data_cell[:accessory][:accessibility_label] || data_cell[:title])
|
98
|
+
switch.addTarget(self.table_screen, action: "accessory_toggled_switch:", forControlEvents:UIControlEventValueChanged)
|
99
|
+
switch.on = !!data_cell[:accessory][:value]
|
100
|
+
switch
|
156
101
|
end
|
157
102
|
|
158
|
-
def
|
159
|
-
|
103
|
+
def set_attributed_text(label, text)
|
104
|
+
text.is_a?(NSAttributedString) ? label.attributedText = text : label.text = text
|
160
105
|
end
|
161
106
|
|
162
107
|
def map_content_mode_symbol(symbol)
|
163
|
-
|
108
|
+
{
|
164
109
|
scale_to_fill: UIViewContentModeScaleToFill,
|
165
110
|
scale_aspect_fit: UIViewContentModeScaleAspectFit,
|
166
111
|
scale_aspect_fill: UIViewContentModeScaleAspectFill,
|
167
112
|
mode_redraw: UIViewContentModeRedraw
|
168
|
-
}[symbol]
|
169
|
-
|
113
|
+
}[symbol] || symbol
|
114
|
+
end
|
115
|
+
|
116
|
+
def map_selection_style_symbol(symbol)
|
117
|
+
{
|
118
|
+
none: UITableViewCellSelectionStyleNone,
|
119
|
+
blue: UITableViewCellSelectionStyleBlue,
|
120
|
+
gray: UITableViewCellSelectionStyleGray,
|
121
|
+
default: UITableViewCellSelectionStyleDefault
|
122
|
+
}[symbol] || symbol
|
170
123
|
end
|
171
124
|
end
|
172
125
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module ProMotion
|
2
|
+
module Table
|
3
|
+
module Longpressable
|
4
|
+
def make_longpressable(params={})
|
5
|
+
params = {
|
6
|
+
min_duration: 1.0
|
7
|
+
}.merge(params)
|
8
|
+
|
9
|
+
long_press_gesture = UILongPressGestureRecognizer.alloc.initWithTarget(self, action:"on_long_press:")
|
10
|
+
long_press_gesture.minimumPressDuration = params[:min_duration]
|
11
|
+
long_press_gesture.delegate = self
|
12
|
+
self.table_view.addGestureRecognizer(long_press_gesture)
|
13
|
+
end
|
14
|
+
|
15
|
+
def on_long_press(gesture)
|
16
|
+
return unless gesture.state == UIGestureRecognizerStateBegan
|
17
|
+
gesture_point = gesture.locationInView(table_view)
|
18
|
+
index_path = table_view.indexPathForRowAtPoint(gesture_point)
|
19
|
+
data_cell = self.promotion_table_data.cell(index_path: index_path)
|
20
|
+
trigger_action(data_cell[:long_press_action], data_cell[:arguments]) if data_cell[:long_press_action]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,15 +1,10 @@
|
|
1
|
-
motion_require '../view/styling'
|
2
|
-
motion_require 'extensions/searchable'
|
3
|
-
motion_require 'extensions/refreshable'
|
4
|
-
motion_require 'extensions/indexable'
|
5
|
-
|
6
1
|
module ProMotion
|
7
2
|
module Table
|
8
|
-
|
9
3
|
include ProMotion::Styling
|
10
4
|
include ProMotion::Table::Searchable
|
11
5
|
include ProMotion::Table::Refreshable
|
12
6
|
include ProMotion::Table::Indexable
|
7
|
+
include ProMotion::Table::Longpressable
|
13
8
|
|
14
9
|
attr_reader :promotion_table_data
|
15
10
|
|
@@ -21,6 +16,7 @@ module ProMotion
|
|
21
16
|
check_table_data
|
22
17
|
set_up_searchable
|
23
18
|
set_up_refreshable
|
19
|
+
set_up_longpressable
|
24
20
|
end
|
25
21
|
|
26
22
|
def check_table_data
|
@@ -47,6 +43,12 @@ module ProMotion
|
|
47
43
|
end
|
48
44
|
end
|
49
45
|
|
46
|
+
def set_up_longpressable
|
47
|
+
if self.class.respond_to?(:get_longpressable) && self.class.get_longpressable
|
48
|
+
self.make_longpressable(self.class.get_longpressable_params)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
50
52
|
def searching?
|
51
53
|
self.promotion_table_data.filtered
|
52
54
|
end
|
@@ -62,31 +64,13 @@ module ProMotion
|
|
62
64
|
def update_table_view_data(data)
|
63
65
|
self.promotion_table_data.data = data
|
64
66
|
table_view.reloadData
|
65
|
-
|
66
|
-
|
67
|
-
# Methods to retrieve data
|
68
|
-
|
69
|
-
def section_at_index(index)
|
70
|
-
self.promotion_table_data.section(index)
|
71
|
-
end
|
72
|
-
|
73
|
-
def cell_at_section_and_index(section, index)
|
74
|
-
self.promotion_table_data.cell(section: section, index: index)
|
67
|
+
@table_search_display_controller.searchResultsTableView.reloadData if searching?
|
75
68
|
end
|
76
69
|
|
77
70
|
def trigger_action(action, arguments)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
self.send(action)
|
82
|
-
elsif expected_arguments == 1 || expected_arguments == -1
|
83
|
-
self.send(action, arguments)
|
84
|
-
else
|
85
|
-
PM.logger.warn "#{action} expects #{expected_arguments} arguments. Maximum number of required arguments for an action is 1."
|
86
|
-
end
|
87
|
-
else
|
88
|
-
PM.logger.info "Action not implemented: #{action.to_s}"
|
89
|
-
end
|
71
|
+
return PM.logger.info "Action not implemented: #{action.to_s}" unless self.respond_to?(action)
|
72
|
+
return self.send(action) if self.method(action).arity == 0
|
73
|
+
self.send(action, arguments)
|
90
74
|
end
|
91
75
|
|
92
76
|
def accessory_toggled_switch(switch)
|
@@ -94,20 +78,16 @@ module ProMotion
|
|
94
78
|
index_path = closest_parent(UITableView, table_cell).indexPathForCell(table_cell)
|
95
79
|
|
96
80
|
if index_path
|
97
|
-
data_cell =
|
81
|
+
data_cell = promotion_table_data.cell(section: index_path.section, index: index_path.row)
|
98
82
|
data_cell[:accessory][:arguments] ||= {}
|
99
83
|
data_cell[:accessory][:arguments][:value] = switch.isOn if data_cell[:accessory][:arguments].is_a?(Hash)
|
100
|
-
|
101
84
|
trigger_action(data_cell[:accessory][:action], data_cell[:accessory][:arguments]) if data_cell[:accessory][:action]
|
102
85
|
end
|
103
86
|
end
|
104
87
|
|
105
88
|
def delete_row(index_paths, animation = nil)
|
106
|
-
animation = map_row_animation_symbol(animation)
|
107
|
-
index_paths = [index_paths] if index_paths.kind_of?(NSIndexPath)
|
108
89
|
deletable_index_paths = []
|
109
|
-
|
110
|
-
index_paths.each do |index_path|
|
90
|
+
Array(index_paths).each do |index_path|
|
111
91
|
delete_cell = false
|
112
92
|
delete_cell = send(:on_cell_deleted, self.promotion_table_data.cell(index_path: index_path)) if self.respond_to?("on_cell_deleted:")
|
113
93
|
unless delete_cell == false
|
@@ -115,45 +95,44 @@ module ProMotion
|
|
115
95
|
deletable_index_paths << index_path
|
116
96
|
end
|
117
97
|
end
|
118
|
-
table_view.deleteRowsAtIndexPaths(deletable_index_paths, withRowAnimation:animation) if deletable_index_paths.length > 0
|
98
|
+
table_view.deleteRowsAtIndexPaths(deletable_index_paths, withRowAnimation:map_row_animation_symbol(animation)) if deletable_index_paths.length > 0
|
119
99
|
end
|
120
100
|
|
121
101
|
def table_view_cell(params={})
|
102
|
+
params = index_path_to_section_index(params)
|
103
|
+
data_cell = self.promotion_table_data.cell(section: params[:section], index: params[:index])
|
104
|
+
return UITableViewCell.alloc.init unless data_cell
|
105
|
+
create_table_cell(data_cell)
|
106
|
+
end
|
107
|
+
|
108
|
+
def index_path_to_section_index(params)
|
122
109
|
if params[:index_path]
|
123
110
|
params[:section] = params[:index_path].section
|
124
111
|
params[:index] = params[:index_path].row
|
125
112
|
end
|
126
|
-
|
127
|
-
data_cell = self.promotion_table_data.cell(section: params[:section], index: params[:index])
|
128
|
-
return UITableViewCell.alloc.init unless data_cell # No data?
|
129
|
-
|
130
|
-
table_cell = create_table_cell(data_cell)
|
131
|
-
|
132
|
-
table_cell
|
113
|
+
params
|
133
114
|
end
|
134
115
|
|
135
116
|
def create_table_cell(data_cell)
|
136
|
-
table_cell = table_view.dequeueReusableCellWithIdentifier(data_cell[:cell_identifier])
|
137
|
-
|
138
|
-
unless table_cell
|
117
|
+
table_cell = table_view.dequeueReusableCellWithIdentifier(data_cell[:cell_identifier]) || begin
|
139
118
|
table_cell = data_cell[:cell_class].alloc.initWithStyle(data_cell[:cell_style], reuseIdentifier:data_cell[:cell_identifier])
|
140
|
-
table_cell.extend
|
119
|
+
table_cell.extend(PM::TableViewCellModule) unless table_cell.is_a?(PM::TableViewCellModule)
|
141
120
|
table_cell.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin
|
142
121
|
table_cell.clipsToBounds = true # fix for changed default in 7.1
|
122
|
+
table_cell
|
143
123
|
end
|
144
|
-
|
145
124
|
table_cell.setup(data_cell, self)
|
146
|
-
|
147
125
|
table_cell
|
148
126
|
end
|
149
127
|
|
150
128
|
def update_table_data
|
151
129
|
self.update_table_view_data(self.table_data)
|
130
|
+
self.promotion_table_data.search(search_string) if searching?
|
152
131
|
end
|
153
132
|
|
154
133
|
########## Cocoa touch methods #################
|
155
134
|
def numberOfSectionsInTableView(table_view)
|
156
|
-
|
135
|
+
self.promotion_table_data.sections.length
|
157
136
|
end
|
158
137
|
|
159
138
|
# Number of cells
|
@@ -162,8 +141,8 @@ module ProMotion
|
|
162
141
|
end
|
163
142
|
|
164
143
|
def tableView(table_view, titleForHeaderInSection:section)
|
165
|
-
section =
|
166
|
-
section[:title]
|
144
|
+
section = promotion_table_data.section(section)
|
145
|
+
section && section[:title]
|
167
146
|
end
|
168
147
|
|
169
148
|
# Set table_data_index if you want the right hand index column (jumplist)
|
@@ -179,8 +158,9 @@ module ProMotion
|
|
179
158
|
|
180
159
|
def tableView(table_view, willDisplayCell: table_cell, forRowAtIndexPath: index_path)
|
181
160
|
data_cell = self.promotion_table_data.cell(index_path: index_path)
|
182
|
-
table_cell
|
183
|
-
table_cell.send(:
|
161
|
+
set_attributes table_cell, data_cell[:style] if data_cell[:style]
|
162
|
+
table_cell.send(:will_display) if table_cell.respond_to?(:will_display)
|
163
|
+
table_cell.send(:restyle!) if table_cell.respond_to?(:restyle!) # Teacup compatibility
|
184
164
|
end
|
185
165
|
|
186
166
|
def tableView(table_view, heightForRowAtIndexPath:index_path)
|
@@ -190,26 +170,12 @@ module ProMotion
|
|
190
170
|
def tableView(table_view, didSelectRowAtIndexPath:index_path)
|
191
171
|
data_cell = self.promotion_table_data.cell(index_path: index_path)
|
192
172
|
table_view.deselectRowAtIndexPath(index_path, animated: true) unless data_cell[:keep_selection] == true
|
193
|
-
|
194
|
-
data_cell[:arguments] ||= {}
|
195
|
-
data_cell[:arguments][:cell] = data_cell if data_cell[:arguments].is_a?(Hash) # TODO: Should we really do this?
|
196
|
-
|
197
173
|
trigger_action(data_cell[:action], data_cell[:arguments]) if data_cell[:action]
|
198
174
|
end
|
199
175
|
|
200
176
|
def tableView(table_view, editingStyleForRowAtIndexPath: index_path)
|
201
177
|
data_cell = self.promotion_table_data.cell(index_path: index_path)
|
202
|
-
|
203
|
-
case data_cell[:editing_style]
|
204
|
-
when nil, :none
|
205
|
-
UITableViewCellEditingStyleNone
|
206
|
-
when :delete
|
207
|
-
UITableViewCellEditingStyleDelete
|
208
|
-
when :insert
|
209
|
-
UITableViewCellEditingStyleInsert
|
210
|
-
else
|
211
|
-
data_cell[:editing_style]
|
212
|
-
end
|
178
|
+
map_cell_editing_style(data_cell[:editing_style])
|
213
179
|
end
|
214
180
|
|
215
181
|
def tableView(table_view, commitEditingStyle: editing_style, forRowAtIndexPath: index_path)
|
@@ -236,22 +202,16 @@ module ProMotion
|
|
236
202
|
|
237
203
|
# Section view methods
|
238
204
|
def tableView(table_view, viewForHeaderInSection: index)
|
239
|
-
section =
|
240
|
-
|
241
|
-
if section[:title_view]
|
242
|
-
|
243
|
-
|
244
|
-
view.title = section[:title] if view.respond_to?(:title=)
|
245
|
-
view
|
246
|
-
else
|
247
|
-
nil
|
248
|
-
end
|
205
|
+
section = promotion_table_data.section(index)
|
206
|
+
view = nil
|
207
|
+
view = section[:title_view].new if section[:title_view].respond_to?(:new)
|
208
|
+
view.title = section[:title] if view.respond_to?(:title=)
|
209
|
+
view
|
249
210
|
end
|
250
211
|
|
251
212
|
def tableView(table_view, heightForHeaderInSection: index)
|
252
|
-
section =
|
253
|
-
|
254
|
-
if section[:title_view] || (section[:title] && !section[:title].empty?)
|
213
|
+
section = promotion_table_data.section(index)
|
214
|
+
if section[:title_view] || section[:title].to_s.length > 0
|
255
215
|
section[:title_view_height] || tableView.sectionHeaderHeight
|
256
216
|
else
|
257
217
|
0.0
|
@@ -260,10 +220,17 @@ module ProMotion
|
|
260
220
|
|
261
221
|
protected
|
262
222
|
|
223
|
+
def map_cell_editing_style(symbol)
|
224
|
+
{
|
225
|
+
none: UITableViewCellEditingStyleNone,
|
226
|
+
delete: UITableViewCellEditingStyleDelete,
|
227
|
+
insert: UITableViewCellEditingStyleInsert
|
228
|
+
}[symbol] || symbol || UITableViewCellEditingStyleNone
|
229
|
+
end
|
230
|
+
|
263
231
|
def map_row_animation_symbol(symbol)
|
264
232
|
symbol ||= UITableViewRowAnimationAutomatic
|
265
233
|
{
|
266
|
-
automatic: UITableViewRowAnimationAutomatic,
|
267
234
|
fade: UITableViewRowAnimationFade,
|
268
235
|
right: UITableViewRowAnimationRight,
|
269
236
|
left: UITableViewRowAnimationLeft,
|
@@ -272,7 +239,7 @@ module ProMotion
|
|
272
239
|
none: UITableViewRowAnimationNone,
|
273
240
|
middle: UITableViewRowAnimationMiddle,
|
274
241
|
automatic: UITableViewRowAnimationAutomatic
|
275
|
-
}[symbol] || symbol
|
242
|
+
}[symbol] || symbol || UITableViewRowAnimationAutomatic
|
276
243
|
end
|
277
244
|
|
278
245
|
module TableClassMethods
|
@@ -322,6 +289,19 @@ module ProMotion
|
|
322
289
|
@indexable_params ||= nil
|
323
290
|
end
|
324
291
|
|
292
|
+
# Longpressable
|
293
|
+
def longpressable(params = {})
|
294
|
+
@longpressable_params = params
|
295
|
+
@longpressable = true
|
296
|
+
end
|
297
|
+
|
298
|
+
def get_longpressable
|
299
|
+
@longpressable ||= false
|
300
|
+
end
|
301
|
+
|
302
|
+
def get_longpressable_params
|
303
|
+
@longpressable_params ||= nil
|
304
|
+
end
|
325
305
|
end
|
326
306
|
|
327
307
|
def self.included(base)
|