blob: 2ccce58af3f6831ff1d2c64bb43d166080e1c69e [file] [log] [blame]
/**
* Copyright 2018 Alibaba Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "EBExpressionScroller.h"
#import "EBExpressionScope.h"
#import "EBExpression.h"
#import "EBExpressionExecutor.h"
#import "EBUtility.h"
@interface EBExpressionScroller () <UIScrollViewDelegate>
@property (nonatomic, assign) CGPoint lastOffset;
@property (nonatomic, assign) CGPoint lastDOffset;
@property (nonatomic, assign) CGPoint turnOffset;
@property (nonatomic, assign) BOOL turnChange;
@end
@implementation EBExpressionScroller
- (void)updateTargetExpression:(NSMapTable<id,NSDictionary *> *)expressionMap
options:(NSDictionary *)options
exitExpression:(NSDictionary *)exitExpression
callback:(EBKeepAliveCallback)callback {
[super updateTargetExpression:expressionMap
options:options
exitExpression:exitExpression
callback:callback];
[self initScroller];
}
- (void)initScroller {
[EBUtility addScrollDelegate:self source:self.source];
}
- (void)removeExpressionBinding {
[super removeExpressionBinding];
[EBUtility removeScrollDelegate:self source:self.source];
if ([NSThread isMainThread]) {
[self fireStateChangedEvent:@"end"];
}
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
@try {
_turnChange = false;
NSDictionary *scope = [self setUpScope:scrollView];
if (self.turnChange) {
[self fireTurnEvent:scope];
}
BOOL exit = ![self executeExpression:scope];
if (exit) {
[self fireStateChangedEvent:@"exit"];
return;
}
} @catch (NSException *exception) {
NSLog(@"%@",exception);
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self fireStateChangedEvent:@"start"];
}
- (NSDictionary *)setUpScope:(UIScrollView *)sender {
NSMutableDictionary *scope = [self generalScope];
CGFloat factor = [EBUtility factor];
CGPoint offset = sender.contentOffset;
CGPoint dOffset = CGPointMake(offset.x - _lastOffset.x, offset.y - _lastOffset.y);
if ( (dOffset.x>0 && _lastDOffset.x<0) || (dOffset.x<0 && _lastDOffset.x>0) ) {
_turnOffset.x = _lastOffset.x;
_turnChange = true;
}
if ( (dOffset.y>0 && _lastDOffset.y<0) || (dOffset.y<0 && _lastDOffset.y>0) ) {
_turnOffset.y = _lastOffset.y;
_turnChange = true;
}
[scope setValue:@(offset.x / factor) forKey:@"x"];
[scope setValue:@(offset.y / factor) forKey:@"y"];
[scope setValue:@(dOffset.x / factor) forKey:@"dx"];
[scope setValue:@(dOffset.y / factor) forKey:@"dy"];
[scope setValue:@((offset.x - _turnOffset.x) / factor) forKey:@"tdx"];
[scope setValue:@((offset.y - _turnOffset.y) / factor) forKey:@"tdy"];
_lastOffset = offset;
_lastDOffset = dOffset;
return [scope copy];
}
- (void)fireStateChangedEvent:(NSString *)state {
CGFloat factor = [EBUtility factor];
NSDictionary *result = @{@"x": @(_lastOffset.x / factor),
@"y": @(_lastOffset.y / factor),
@"state": state};
if (self.callback) {
self.callback(self.source, result, YES);
}
}
- (void)fireTurnEvent:(NSDictionary* )scope {
NSDictionary *result = @{
@"x": scope[@"x"],
@"y": scope[@"y"],
@"dx": scope[@"dx"],
@"dy": scope[@"dy"],
@"tdx": scope[@"tdx"],
@"tdy": scope[@"tdy"],
@"state": @"turn"
};
if (self.callback) {
self.callback(self.source, result, YES);
}
}
@end