blob: 5538cf9b96dfb5a2e65db6845131a3451d246b73 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 "WXRecyclerDragController.h"
@implementation WXRecyclerDragController
- (instancetype)init{
self = [super init];
if (self) {
_excludedAry = [[NSMutableArray alloc] init];
_isDragAnchor = NO;
}
return self;
}
- (void)setCollectionView:(UICollectionView *)collectionView{
_collectionView = collectionView;
_currentLongPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressMethod:)];
_currentLongPress.minimumPressDuration = 0.3f;
[_collectionView addGestureRecognizer:_currentLongPress];
}
- (void)setDragingCell:(UICollectionViewCell *)dragingCell{
_dragingCell = dragingCell;
_dragingCell.hidden = true;
[_collectionView addSubview:_dragingCell];
}
- (void)goThroughAnchor:(WXComponent *)wxComponent indexPath:(NSIndexPath *)indexPath{
if (wxComponent.attributes && [wxComponent.attributes[@"dragExcluded"] boolValue]){
[_excludedAry addObject:indexPath];
NSSet *set = [NSSet setWithArray:_excludedAry];
[_excludedAry removeAllObjects];
[_excludedAry addObjectsFromArray:[set allObjects]];
}
NSMutableArray *subviewComponents = [[NSMutableArray alloc] init];
[subviewComponents addObjectsFromArray:wxComponent.subcomponents];
WXComponent *anchorComponent;
for (int i = 0 ; i < subviewComponents.count ; i++){
WXComponent *compoent = subviewComponents[i];
if (compoent.attributes[@"dragAnchor"]) {
anchorComponent = compoent;
_isDragAnchor = YES;
break;
}
if (compoent.subcomponents && compoent.subcomponents.count && compoent.subcomponents.count > 0) {
[subviewComponents addObjectsFromArray:compoent.subcomponents];
}
}
if (anchorComponent) {
if (_currentLongPress) {
[self.collectionView removeGestureRecognizer:_currentLongPress];
_currentLongPress = nil;
}
if (_dragTriggerType == WXRecyclerDragTriggerPan) {
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(longPressMethod:)];
[anchorComponent.view addGestureRecognizer:panGestureRecognizer];
}else{
UILongPressGestureRecognizer *longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressMethod:)];
[anchorComponent.view addGestureRecognizer:longPressGestureRecognizer];
}
}
}
#pragma mark - dragMethod
- (void)longPressMethod:(UILongPressGestureRecognizer*)gesture
{
if (_isDragable) {
switch (gesture.state) {
case UIGestureRecognizerStateBegan:
[self dragBegin:gesture];
break;
case UIGestureRecognizerStateChanged:
[self dragChanged:gesture];
break;
case UIGestureRecognizerStateEnded:
[self dragEnd:gesture];
break;
default:
break;
}
}
}
- (void)dragBegin:(UILongPressGestureRecognizer *)gesture{
CGPoint point = [gesture locationInView:_collectionView];
_startIndexPath = [self getDragingIndexPathWithPoint:point];
if (!_startIndexPath) {
return;
}
if ([self.delegate respondsToSelector:@selector(fireEvent:params:)]) {
[self.delegate dragFireEvent:@"dragstart" params:@{@"fromIndex":[NSString stringWithFormat:@"%ld",(long)_startIndexPath.row]}];
}
_dragingIndexPath = [self getDragingIndexPathWithPoint:point];
if (!_dragingIndexPath) {
return;
}
[_collectionView bringSubviewToFront:_dragingCell];
_dragingCell.frame = [_collectionView cellForItemAtIndexPath:_dragingIndexPath].frame;
_dragingCell.hidden = false;
[UIView animateWithDuration:0.3 animations:^{
[_dragingCell setTransform:CGAffineTransformMakeScale(1.2, 1.2)];
}];
}
- (void)dragChanged:(UILongPressGestureRecognizer *)gesture{
if (!_startIndexPath) {
return;
}
CGPoint point = [gesture locationInView:_collectionView];
_dragingCell.center = point;
_targetIndexPath = [self getTargetIndexPathWithPoint:point];
if (_targetIndexPath && _dragingIndexPath && (_targetIndexPath.section == _startIndexPath.section)){
[_collectionView moveItemAtIndexPath:_dragingIndexPath toIndexPath:_targetIndexPath];
_dragingIndexPath = _targetIndexPath;
}
}
- (void)dragEnd:(UILongPressGestureRecognizer *)gesture{
if (!_startIndexPath || !_dragingIndexPath) {
return;
}
if ([self.delegate respondsToSelector:@selector(fireEvent:params:)]) {
[self.delegate dragFireEvent:@"dragend" params:@{@"toIndex":[NSString stringWithFormat:@"%ld",(long)_dragingIndexPath.row],@"fromIndex":[NSString stringWithFormat:@"%ld",(long)_startIndexPath.row]}];
}
CGRect endFrame = [_collectionView cellForItemAtIndexPath:_dragingIndexPath].frame;
__weak typeof(self) weakSelf = self;
[UIView animateWithDuration:0.3 animations:^{
[weakSelf.dragingCell setTransform:CGAffineTransformMakeScale(1.0, 1.0)];
weakSelf.dragingCell.frame = endFrame;
} completion:^(BOOL finished) {
weakSelf.dragingCell.hidden = YES;
if ([weakSelf.delegate respondsToSelector:@selector(updateDataSource)]) {
[weakSelf.delegate updateDataSource];
}
}];
}
- (NSIndexPath *)getDragingIndexPathWithPoint:(CGPoint)point{
NSIndexPath *dragingIndexPath = nil;
for (NSIndexPath *indexPath in [_collectionView indexPathsForVisibleItems]){
if (CGRectContainsPoint([_collectionView cellForItemAtIndexPath:indexPath].frame,point)) {
dragingIndexPath = indexPath;
break;
}
}
BOOL isExcluded = NO;
if (dragingIndexPath) {
for (NSIndexPath *indexPath in _excludedAry) {
if (indexPath.row == dragingIndexPath.row) {
isExcluded = YES;
}
}
}
return isExcluded?nil:dragingIndexPath;
}
- (NSIndexPath *)getTargetIndexPathWithPoint:(CGPoint)point{
NSIndexPath *targetIndexPath = nil;
for (NSIndexPath *indexPath in _collectionView.indexPathsForVisibleItems) {
if (CGRectContainsPoint([_collectionView cellForItemAtIndexPath:indexPath].frame, point)) {
targetIndexPath = indexPath;
}
}
return targetIndexPath;
}
- (void)dealloc{
}
@end