OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "ios/chrome/browser/ui/contextual_search/contextual_search_panel_view.h" | 5 #import "ios/chrome/browser/ui/contextual_search/contextual_search_panel_view.h" |
6 | 6 |
7 #import "base/ios/crb_protocol_observers.h" | 7 #import "base/ios/crb_protocol_observers.h" |
8 #include "base/ios/weak_nsobject.h" | |
9 #include "base/logging.h" | 8 #include "base/logging.h" |
10 #include "base/mac/scoped_block.h" | |
11 #include "base/mac/scoped_nsobject.h" | |
12 #import "ios/chrome/browser/procedural_block_types.h" | 9 #import "ios/chrome/browser/procedural_block_types.h" |
13 #import "ios/chrome/browser/ui/contextual_search/contextual_search_panel_protoco
ls.h" | 10 #import "ios/chrome/browser/ui/contextual_search/contextual_search_panel_protoco
ls.h" |
14 #import "ios/chrome/browser/ui/uikit_ui_util.h" | 11 #import "ios/chrome/browser/ui/uikit_ui_util.h" |
15 #import "ios/chrome/common/material_timing.h" | 12 #import "ios/chrome/common/material_timing.h" |
16 #import "ios/third_party/material_components_ios/src/components/ShadowElevations
/src/MaterialShadowElevations.h" | 13 #import "ios/third_party/material_components_ios/src/components/ShadowElevations
/src/MaterialShadowElevations.h" |
17 #import "ios/third_party/material_components_ios/src/components/ShadowLayer/src/
MaterialShadowLayer.h" | 14 #import "ios/third_party/material_components_ios/src/components/ShadowLayer/src/
MaterialShadowLayer.h" |
18 | 15 |
| 16 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 17 #error "This file requires ARC support." |
| 18 #endif |
| 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 // Animation timings. | 22 // Animation timings. |
22 const NSTimeInterval kPanelAnimationDuration = ios::material::kDuration3; | 23 const NSTimeInterval kPanelAnimationDuration = ios::material::kDuration3; |
23 const NSTimeInterval kDismissAnimationDuration = ios::material::kDuration1; | 24 const NSTimeInterval kDismissAnimationDuration = ios::material::kDuration1; |
24 | 25 |
25 // Elevation (in MD vertical space) of the panel when dismissed and peeking. | 26 // Elevation (in MD vertical space) of the panel when dismissed and peeking. |
26 const CGFloat kShadowElevation = MDCShadowElevationMenu; | 27 const CGFloat kShadowElevation = MDCShadowElevationMenu; |
27 | 28 |
28 } // namespace | 29 } // namespace |
29 | 30 |
30 @interface ContextualSearchPanelObservers | 31 @interface ContextualSearchPanelObservers |
31 : CRBProtocolObservers<ContextualSearchPanelMotionObserver> | 32 : CRBProtocolObservers<ContextualSearchPanelMotionObserver> |
32 @end | 33 @end |
33 @implementation ContextualSearchPanelObservers | 34 @implementation ContextualSearchPanelObservers |
34 | 35 |
35 @end | 36 @end |
36 | 37 |
37 @interface ContextualSearchPanelView ()<UIGestureRecognizerDelegate, | 38 @interface ContextualSearchPanelView ()<UIGestureRecognizerDelegate, |
38 ContextualSearchPanelMotionObserver> | 39 ContextualSearchPanelMotionObserver> |
39 | 40 |
40 // A subview whose content scrolls and whose scrolling is synchronized with | 41 // A subview whose content scrolls and whose scrolling is synchronized with |
41 // panel dragging. This means that if the scrolling subview is being scrolled, | 42 // panel dragging. This means that if the scrolling subview is being scrolled, |
42 // that motion will not cause the panel to move, but if the scrolling reaches | 43 // that motion will not cause the panel to move, but if the scrolling reaches |
43 // the end of its possible range, the gesture will then start dragging the | 44 // the end of its possible range, the gesture will then start dragging the |
44 // panel. | 45 // panel. |
45 @property(nonatomic, assign) | 46 @property(nonatomic, weak) |
46 UIView<ContextualSearchPanelScrollSynchronizer>* scrollSynchronizer; | 47 UIView<ContextualSearchPanelScrollSynchronizer>* scrollSynchronizer; |
47 | 48 |
48 // Private readonly property to be used by weak pointers to |self| for non- | 49 // Private readonly property to be used by weak pointers to |self| for non- |
49 // retaining access to the underlying ivar in blocks. | 50 // retaining access to the underlying ivar in blocks. |
50 @property(nonatomic, readonly) ContextualSearchPanelObservers* observers; | 51 @property(nonatomic, strong, readonly) |
| 52 ContextualSearchPanelObservers* observers; |
51 | 53 |
52 // Utility to generate a PanelMotion struct for the panel's current position. | 54 // Utility to generate a PanelMotion struct for the panel's current position. |
53 - (ContextualSearch::PanelMotion)motion; | 55 - (ContextualSearch::PanelMotion)motion; |
54 @end | 56 @end |
55 | 57 |
56 @implementation ContextualSearchPanelView { | 58 @implementation ContextualSearchPanelView { |
57 UIStackView* _contents; | 59 UIStackView* _contents; |
58 | 60 |
59 // Constraints that define the size of this view. These will be cleared and | 61 // Constraints that define the size of this view. These will be cleared and |
60 // regenerated when the horizontal size class changes. | 62 // regenerated when the horizontal size class changes. |
61 base::scoped_nsobject<NSArray> _sizingConstraints; | 63 NSArray* _sizingConstraints; |
62 | 64 |
63 CGPoint _draggingStartPosition; | 65 CGPoint _draggingStartPosition; |
64 CGPoint _scrolledOffset; | 66 CGPoint _scrolledOffset; |
65 base::scoped_nsobject<UIPanGestureRecognizer> _dragRecognizer; | 67 UIPanGestureRecognizer* _dragRecognizer; |
66 | |
67 base::scoped_nsobject<ContextualSearchPanelObservers> _observers; | |
68 | |
69 base::scoped_nsobject<PanelConfiguration> _configuration; | |
70 | |
71 base::WeakNSProtocol<id<ContextualSearchPanelScrollSynchronizer>> | |
72 _scrollSynchronizer; | |
73 | 68 |
74 // Guide that's used to position this view. | 69 // Guide that's used to position this view. |
75 base::WeakNSObject<UILayoutGuide> _positioningGuide; | 70 __weak UILayoutGuide* _positioningGuide; |
76 // Constraint that sets the size of |_positioningView| so this view is | 71 // Constraint that sets the size of |_positioningView| so this view is |
77 // positioned correctly for its state. | 72 // positioned correctly for its state. |
78 base::WeakNSObject<NSLayoutConstraint> _positioningViewConstraint; | 73 __weak NSLayoutConstraint* _positioningViewConstraint; |
79 // Other constraints that determine the position of this view. | 74 // Other constraints that determine the position of this view. |
80 base::scoped_nsobject<NSArray> _positioningConstraints; | 75 NSArray* _positioningConstraints; |
81 | 76 |
82 // Promotion state variables. | 77 // Promotion state variables. |
83 BOOL _resizingForPromotion; | 78 BOOL _resizingForPromotion; |
84 CGFloat _promotionVerticalOffset; | 79 CGFloat _promotionVerticalOffset; |
85 | 80 |
86 // YES if dragging started inside the content view and scrolling is possible. | 81 // YES if dragging started inside the content view and scrolling is possible. |
87 BOOL _maybeScrollContent; | 82 BOOL _maybeScrollContent; |
88 // YES if the drag is happening along with scrolling the content view. | 83 // YES if the drag is happening along with scrolling the content view. |
89 BOOL _isScrollingContent; | 84 BOOL _isScrollingContent; |
90 | 85 |
91 // YES if dragging upwards has occurred. | 86 // YES if dragging upwards has occurred. |
92 BOOL _hasDraggedUp; | 87 BOOL _hasDraggedUp; |
93 } | 88 } |
94 | 89 |
95 @synthesize state = _state; | 90 @synthesize state = _state; |
| 91 @synthesize scrollSynchronizer = _scrollSynchronizer; |
| 92 @synthesize configuration = _configuration; |
| 93 @synthesize observers = _observers; |
96 | 94 |
97 + (BOOL)requiresConstraintBasedLayout { | 95 + (BOOL)requiresConstraintBasedLayout { |
98 return YES; | 96 return YES; |
99 } | 97 } |
100 | 98 |
101 #pragma mark - Initializers | 99 #pragma mark - Initializers |
102 | 100 |
103 - (instancetype)initWithConfiguration:(PanelConfiguration*)configuration { | 101 - (instancetype)initWithConfiguration:(PanelConfiguration*)configuration { |
104 if ((self = [super initWithFrame:CGRectZero])) { | 102 if ((self = [super initWithFrame:CGRectZero])) { |
105 _configuration.reset([configuration retain]); | 103 _configuration = configuration; |
106 _state = ContextualSearch::DISMISSED; | 104 _state = ContextualSearch::DISMISSED; |
107 | 105 |
108 self.translatesAutoresizingMaskIntoConstraints = NO; | 106 self.translatesAutoresizingMaskIntoConstraints = NO; |
109 self.backgroundColor = [UIColor whiteColor]; | 107 self.backgroundColor = [UIColor whiteColor]; |
110 self.accessibilityIdentifier = @"contextualSearchPanel"; | 108 self.accessibilityIdentifier = @"contextualSearchPanel"; |
111 | 109 |
112 _observers.reset([[ContextualSearchPanelObservers | 110 _observers = [ContextualSearchPanelObservers |
113 observersWithProtocol:@protocol(ContextualSearchPanelMotionObserver)] | 111 observersWithProtocol:@protocol(ContextualSearchPanelMotionObserver)]; |
114 retain]); | |
115 [self addMotionObserver:self]; | 112 [self addMotionObserver:self]; |
116 | 113 |
117 // Add gesture recognizer. | 114 // Add gesture recognizer. |
118 _dragRecognizer.reset([[UIPanGestureRecognizer alloc] | 115 _dragRecognizer = [[UIPanGestureRecognizer alloc] |
119 initWithTarget:self | 116 initWithTarget:self |
120 action:@selector(handleDragFrom:)]); | 117 action:@selector(handleDragFrom:)]; |
121 [self addGestureRecognizer:_dragRecognizer]; | 118 [self addGestureRecognizer:_dragRecognizer]; |
122 [_dragRecognizer setDelegate:self]; | 119 [_dragRecognizer setDelegate:self]; |
123 | 120 |
124 // Set up the stack view that holds the panel content | 121 // Set up the stack view that holds the panel content |
125 _contents = [[[UIStackView alloc] initWithFrame:self.bounds] autorelease]; | 122 _contents = [[UIStackView alloc] initWithFrame:self.bounds]; |
126 [self addSubview:_contents]; | 123 [self addSubview:_contents]; |
127 _contents.translatesAutoresizingMaskIntoConstraints = NO; | 124 _contents.translatesAutoresizingMaskIntoConstraints = NO; |
128 _contents.accessibilityIdentifier = @"panelContents"; | 125 _contents.accessibilityIdentifier = @"panelContents"; |
129 [NSLayoutConstraint activateConstraints:@[ | 126 [NSLayoutConstraint activateConstraints:@[ |
130 [_contents.centerXAnchor constraintEqualToAnchor:self.centerXAnchor], | 127 [_contents.centerXAnchor constraintEqualToAnchor:self.centerXAnchor], |
131 [_contents.centerYAnchor constraintEqualToAnchor:self.centerYAnchor], | 128 [_contents.centerYAnchor constraintEqualToAnchor:self.centerYAnchor], |
132 [_contents.widthAnchor constraintEqualToAnchor:self.widthAnchor], | 129 [_contents.widthAnchor constraintEqualToAnchor:self.widthAnchor], |
133 [_contents.heightAnchor constraintEqualToAnchor:self.heightAnchor] | 130 [_contents.heightAnchor constraintEqualToAnchor:self.heightAnchor] |
134 ]]; | 131 ]]; |
135 _contents.axis = UILayoutConstraintAxisVertical; | 132 _contents.axis = UILayoutConstraintAxisVertical; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 [[_positioningGuide owningView] removeLayoutGuide:_positioningGuide]; | 187 [[_positioningGuide owningView] removeLayoutGuide:_positioningGuide]; |
191 [_observers panelIsPromoting:self]; | 188 [_observers panelIsPromoting:self]; |
192 [self setNeedsUpdateConstraints]; | 189 [self setNeedsUpdateConstraints]; |
193 [self updateConstraintsIfNeeded]; | 190 [self updateConstraintsIfNeeded]; |
194 [self layoutIfNeeded]; | 191 [self layoutIfNeeded]; |
195 } | 192 } |
196 | 193 |
197 #pragma mark - Public property getters/setters | 194 #pragma mark - Public property getters/setters |
198 | 195 |
199 - (PanelConfiguration*)configuration { | 196 - (PanelConfiguration*)configuration { |
200 return _configuration.get(); | 197 return _configuration; |
201 } | |
202 | |
203 - (void)setScrollSynchronizer: | |
204 (id<ContextualSearchPanelScrollSynchronizer>)scrollSynchronizer { | |
205 _scrollSynchronizer.reset(scrollSynchronizer); | |
206 } | |
207 | |
208 - (id<ContextualSearchPanelScrollSynchronizer>)scrollSynchronizer { | |
209 return _scrollSynchronizer; | |
210 } | 198 } |
211 | 199 |
212 - (ContextualSearchPanelObservers*)observers { | 200 - (ContextualSearchPanelObservers*)observers { |
213 return _observers; | 201 return _observers; |
214 } | 202 } |
215 | 203 |
216 - (void)setState:(ContextualSearch::PanelState)state { | 204 - (void)setState:(ContextualSearch::PanelState)state { |
217 if (state == _state) | 205 if (state == _state) |
218 return; | 206 return; |
219 | 207 |
220 [_positioningViewConstraint setActive:NO]; | 208 [_positioningViewConstraint setActive:NO]; |
221 _positioningViewConstraint.reset(); | 209 _positioningViewConstraint = nil; |
222 base::WeakNSObject<ContextualSearchPanelView> weakSelf(self); | 210 __weak ContextualSearchPanelView* weakSelf = self; |
223 void (^transform)(void) = ^{ | 211 void (^transform)(void) = ^{ |
224 base::scoped_nsobject<ContextualSearchPanelView> strongSelf( | 212 ContextualSearchPanelView* strongSelf = weakSelf; |
225 [weakSelf retain]); | |
226 if (strongSelf) { | 213 if (strongSelf) { |
227 [strongSelf setNeedsUpdateConstraints]; | 214 [strongSelf setNeedsUpdateConstraints]; |
228 [[strongSelf superview] layoutIfNeeded]; | 215 [[strongSelf superview] layoutIfNeeded]; |
229 [[strongSelf observers] panel:strongSelf | 216 [[strongSelf observers] panel:strongSelf |
230 didMoveWithMotion:[strongSelf motion]]; | 217 didMoveWithMotion:[strongSelf motion]]; |
231 } | 218 } |
232 }; | 219 }; |
233 | 220 |
234 base::mac::ScopedBlock<ProceduralBlockWithBool> completion; | 221 ProceduralBlockWithBool completion; |
235 NSTimeInterval animationDuration; | 222 NSTimeInterval animationDuration; |
236 if (state == ContextualSearch::DISMISSED) { | 223 if (state == ContextualSearch::DISMISSED) { |
237 animationDuration = kDismissAnimationDuration; | 224 animationDuration = kDismissAnimationDuration; |
238 completion.reset( | 225 completion = [^(BOOL) { |
239 ^(BOOL) { | 226 [weakSelf setHidden:YES]; |
240 [weakSelf setHidden:YES]; | 227 } copy]; |
241 }, | |
242 base::scoped_policy::RETAIN); | |
243 } else { | 228 } else { |
244 self.hidden = NO; | 229 self.hidden = NO; |
245 animationDuration = kPanelAnimationDuration; | 230 animationDuration = kPanelAnimationDuration; |
246 } | 231 } |
247 | 232 |
248 // Animations from a dismissed state are EaseOut, others are EaseInOut. | 233 // Animations from a dismissed state are EaseOut, others are EaseInOut. |
249 ios::material::Curve curve = _state == ContextualSearch::DISMISSED | 234 ios::material::Curve curve = _state == ContextualSearch::DISMISSED |
250 ? ios::material::CurveEaseOut | 235 ? ios::material::CurveEaseOut |
251 : ios::material::CurveEaseInOut; | 236 : ios::material::CurveEaseInOut; |
252 | 237 |
(...skipping 22 matching lines...) Expand all Loading... |
275 .active = YES; | 260 .active = YES; |
276 [self.topAnchor constraintEqualToAnchor:self.superview.topAnchor | 261 [self.topAnchor constraintEqualToAnchor:self.superview.topAnchor |
277 constant:_promotionVerticalOffset] | 262 constant:_promotionVerticalOffset] |
278 .active = YES; | 263 .active = YES; |
279 } else { | 264 } else { |
280 // Don't update sizing constraints if there isn't a defined horizontal size | 265 // Don't update sizing constraints if there isn't a defined horizontal size |
281 // yet. | 266 // yet. |
282 if (self.traitCollection.horizontalSizeClass != | 267 if (self.traitCollection.horizontalSizeClass != |
283 UIUserInterfaceSizeClassUnspecified && | 268 UIUserInterfaceSizeClassUnspecified && |
284 !_sizingConstraints) { | 269 !_sizingConstraints) { |
285 _sizingConstraints.reset( | 270 _sizingConstraints = [_configuration constraintsForSizingPanel:self]; |
286 [[_configuration constraintsForSizingPanel:self] retain]); | |
287 [NSLayoutConstraint activateConstraints:_sizingConstraints]; | 271 [NSLayoutConstraint activateConstraints:_sizingConstraints]; |
288 } | 272 } |
289 // Update positioning constraints if they don't exist. | 273 // Update positioning constraints if they don't exist. |
290 if (!_positioningConstraints) { | 274 if (!_positioningConstraints) { |
291 NSArray* positioningConstraints = @[ | 275 NSArray* positioningConstraints = @[ |
292 [[_positioningGuide topAnchor] | 276 [[_positioningGuide topAnchor] |
293 constraintEqualToAnchor:self.superview.topAnchor], | 277 constraintEqualToAnchor:self.superview.topAnchor], |
294 [[_positioningGuide bottomAnchor] | 278 [[_positioningGuide bottomAnchor] |
295 constraintEqualToAnchor:self.topAnchor] | 279 constraintEqualToAnchor:self.topAnchor] |
296 ]; | 280 ]; |
297 [NSLayoutConstraint activateConstraints:positioningConstraints]; | 281 [NSLayoutConstraint activateConstraints:positioningConstraints]; |
298 | 282 |
299 _positioningConstraints.reset([positioningConstraints retain]); | 283 _positioningConstraints = positioningConstraints; |
300 } | 284 } |
301 // Always update the positioning view constraint. | 285 // Always update the positioning view constraint. |
302 _positioningViewConstraint.reset([self.configuration | 286 _positioningViewConstraint = |
303 constraintForPositioningGuide:_positioningGuide | 287 [self.configuration constraintForPositioningGuide:_positioningGuide |
304 atState:self.state]); | 288 atState:self.state]; |
305 [_positioningViewConstraint setActive:YES]; | 289 [_positioningViewConstraint setActive:YES]; |
306 } | 290 } |
307 [super updateConstraints]; | 291 [super updateConstraints]; |
308 } | 292 } |
309 | 293 |
310 - (void)didMoveToSuperview { | 294 - (void)didMoveToSuperview { |
311 if (!self.superview) | 295 if (!self.superview) |
312 return; | 296 return; |
313 // Set up the invisible positioning view used to constrain this view's | 297 // Set up the invisible positioning view used to constrain this view's |
314 // position. | 298 // position. |
315 UILayoutGuide* positioningGuide = [[[UILayoutGuide alloc] init] autorelease]; | 299 UILayoutGuide* positioningGuide = [[UILayoutGuide alloc] init]; |
316 positioningGuide.identifier = @"contextualSearchPosition"; | 300 positioningGuide.identifier = @"contextualSearchPosition"; |
317 [self.superview addLayoutGuide:positioningGuide]; | 301 [self.superview addLayoutGuide:positioningGuide]; |
318 _positioningGuide.reset(positioningGuide); | 302 _positioningGuide = positioningGuide; |
319 [self setNeedsUpdateConstraints]; | 303 [self setNeedsUpdateConstraints]; |
320 } | 304 } |
321 | 305 |
322 - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { | 306 - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { |
323 if (previousTraitCollection.horizontalSizeClass == | 307 if (previousTraitCollection.horizontalSizeClass == |
324 self.traitCollection.horizontalSizeClass) { | 308 self.traitCollection.horizontalSizeClass) { |
325 return; | 309 return; |
326 } | 310 } |
327 | 311 |
328 [self dismissPanel]; | 312 [self dismissPanel]; |
329 | 313 |
330 [_configuration | 314 [_configuration |
331 setHorizontalSizeClass:self.traitCollection.horizontalSizeClass]; | 315 setHorizontalSizeClass:self.traitCollection.horizontalSizeClass]; |
332 [NSLayoutConstraint deactivateConstraints:_sizingConstraints]; | 316 [NSLayoutConstraint deactivateConstraints:_sizingConstraints]; |
333 _sizingConstraints.reset(); | 317 _sizingConstraints = nil; |
334 [self setNeedsUpdateConstraints]; | 318 [self setNeedsUpdateConstraints]; |
335 } | 319 } |
336 | 320 |
337 - (void)layoutSubviews { | 321 - (void)layoutSubviews { |
338 [super layoutSubviews]; | 322 [super layoutSubviews]; |
339 self.configuration.containerSize = self.superview.bounds.size; | 323 self.configuration.containerSize = self.superview.bounds.size; |
340 // Update the shadow path for this view. | 324 // Update the shadow path for this view. |
341 // Consider switching to "full" MDCShadowLayer. | 325 // Consider switching to "full" MDCShadowLayer. |
342 MDCShadowMetrics* metrics = | 326 MDCShadowMetrics* metrics = |
343 [MDCShadowMetrics metricsWithElevation:kShadowElevation]; | 327 [MDCShadowMetrics metricsWithElevation:kShadowElevation]; |
344 UIBezierPath* shadowPath = [UIBezierPath bezierPathWithRect:self.bounds]; | 328 UIBezierPath* shadowPath = [UIBezierPath bezierPathWithRect:self.bounds]; |
345 self.layer.shadowPath = shadowPath.CGPath; | 329 self.layer.shadowPath = shadowPath.CGPath; |
346 self.layer.shadowOpacity = metrics.topShadowOpacity; | 330 self.layer.shadowOpacity = metrics.topShadowOpacity; |
347 self.layer.shadowRadius = metrics.topShadowRadius; | 331 self.layer.shadowRadius = metrics.topShadowRadius; |
348 } | 332 } |
349 | 333 |
350 - (void)dismissPanel { | 334 - (void)dismissPanel { |
351 ContextualSearch::PanelMotion motion; | 335 ContextualSearch::PanelMotion motion; |
352 motion.state = ContextualSearch::DISMISSED; | 336 motion.state = ContextualSearch::DISMISSED; |
353 motion.nextState = ContextualSearch::DISMISSED; | 337 motion.nextState = ContextualSearch::DISMISSED; |
354 motion.gradation = 0; | 338 motion.gradation = 0; |
355 motion.position = 0; | 339 motion.position = 0; |
356 [_observers panel:self didStopMovingWithMotion:motion]; | 340 [_observers panel:self didStopMovingWithMotion:motion]; |
357 } | 341 } |
358 | 342 |
359 - (void)dealloc { | 343 - (void)dealloc { |
360 [self removeMotionObserver:self]; | 344 [self removeMotionObserver:self]; |
361 [self removeGestureRecognizer:_dragRecognizer]; | 345 [self removeGestureRecognizer:_dragRecognizer]; |
362 [[_positioningGuide owningView] removeLayoutGuide:_positioningGuide]; | 346 [[_positioningGuide owningView] removeLayoutGuide:_positioningGuide]; |
363 [super dealloc]; | |
364 } | 347 } |
365 | 348 |
366 #pragma mark - Gesture recognizer callbacks | 349 #pragma mark - Gesture recognizer callbacks |
367 | 350 |
368 - (void)handleDragFrom:(UIGestureRecognizer*)gestureRecognizer { | 351 - (void)handleDragFrom:(UIGestureRecognizer*)gestureRecognizer { |
369 UIPanGestureRecognizer* recognizer = | 352 UIPanGestureRecognizer* recognizer = |
370 static_cast<UIPanGestureRecognizer*>(gestureRecognizer); | 353 static_cast<UIPanGestureRecognizer*>(gestureRecognizer); |
371 if ([recognizer state] == UIGestureRecognizerStateCancelled) { | 354 if ([recognizer state] == UIGestureRecognizerStateCancelled) { |
372 recognizer.enabled = YES; | 355 recognizer.enabled = YES; |
373 [self dismissPanel]; | 356 [self dismissPanel]; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 } | 441 } |
459 } | 442 } |
460 | 443 |
461 #pragma mark - UIGestureRecognizerDelegate methods | 444 #pragma mark - UIGestureRecognizerDelegate methods |
462 | 445 |
463 - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer | 446 - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer |
464 shouldRecognizeSimultaneouslyWithGestureRecognizer: | 447 shouldRecognizeSimultaneouslyWithGestureRecognizer: |
465 (UIGestureRecognizer*)otherGestureRecognizer { | 448 (UIGestureRecognizer*)otherGestureRecognizer { |
466 // Allow the drag recognizer and the panel content scroll recognizer to | 449 // Allow the drag recognizer and the panel content scroll recognizer to |
467 // co-recognize. | 450 // co-recognize. |
468 if (gestureRecognizer == _dragRecognizer.get() && | 451 if (gestureRecognizer == _dragRecognizer && |
469 otherGestureRecognizer == self.scrollSynchronizer.scrollRecognizer) { | 452 otherGestureRecognizer == self.scrollSynchronizer.scrollRecognizer) { |
470 return YES; | 453 return YES; |
471 } | 454 } |
472 | 455 |
473 if (gestureRecognizer == _dragRecognizer.get() && | 456 if (gestureRecognizer == _dragRecognizer && |
474 [_dragRecognizer state] == UIGestureRecognizerStateChanged) { | 457 [_dragRecognizer state] == UIGestureRecognizerStateChanged) { |
475 [gestureRecognizer setEnabled:NO]; | 458 [gestureRecognizer setEnabled:NO]; |
476 } | 459 } |
477 return NO; | 460 return NO; |
478 } | 461 } |
479 | 462 |
480 @end | 463 @end |
OLD | NEW |