forked from fbsamples/f8app
-
Notifications
You must be signed in to change notification settings - Fork 0
/
F8Scrolling.m
82 lines (68 loc) · 2.53 KB
/
F8Scrolling.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import <UIKit/UIKit.h>
#import <CoreGraphics/CoreGraphics.h>
#import "F8Scrolling.h"
#import "RCTUIManager.h"
#import "RCTScrollView.h"
@interface F8Scrolling () {
NSMapTable *_pinnedViews;
NSMapTable *_distances;
}
@end
@implementation F8Scrolling
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE()
- (instancetype)init
{
if (self = [super init]) {
_pinnedViews = [[NSMapTable alloc] initWithKeyOptions:NSMapTableWeakMemory valueOptions:NSMapTableWeakMemory capacity:20];
_distances = [[NSMapTable alloc] initWithKeyOptions:NSMapTableWeakMemory valueOptions:NSMapTableStrongMemory capacity:20];
}
return self;
}
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
RCT_EXPORT_METHOD(pin:(nonnull NSNumber *)scrollViewReactTag
toView:(nonnull NSNumber *)pinnedViewReactTag
withDistance:(nonnull NSNumber *)distance)
{
UIView *pinnedView = [self.bridge.uiManager viewForReactTag:pinnedViewReactTag];
UIView *scrollView = [self.bridge.uiManager viewForReactTag:scrollViewReactTag];
if ([scrollView isKindOfClass:[RCTScrollView class]]) {
RCTScrollView *reactScrollView = (RCTScrollView *)scrollView;
[_pinnedViews setObject:pinnedView forKey:reactScrollView.scrollView];
[_distances setObject:distance forKey:reactScrollView.scrollView];
[reactScrollView setNativeScrollDelegate:self];
[self scrollViewDidScroll:reactScrollView.scrollView];
}
}
RCT_EXPORT_METHOD(unpin:(nonnull NSNumber *)scrollViewReactTag)
{
UIView *scrollView = [self.bridge.uiManager viewForReactTag:scrollViewReactTag];
if ([scrollView isKindOfClass:[RCTScrollView class]]) {
RCTScrollView *reactScrollView = (RCTScrollView *)scrollView;
[_pinnedViews removeObjectForKey:reactScrollView.scrollView];
[_distances removeObjectForKey:reactScrollView.scrollView];
[reactScrollView setNativeScrollDelegate:nil];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
UIView *pinnedView = [_pinnedViews objectForKey:scrollView];
if (!pinnedView) {
return;
}
CGFloat distance = [[_distances objectForKey:scrollView] doubleValue];
CGFloat y = MAX(0, distance - scrollView.contentOffset.y);
pinnedView.transform = CGAffineTransformMakeTranslation(0, y);
}
@end