rmx 0.6.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.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/Gemfile +7 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +40 -0
  6. data/Rakefile +18 -0
  7. data/app/app_delegate.rb +5 -0
  8. data/lib/motion/RMXActionSheet.rb +14 -0
  9. data/lib/motion/RMXAutoLayoutLabel.rb +19 -0
  10. data/lib/motion/RMXAutoLayoutScrollView.rb +53 -0
  11. data/lib/motion/RMXCommonMethods.rb +27 -0
  12. data/lib/motion/RMXEventsFromProxy.rb +103 -0
  13. data/lib/motion/RMXExecutionBlock.rb +51 -0
  14. data/lib/motion/RMXKeyboardHelpers.rb +54 -0
  15. data/lib/motion/RMXLongTask.rb +133 -0
  16. data/lib/motion/RMXNavigationController.rb +133 -0
  17. data/lib/motion/RMXObjectExtensions.rb +10 -0
  18. data/lib/motion/RMXSegmentedController.rb +71 -0
  19. data/lib/motion/RMXSetAttributes.rb +34 -0
  20. data/lib/motion/RMXStrongToWeakHash.rb +46 -0
  21. data/lib/motion/RMXSynchronizedStrongToWeakHash.rb +40 -0
  22. data/lib/motion/RMXTableHandler.rb +212 -0
  23. data/lib/motion/RMXTableViewCell.rb +85 -0
  24. data/lib/motion/RMXTableViewCellInnerContentView.rb +16 -0
  25. data/lib/motion/RMXTableViewController.rb +65 -0
  26. data/lib/motion/RMXUnsafeUnretainedHolder.rb +30 -0
  27. data/lib/motion/RMXView.rb +84 -0
  28. data/lib/motion/RMXViewController.rb +65 -0
  29. data/lib/motion/RMXViewControllerPresentation.rb +127 -0
  30. data/lib/motion/RMXWeakHolder.rb +36 -0
  31. data/lib/motion/RMXWeakToStrongHash.rb +39 -0
  32. data/lib/motion/accessors.rb +29 -0
  33. data/lib/motion/base.rb +12 -0
  34. data/lib/motion/env.rb +9 -0
  35. data/lib/motion/events.rb +61 -0
  36. data/lib/motion/layout.rb +357 -0
  37. data/lib/motion/ui.rb +55 -0
  38. data/lib/motion/util.rb +155 -0
  39. data/lib/rmx/version.rb +3 -0
  40. data/lib/rmx.rb +50 -0
  41. data/resources/Default-568h@2x.png +0 -0
  42. data/rmx.gemspec +19 -0
  43. data/spec/main_spec.rb +240 -0
  44. metadata +86 -0
@@ -0,0 +1,133 @@
1
+ class RMXNavigationController < UINavigationController
2
+
3
+ include RMXCommonMethods
4
+ include RMXViewControllerPresentation
5
+
6
+ RMX.new(self).weak_attr_accessor :lastShownViewController
7
+
8
+ def animating?
9
+ if vc = viewControllers.last
10
+ vc != lastShownViewController
11
+ end
12
+ end
13
+
14
+ def navigationController(navigationController, didShowViewController:view_controller, animated:animated)
15
+ self.lastShownViewController = view_controller
16
+ Dispatch::Queue.main.async do
17
+ unless animating?
18
+ navigationBar.userInteractionEnabled = true
19
+ RMX.new(self).trigger(:done_animating)
20
+ end
21
+ end
22
+ end
23
+
24
+ def pushViewController(view_controller, animated:animated)
25
+ unless animating?
26
+ super
27
+ else
28
+ navigationBar.userInteractionEnabled = false
29
+ p "DELAYED pushViewController:animated:", view_controller, animated
30
+ RMX.new(self).once(:done_animating) do
31
+ p "RESUMED pushViewController:animated:", view_controller, animated
32
+ pushViewController(view_controller, animated:animated)
33
+ end
34
+ nil
35
+ end
36
+ end
37
+
38
+ def popViewControllerAnimated(animated)
39
+ unless animating?
40
+ super
41
+ else
42
+ navigationBar.userInteractionEnabled = false
43
+ p "DELAYED popViewControllerAnimated:", animated
44
+ RMX.new(self).once(:done_animating) do
45
+ p "RESUMED popViewControllerAnimated:", animated
46
+ popViewControllerAnimated(animated)
47
+ end
48
+ nil
49
+ end
50
+ end
51
+
52
+ def popToRootViewControllerAnimated(animated)
53
+ unless animating?
54
+ super
55
+ else
56
+ navigationBar.userInteractionEnabled = false
57
+ p "DELAYED popToRootViewControllerAnimated:", animated
58
+ RMX.new(self).once(:done_animating) do
59
+ p "RESUMED popToRootViewControllerAnimated:", animated
60
+ popToRootViewControllerAnimated(animated)
61
+ end
62
+ nil
63
+ end
64
+ end
65
+ def popToViewController(view_controller, animated:animated)
66
+ unless animating?
67
+ super
68
+ else
69
+ navigationBar.userInteractionEnabled = false
70
+ p "DELAYED popToViewController:animated:", view_controller, animated
71
+ RMX.new(self).once(:done_animating) do
72
+ p "RESUMED popToViewController:animated:", view_controller, animated
73
+ popToViewController(view_controller, animated:animated)
74
+ end
75
+ nil
76
+ end
77
+ end
78
+
79
+ def viewDidLoad
80
+ s = super
81
+ s
82
+ end
83
+
84
+ def viewWillAppear(animated)
85
+ s = super
86
+ rmx_viewWillAppear(animated)
87
+ s
88
+ end
89
+
90
+ def viewDidAppear(animated)
91
+ s = super
92
+ rmx_viewDidAppear(animated)
93
+ s
94
+ end
95
+
96
+ def viewWillDisappear(animated)
97
+ s = super
98
+ resignApplicationFirstResponder
99
+ rmx_viewWillDisappear(animated)
100
+ s
101
+ end
102
+
103
+ def viewDidDisappear(animated)
104
+ s = super
105
+ rmx_viewDidDisappear(animated)
106
+ s
107
+ end
108
+
109
+ def resignApplicationFirstResponder
110
+ windows = [] + UIApplication.sharedApplication.windows
111
+ while window = windows.pop
112
+ window.endEditing(true)
113
+ end
114
+ end
115
+
116
+ def didReceiveMemoryWarning
117
+ p "didReceiveMemoryWarning"
118
+ super
119
+ end
120
+
121
+ def rmx_dealloc
122
+ NSNotificationCenter.defaultCenter.removeObserver(self)
123
+ super
124
+ end
125
+
126
+ def self.create(rootViewController)
127
+ v = alloc.initWithNavigationBarClass(UINavigationBar, toolbarClass:nil)
128
+ v.delegate = v
129
+ v.pushViewController(rootViewController, animated: false) if rootViewController
130
+ v
131
+ end
132
+
133
+ end
@@ -0,0 +1,10 @@
1
+ module RMXObjectExtensions
2
+
3
+ def rmx_object_desc
4
+ cname = self.className.to_s
5
+ obj_id = '%x' % (self.object_id + 0)
6
+ res = "#<#{cname}:0x#{obj_id}>"
7
+ end
8
+
9
+ end
10
+ Object.send(:include, RMXObjectExtensions)
@@ -0,0 +1,71 @@
1
+ class RMXSegmentedController < RMXViewController
2
+
3
+ def prepare
4
+ @controller_indexes = []
5
+ @control = UISegmentedControl.new
6
+ @control.addTarget(self, action:'control_change:', forControlEvents:UIControlEventValueChanged)
7
+ end
8
+
9
+ def loaded
10
+ navigationItem.titleView = @control
11
+ self.selectedIndex = 0
12
+ end
13
+
14
+ def segments=(segments)
15
+ @controller_indexes.clear
16
+ @control.removeAllSegments
17
+ if segments
18
+ segments.each_with_index do |segment, i|
19
+ if segment[:title]
20
+ @control.insertSegmentWithTitle(segment[:title], atIndex:i, animated:false)
21
+ elsif segment[:image]
22
+ @control.insertSegmentWithImage(segment[:image], atIndex:i, animated:false)
23
+ end
24
+ @controller_indexes[i] = segment[:controller]
25
+ end
26
+ end
27
+ @control.sizeToFit
28
+ end
29
+
30
+ def control_change(sender)
31
+ self.selectedIndex = sender.selectedSegmentIndex
32
+ end
33
+
34
+ def selectedIndex=(i)
35
+ cleanup_active
36
+ @control.selectedSegmentIndex = @control.numberOfSegments > i ? i : UISegmentedControlNoSegment
37
+ @active_controller = @controller_indexes[i]
38
+ if @active_controller
39
+ addChildViewController(@active_controller)
40
+ RMX::Layout.new do |layout|
41
+ layout.view = view
42
+ layout.subviews = {
43
+ "content" => @active_controller.view
44
+ }
45
+ layout.eqs %Q{
46
+ content.left == 0
47
+ content.right == 0
48
+ content.top == 0
49
+ content.bottom == 0
50
+ }
51
+ end
52
+ @active_controller.didMoveToParentViewController(self)
53
+ end
54
+ end
55
+
56
+ def cleanup_active
57
+ if @active_controller
58
+ @active_controller.willMoveToParentViewController(nil)
59
+ @active_controller.view.removeFromSuperview
60
+ @active_controller.removeFromParentViewController
61
+ @active_controller = nil
62
+ end
63
+ end
64
+
65
+ def rmx_dealloc
66
+ cleanup_active
67
+ @controller_indexes = nil
68
+ end
69
+
70
+ end
71
+
@@ -0,0 +1,34 @@
1
+ module RMXSetAttributes
2
+
3
+ def self.included(klass)
4
+ klass.send(:include, InstanceMethods)
5
+ klass.send(:extend, ClassMethods)
6
+ end
7
+
8
+ module InstanceMethods
9
+
10
+ def after_attributes_set
11
+ end
12
+
13
+ def attributes=(attrs={})
14
+ keys = [] + attrs.keys
15
+ while key = keys.pop
16
+ value = attrs[key]
17
+ self.send("#{key}=", value)
18
+ end
19
+ after_attributes_set
20
+ end
21
+
22
+ end
23
+
24
+ module ClassMethods
25
+
26
+ def create(opts={})
27
+ x = new
28
+ x.attributes = opts
29
+ x
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,46 @@
1
+ class RMXStrongToWeakHash < Hash
2
+
3
+ def [](key)
4
+ if weak = super
5
+ if val = weak.value
6
+ val
7
+ end
8
+ end
9
+ end
10
+
11
+ def []=(key, value)
12
+ super(key, value.nil? ? nil : RMXWeakHolder.new(value))
13
+ value
14
+ end
15
+
16
+ def delete(key)
17
+ if val = super
18
+ val.value
19
+ end
20
+ end
21
+
22
+ def keys
23
+ out = []
24
+ _keys = [] + super
25
+ while _keys.size > 0
26
+ key = _keys.shift
27
+ if val = self[key]
28
+ out << key
29
+ end
30
+ end
31
+ out
32
+ end
33
+
34
+ def values
35
+ out = []
36
+ values = [] + super
37
+ while values.size > 0
38
+ value = values.shift
39
+ if val = value.value
40
+ out << val
41
+ end
42
+ end
43
+ out
44
+ end
45
+
46
+ end
@@ -0,0 +1,40 @@
1
+ class RMXSynchronizedStrongToWeakHash < RMXStrongToWeakHash
2
+
3
+ def initialize
4
+ super
5
+ @queue = Dispatch::Queue.new("#{NSBundle.mainBundle.bundleIdentifier}.rmx.IdentityMap.queue.#{object_id}")
6
+ end
7
+
8
+ def [](key)
9
+ res = nil
10
+ @queue.sync do
11
+ res = super
12
+ end
13
+ res
14
+ end
15
+
16
+ def []=(key, value)
17
+ res = nil
18
+ @queue.sync do
19
+ res = super
20
+ end
21
+ res
22
+ end
23
+
24
+ def delete(key)
25
+ res = nil
26
+ @queue.sync do
27
+ res = super
28
+ end
29
+ res
30
+ end
31
+
32
+ def values
33
+ res = nil
34
+ @queue.sync do
35
+ res = super
36
+ end
37
+ res
38
+ end
39
+
40
+ end
@@ -0,0 +1,212 @@
1
+ class RMXTableHandler
2
+
3
+ include RMXCommonMethods
4
+
5
+ RMX.new(self).weak_attr_accessor :tableView, :delegate
6
+
7
+ attr_accessor :registered_reuse_identifiers, :sections
8
+
9
+ def self.forTable(tableView)
10
+ x = new
11
+ x.tableView = tableView
12
+ tableView.dataSource = x
13
+ tableView.delegate = x
14
+ x
15
+ end
16
+
17
+ def rmx_dealloc
18
+ if tv = tableView
19
+ tv.dataSource = nil
20
+ tv.delegate = nil
21
+ end
22
+ RMX.new(self).nil_instance_variables!
23
+ super
24
+ end
25
+
26
+ def initialize
27
+ @sections = []
28
+ @heights = {}
29
+ @registered_reuse_identifiers = {}
30
+ self
31
+ end
32
+
33
+ def animateUpdates
34
+ if @isAnimatingUpdates
35
+ @animateUpdatesAgain = true
36
+ return
37
+ end
38
+ @isAnimatingUpdates = true
39
+ CATransaction.begin
40
+ CATransaction.setCompletionBlock(lambda do
41
+ p "animation has finished"
42
+ @isAnimatingUpdates = false
43
+ if @animateUpdatesAgain
44
+ p "animate again!"
45
+ @animateUpdatesAgain = false
46
+ animateUpdates
47
+ end
48
+ end)
49
+ tableView.beginUpdates
50
+ tableView.endUpdates
51
+ CATransaction.commit
52
+ end
53
+
54
+ def reloadData
55
+ if tv = tableView
56
+ tv.reloadData
57
+ end
58
+ end
59
+
60
+ def set_size_for_data(data, reuseIdentifier:reuseIdentifier)
61
+ reuseIdentifier = reuseIdentifier.to_s
62
+ sizerCell = registered_reuse_identifiers[reuseIdentifier]
63
+ sizerCell.data = data
64
+ height = sizerCell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
65
+ updateHeight(height, data:data, reuseIdentifier:reuseIdentifier)
66
+ end
67
+
68
+ def registerClass(klass, forCellReuseIdentifier:reuseIdentifier)
69
+ reuseIdentifier = reuseIdentifier.to_s
70
+ registered_reuse_identifiers[reuseIdentifier] = klass.new
71
+ tableView.registerClass(klass, forCellReuseIdentifier:reuseIdentifier)
72
+ end
73
+
74
+ def tableView(tableView, cellForRowAtIndexPath:indexPath)
75
+ RMX.assert_main_thread!
76
+ context = {
77
+ :tableHandler => self,
78
+ :tableView => tableView,
79
+ :indexPath => indexPath,
80
+ :data => delegate.tableHandler(self, dataForSectionName:@sections[indexPath.section])[indexPath.row]
81
+ }
82
+ res = delegate.tableHandler(self, cellOptsForContext:context)
83
+ if res.is_a?(Hash)
84
+ context.update(res)
85
+ unless res[:reuseIdentifier]
86
+ raise ":reuseIdentifier is required"
87
+ end
88
+ reuseIdentifier = res[:reuseIdentifier].to_s
89
+ registered_reuse_identifiers[reuseIdentifier] || registerClass(RMXTableViewCell, forCellReuseIdentifier:reuseIdentifier)
90
+ res = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier, forIndexPath:indexPath)
91
+ res.context = context
92
+ end
93
+ # p "cellForRowAtIndexPath", res, context
94
+ res
95
+ end
96
+
97
+ def tableView(tableView, heightForRowAtIndexPath:indexPath)
98
+ RMX.assert_main_thread!
99
+ context = {
100
+ :tableHandler => self,
101
+ :tableView => tableView,
102
+ :indexPath => indexPath,
103
+ :data => delegate.tableHandler(self, dataForSectionName:@sections[indexPath.section])[indexPath.row]
104
+ }
105
+ res = if @respondsToHeightForContext || delegate.respondsToSelector('tableHandler:heightForContext:')
106
+ @respondsToHeightForContext = true
107
+ delegate.tableHandler(self, heightForContext:context)
108
+ else
109
+ delegate.tableHandler(self, cellOptsForContext:context)
110
+ end
111
+ if res.is_a?(Hash)
112
+ context.update(res)
113
+ unless res[:reuseIdentifier]
114
+ raise ":reuseIdentifier is required"
115
+ end
116
+ reuseIdentifier = res[:reuseIdentifier].to_s
117
+ height = nil
118
+ if res[:data]
119
+ if heights = @heights[reuseIdentifier]
120
+ height = heights[res[:data]]
121
+ end
122
+ end
123
+ unless height
124
+ # p "using estimated"
125
+ height = res[:estimated]
126
+ # else
127
+ # p "using real"
128
+ end
129
+ res = height
130
+ end
131
+ # p "heightForRowAtIndexPath", indexPath, res
132
+ res
133
+ end
134
+
135
+ def tableView(tableView, estimatedHeightForRowAtIndexPath:indexPath)
136
+ tableView(tableView, heightForRowAtIndexPath:indexPath)
137
+ end
138
+
139
+ def tableView(tableView, viewForHeaderInSection:section)
140
+ RMX.assert_main_thread!
141
+ if @respondsToHeaderForContext || delegate.respondsToSelector('tableHandler:headerForContext:')
142
+ @respondsToHeaderForContext = true
143
+ context = {
144
+ :tableHandler => self,
145
+ :tableView => tableView,
146
+ :section => section
147
+ }
148
+ res = delegate.tableHandler(self, headerForContext:context)
149
+ # p "viewForHeaderInSection", section, res
150
+ res
151
+ end
152
+ end
153
+
154
+ def tableView(tableView, heightForHeaderInSection:section)
155
+ RMX.assert_main_thread!
156
+ if @respondsToHeaderHeightForContext || delegate.respondsToSelector('tableHandler:headerHeightForContext:')
157
+ @respondsToHeaderHeightForContext = true
158
+ context = {
159
+ :tableHandler => self,
160
+ :tableView => tableView,
161
+ :section => section
162
+ }
163
+ res = delegate.tableHandler(self, headerHeightForContext:context)
164
+ # p "heightForHeaderInSection", section, res
165
+ res
166
+ else
167
+ 0
168
+ end
169
+ end
170
+
171
+ def tableView(tableView, numberOfRowsInSection: section)
172
+ RMX.assert_main_thread!
173
+ res = delegate.tableHandler(self, dataForSectionName:@sections[section]).size
174
+ # p "numberOfRowsInSection", res
175
+ res
176
+ end
177
+
178
+ def numberOfSectionsInTableView(tableView)
179
+ RMX.assert_main_thread!
180
+ res = @sections.size
181
+ # p "numberOfSectionsInTableView", res
182
+ res
183
+ end
184
+
185
+ def tableView(tableView, didSelectRowAtIndexPath:indexPath)
186
+ RMX.assert_main_thread!
187
+ if @respondsToClickForContext || delegate.respondsToSelector('tableHandler:clickForContext:')
188
+ @respondsToClickForContext = true
189
+ context = {
190
+ :tableHandler => self,
191
+ :tableView => tableView,
192
+ :indexPath => indexPath,
193
+ :data => delegate.tableHandler(self, dataForSectionName:@sections[indexPath.section])[indexPath.row]
194
+ }
195
+ delegate.tableHandler(self, clickForContext:context)
196
+ tableView.deselectRowAtIndexPath(indexPath, animated:true)
197
+ end
198
+ end
199
+
200
+ def updateHeight(height, data:data, reuseIdentifier:reuseIdentifier)
201
+ reuseIdentifier = reuseIdentifier.to_s
202
+ @heights[reuseIdentifier] ||= {}
203
+ heights = @heights[reuseIdentifier]
204
+ current_height = heights[data]
205
+ if current_height != height
206
+ heights[data] = height
207
+ return true
208
+ end
209
+ false
210
+ end
211
+
212
+ end
@@ -0,0 +1,85 @@
1
+ class RMXTableViewCell < UITableViewCell
2
+
3
+ include RMXCommonMethods
4
+
5
+ RMX.new(self).weak_attr_accessor :tableView
6
+ RMX.new(self).weak_attr_accessor :tableHandler
7
+ attr_accessor :indexPath, :innerContentView
8
+
9
+ def initWithStyle(style, reuseIdentifier:reuseIdentifier)
10
+ reuseIdentifier = reuseIdentifier.to_s
11
+ s = super(style, reuseIdentifier)
12
+ @innerContentView = RMXTableViewCellInnerContentView.new
13
+ @innerContentView.cell = self
14
+ RMX::Layout.new do |layout|
15
+ layout.view = contentView
16
+ layout.subviews = {
17
+ "innerContentView" => @innerContentView
18
+ }
19
+ layout.eqs %Q{
20
+ innerContentView.top == 0
21
+ innerContentView.left == 0
22
+ innerContentView.right == 0
23
+ innerContentView.bottom == 0 @ med
24
+ }
25
+ end
26
+ setup
27
+ s
28
+ end
29
+
30
+ def context=(context)
31
+ self.tableHandler = context[:tableHandler]
32
+ self.tableView = context[:tableView]
33
+ self.indexPath = context[:indexPath]
34
+ self.data = context[:data]
35
+ self.view = context[:view]
36
+ if context[:transform] && transform != context[:transform]
37
+ self.transform = context[:transform]
38
+ end
39
+ end
40
+
41
+ def setup
42
+ end
43
+
44
+ def data
45
+ @data
46
+ end
47
+
48
+ def data=(data)
49
+ @data = data
50
+ end
51
+
52
+ def view
53
+ @view
54
+ end
55
+
56
+ def view=(view)
57
+ @view.removeFromSuperview if @view
58
+ if @view = view
59
+ RMX::Layout.new do |layout|
60
+ layout.view = innerContentView
61
+ layout.subviews = {
62
+ "tile" => view
63
+ }
64
+ layout.eqs %Q{
65
+ tile.top == 0
66
+ tile.left == 0
67
+ tile.right == 0
68
+ tile.bottom == 0 @ 500
69
+ }
70
+ end
71
+ end
72
+ view
73
+ end
74
+
75
+ def updateHeight!
76
+ if (d = data) && (h = tableHandler)
77
+ height = contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
78
+ # p "height", height
79
+ if h.updateHeight(height, data:d, reuseIdentifier:reuseIdentifier)
80
+ h.reloadData
81
+ end
82
+ end
83
+ end
84
+
85
+ end
@@ -0,0 +1,16 @@
1
+ class RMXTableViewCellInnerContentView < RMXView
2
+ RMX.new(self).weak_attr_accessor :cell
3
+ attr_accessor :autoUpdateHeight
4
+
5
+ def layoutSubviews
6
+ s = super
7
+ updateHeight! if @autoUpdateHeight
8
+ s
9
+ end
10
+
11
+ def updateHeight!
12
+ if c = cell
13
+ c.updateHeight!
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,65 @@
1
+ class RMXTableViewController < UITableViewController
2
+
3
+ include RMXCommonMethods
4
+ include RMXViewControllerPresentation
5
+ include RMXKeyboardHelpers
6
+ include RMXSetAttributes
7
+
8
+ def prepare
9
+ end
10
+
11
+ def loaded
12
+ end
13
+
14
+ def init
15
+ s = super
16
+ NSNotificationCenter.defaultCenter.addObserver(self, selector:'refresh', name:UIApplicationWillEnterForegroundNotification, object:nil)
17
+ listenForKeyboardChanged
18
+ prepare
19
+ s
20
+ end
21
+
22
+ def refresh
23
+ end
24
+
25
+ def viewDidLoad
26
+ s = super
27
+ loaded
28
+ s
29
+ end
30
+
31
+ def viewWillAppear(animated)
32
+ s = super
33
+ rmx_viewWillAppear(animated)
34
+ s
35
+ end
36
+
37
+ def viewDidAppear(animated)
38
+ s = super
39
+ rmx_viewDidAppear(animated)
40
+ s
41
+ end
42
+
43
+ def viewWillDisappear(animated)
44
+ s = super
45
+ rmx_viewWillDisappear(animated)
46
+ s
47
+ end
48
+
49
+ def viewDidDisappear(animated)
50
+ s = super
51
+ rmx_viewDidDisappear(animated)
52
+ s
53
+ end
54
+
55
+ def didReceiveMemoryWarning
56
+ p "didReceiveMemoryWarning"
57
+ super
58
+ end
59
+
60
+ def rmx_dealloc
61
+ NSNotificationCenter.defaultCenter.removeObserver(self)
62
+ super
63
+ end
64
+
65
+ end