|
1 | 1 | #import "RNNComponentPresenter.h" |
2 | 2 | #import "RNNComponentViewController.h" |
| 3 | +#import "RNNScrollEdgeEffectOptions.h" |
3 | 4 | #import "TopBarTitlePresenter.h" |
4 | 5 | #import "UITabBarController+RNNOptions.h" |
5 | 6 | #import "UIViewController+RNNOptions.h" |
6 | 7 |
|
| 8 | +static NSNumber *RNNScrollEdgeEffectStyleFromString(NSString *value) { |
| 9 | + if ([value isEqualToString:@"hard"]) |
| 10 | + return @(2); |
| 11 | + if ([value isEqualToString:@"soft"]) |
| 12 | + return @(1); |
| 13 | + return @(0); // automatic |
| 14 | +} |
| 15 | + |
| 16 | +static RNNScrollEdgeOptions *RNNScrollEdgeOptionsForKey(RNNScrollEdgeEffectOptions *options, |
| 17 | + NSString *edgeKey) { |
| 18 | + if ([edgeKey isEqualToString:@"topEdgeEffect"]) |
| 19 | + return options.top; |
| 20 | + if ([edgeKey isEqualToString:@"bottomEdgeEffect"]) |
| 21 | + return options.bottom; |
| 22 | + if ([edgeKey isEqualToString:@"leftEdgeEffect"]) |
| 23 | + return options.left; |
| 24 | + if ([edgeKey isEqualToString:@"rightEdgeEffect"]) |
| 25 | + return options.right; |
| 26 | + return nil; |
| 27 | +} |
| 28 | + |
| 29 | +static BOOL RNNScrollEdgeEffectHasAnyValue(RNNScrollEdgeEffectOptions *options) { |
| 30 | + if (!options) |
| 31 | + return NO; |
| 32 | + if (options.hidden.hasValue || options.style.hasValue) |
| 33 | + return YES; |
| 34 | + NSArray<RNNScrollEdgeOptions *> *edges = |
| 35 | + @[ options.top ?: [RNNScrollEdgeOptions new], options.bottom ?: [RNNScrollEdgeOptions new], |
| 36 | + options.left ?: [RNNScrollEdgeOptions new], options.right ?: [RNNScrollEdgeOptions new] ]; |
| 37 | + for (RNNScrollEdgeOptions *edge in edges) { |
| 38 | + if (edge.hidden.hasValue || edge.style.hasValue) |
| 39 | + return YES; |
| 40 | + } |
| 41 | + return NO; |
| 42 | +} |
| 43 | + |
| 44 | +static void RNNApplyScrollEdgeEffectToScrollView(UIScrollView *scrollView, |
| 45 | + RNNScrollEdgeEffectOptions *options) { |
| 46 | + if (![scrollView respondsToSelector:NSSelectorFromString(@"topEdgeEffect")]) |
| 47 | + return; |
| 48 | + NSArray<NSString *> *edgeKeys = |
| 49 | + @[ @"topEdgeEffect", @"bottomEdgeEffect", @"leftEdgeEffect", @"rightEdgeEffect" ]; |
| 50 | + for (NSString *key in edgeKeys) { |
| 51 | + id effect = [scrollView valueForKey:key]; |
| 52 | + if (!effect) |
| 53 | + continue; |
| 54 | + RNNScrollEdgeOptions *perEdge = RNNScrollEdgeOptionsForKey(options, key); |
| 55 | + |
| 56 | + Bool *hidden = (perEdge.hidden.hasValue) ? perEdge.hidden : options.hidden; |
| 57 | + Text *style = (perEdge.style.hasValue) ? perEdge.style : options.style; |
| 58 | + |
| 59 | + if (hidden.hasValue && |
| 60 | + [effect respondsToSelector:NSSelectorFromString(@"setHidden:")]) { |
| 61 | + [effect setValue:@([hidden withDefault:NO]) forKey:@"hidden"]; |
| 62 | + } |
| 63 | + if (style.hasValue && |
| 64 | + [effect respondsToSelector:NSSelectorFromString(@"setStyle:")]) { |
| 65 | + [effect setValue:RNNScrollEdgeEffectStyleFromString(style.get) forKey:@"style"]; |
| 66 | + } |
| 67 | + } |
| 68 | +} |
| 69 | + |
| 70 | +static void RNNApplyScrollEdgeEffectToView(UIView *view, RNNScrollEdgeEffectOptions *options) { |
| 71 | + if (!RNNScrollEdgeEffectHasAnyValue(options)) |
| 72 | + return; |
| 73 | + if ([view isKindOfClass:[UIScrollView class]]) { |
| 74 | + RNNApplyScrollEdgeEffectToScrollView((UIScrollView *)view, options); |
| 75 | + } |
| 76 | + for (UIView *subview in view.subviews) { |
| 77 | + RNNApplyScrollEdgeEffectToView(subview, options); |
| 78 | + } |
| 79 | +} |
| 80 | + |
7 | 81 | @implementation RNNComponentPresenter { |
8 | 82 | TopBarTitlePresenter *_topBarTitlePresenter; |
9 | 83 | RNNButtonsPresenter *_buttonsPresenter; |
@@ -34,6 +108,11 @@ - (void)componentWillAppear { |
34 | 108 | - (void)componentDidAppear { |
35 | 109 | [_topBarTitlePresenter componentDidAppear]; |
36 | 110 | [_buttonsPresenter componentDidAppear]; |
| 111 | + |
| 112 | + RNNComponentViewController *viewController = self.boundViewController; |
| 113 | + RNNNavigationOptions *withDefault = |
| 114 | + [viewController.options withDefault:[self defaultOptions]]; |
| 115 | + RNNApplyScrollEdgeEffectToView(viewController.view, withDefault.scrollEdgeEffect); |
37 | 116 | } |
38 | 117 |
|
39 | 118 | - (void)componentDidDisappear { |
@@ -102,6 +181,8 @@ - (void)applyOptions:(RNNNavigationOptions *)options { |
102 | 181 | defaultDisabledColor:withDefault.topBar.rightButtonDisabledColor |
103 | 182 | animated:[withDefault.topBar.animateRightButtons withDefault:NO]]; |
104 | 183 | } |
| 184 | + |
| 185 | + RNNApplyScrollEdgeEffectToView(viewController.view, withDefault.scrollEdgeEffect); |
105 | 186 | } |
106 | 187 |
|
107 | 188 | - (void)applyOptionsOnInit:(RNNNavigationOptions *)options { |
@@ -236,6 +317,10 @@ - (void)mergeOptions:(RNNNavigationOptions *)mergeOptions |
236 | 317 | } |
237 | 318 |
|
238 | 319 | [_topBarTitlePresenter mergeOptions:mergeOptions.topBar resolvedOptions:withDefault.topBar]; |
| 320 | + |
| 321 | + if (RNNScrollEdgeEffectHasAnyValue(mergeOptions.scrollEdgeEffect)) { |
| 322 | + RNNApplyScrollEdgeEffectToView(viewController.view, mergeOptions.scrollEdgeEffect); |
| 323 | + } |
239 | 324 | } |
240 | 325 |
|
241 | 326 | - (void)renderComponents:(RNNNavigationOptions *)options |
|
0 commit comments