//
// OCFTFreeCombinationView.m
// ZNSLSDK
//
// Copyright © 2022 yull. All rights reserved.
//
#import "OCFTFreeCombinationView.h"
#import "Masonry.h"
#import "OCFTMultiRecordDefine.h"
#import "OCFTFreeCombinationCollectionViewCell.h"
#import "PAFFToast.h"
#import "OCFTUICollectionViewLeftAlignedFlowLayout.h"
#import "OCFTFreeCombinationDataModel.h"
#import "ZNSLLogTool.h"
#define OCFTItemWidth 115.f
static NSString * const cellIndentifier = @"cellIndentifier";
@interface OCFTFreeCombinationView()<UICollectionViewDataSource,UICollectionViewDelegate,UIGestureRecognizerDelegate,OCFTUICollectionViewDelegateLeftAlignedFlowLayout>
@property (nonatomic, strong) UICollectionView *freeCollectionView;
@property (nonatomic, strong) NSArray *dataSourceArray;
@property (nonatomic, strong) NSMutableArray *dataMutableArray;
@property (nonatomic, strong) UIPanGestureRecognizer *panGesture;
@property (nonatomic, strong) NSIndexPath *activeIndexPath;
//拖动的cell
@property (nonatomic, strong) OCFTFreeCombinationCollectionViewCell *activeCell;
@property (nonatomic, strong) NSIndexPath *changedIndexPath;
@property (nonatomic, assign) CGPoint changedPoint;
@property (nonatomic, copy) void(^completedBlock)(NSString *groupString);
@property (nonatomic, assign) NSUInteger roleCount;
@property (nonatomic, strong) UICollectionSectionColorReusableView *sectionColorReusableView;
//记录相交的Cell
@property (nonatomic, strong) OCFTFreeCombinationCollectionViewCell *intersectCell;
@end
@implementation OCFTFreeCombinationView
#pragma mark - init
- (instancetype)initWithDataSourceArray:(NSArray *)datSourceArray completedBlock:(void(^)(NSString *groupString))completedBlock {
if (self = [super init]) {
self.roleCount = datSourceArray.count;
self.completedBlock = completedBlock;
self.intersectCell = nil;
[self handleDataSource:datSourceArray];
[self addAllSubView];
}
return self;
}
- (void)handleDataSource:(NSArray *)array {
self.dataMutableArray = [NSMutableArray array];
for (NSInteger i = 0;i < array.count; i ++) {
NSMutableArray *tempArray = [NSMutableArray array];
OCFTFreeCombinationDataModel *model = [[OCFTFreeCombinationDataModel alloc]init];
if (0 == i) {
model.nailShow = YES;
}else{
model.nailShow = NO;
}
NSDictionary *dict = array[i];
if ([dict[@"role"] isEqualToString:@"1"]) {
model.name = @"代理人";
}else if ([dict[@"role"] isEqualToString:@"2"]){
model.name = @"投保人";
}else if ([dict[@"role"] isEqualToString:@"4"]){
model.name = @"被保人二";
}else if([dict[@"role"] isEqualToString:@"3"]){
//是否包含被保人二
if ([self getHasContainerInsured:array]) {
model.name = @"被保人一";
}else{
model.name = @"被保人";
}
}else{
model.name = @"未知角色";
}
model.excuteRoleShow = YES;
[tempArray addObject:model];
[self.dataMutableArray addObject:tempArray];
}
self.dataSourceArray = [NSArray arrayWithArray:self.dataMutableArray];
}
- (BOOL)getHasContainerInsured:(NSArray *)array {
BOOL isContainer = NO;
for (NSInteger i = 0; i < array.count; i ++) {
NSDictionary *dict = array[i];
if ([dict[@"role"] isEqualToString:@"4"]) {
isContainer = YES;
break;
}
}
return isContainer;
}
- (void)addAllSubView {
UIView *topView = [UIView new];
topView.backgroundColor = UIColorFromHex(0xFFF1F3);
topView.layer.masksToBounds = YES;
topView.layer.cornerRadius = 4.f;
topView.layer.borderColor = UIColorFromHex(0xFFC2C5).CGColor;
topView.layer.borderWidth = 1.f;
[self addSubview:topView];
[topView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self).offset(16.f);
make.right.mas_equalTo(self).offset(-16.f);
make.top.mas_equalTo(self).offset(11.f);
make.height.mas_equalTo(60.f);
}];
UILabel *warningLabel = [[UILabel alloc]init];
warningLabel.text = @"!";
warningLabel.backgroundColor = [UIColor colorWithRed:248/255.f green:205/255.f blue:118/255.f alpha:1.f];
warningLabel.font = [UIFont systemFontOfSize:12.f];
warningLabel.textColor = [UIColor whiteColor];
warningLabel.textAlignment = NSTextAlignmentCenter;
warningLabel.layer.masksToBounds = YES;
warningLabel.layer.cornerRadius = 7.5f;
[topView addSubview:warningLabel];
[warningLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(topView).offset(16.f);
make.top.mas_equalTo(topView).offset(9.f);
make.size.mas_equalTo(CGSizeMake(15.f, 15.f));
}];
UITextView *textView = [[UITextView alloc]init];
textView.backgroundColor = [UIColor clearColor];
textView.text = @"除代理人外,其他角色可拖动自由组合。\n请确认好各组人员在哪一端进行录制。(默认是通过第一位的金管家进行录制)";
textView.font = [UIFont systemFontOfSize:12.f];
textView.textColor = UIColorFromHex(0x3F4254);
textView.textAlignment = NSTextAlignmentLeft;
textView.userInteractionEnabled = NO;
[topView addSubview:textView];
[textView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(warningLabel.mas_right).offset(8.f);
make.right.mas_equalTo(topView).offset(-16.f);
make.top.bottom.mas_equalTo(topView);
}];
//表视图
[self addSubview:self.freeCollectionView];
[self.freeCollectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self).offset(16.f);
make.right.mas_equalTo(self).offset(-16.f);
make.top.mas_equalTo(topView.mas_bottom).offset(16.f);
make.height.mas_equalTo(62 * self.dataSourceArray.count);
}];
[self.freeCollectionView reloadData];
//添加拖动手势
self.panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGestureMoving:)];
self.panGesture.delegate = self;
[self.freeCollectionView addGestureRecognizer:self.panGesture];
//回传数据
if (self.completedBlock) {
self.completedBlock([self getGroupString]);
}
}
- (NSString *)getGroupString {
NSString *jsonStr = @"";
for (NSInteger i = 0; i < self.dataSourceArray.count; i ++) {
NSArray *tempArray = self.dataSourceArray[i];
if ((i != 0) && (tempArray.count > 0)) {
jsonStr = [jsonStr stringByAppendingString:@"&"];
}
for (NSInteger j = 0; j < tempArray.count ; j ++) {
OCFTFreeCombinationDataModel *model = tempArray[j];
if (0 == j) {
if ([model.name isEqualToString:@"代理人"]) {
jsonStr = [jsonStr stringByAppendingString:@"1"];
}else if([model.name isEqualToString:@"投保人"]){
jsonStr = [jsonStr stringByAppendingString:@"2"];
}else if([model.name isEqualToString:@"被保人"] || [model.name isEqualToString:@"被保人一"]){
jsonStr = [jsonStr stringByAppendingString:@"3"];
}else if([model.name isEqualToString:@"被保人二"]){
jsonStr = [jsonStr stringByAppendingString:@"4"];
}else{
}
}else{
if ([model.name isEqualToString:@"代理人"]) {
jsonStr = [jsonStr stringByAppendingString:@"/1"];
}else if([model.name isEqualToString:@"投保人"]){
jsonStr = [jsonStr stringByAppendingString:@"/2"];
}else if([model.name isEqualToString:@"被保人"] || [model.name isEqualToString:@"被保人一"]){
jsonStr = [jsonStr stringByAppendingString:@"/3"];
}else if([model.name isEqualToString:@"被保人二"]){
jsonStr = [jsonStr stringByAppendingString:@"/4"];
}else{
}
}
}
}
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:[NSString stringWithFormat:@"自由组合结果ABC==:%@",jsonStr]];
return jsonStr;
}
#pragma mark - Guesture
//是否允许开始触发手势
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)panGesture;
{
self.activeIndexPath = [self.freeCollectionView indexPathForItemAtPoint:[panGesture locationInView:self.freeCollectionView]];
if (nil == self.activeIndexPath)
{
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:self.activeIndexPath=nil"];
//取消手势
return NO;
}
return YES;
}
- (void)panGestureMoving:(UIPanGestureRecognizer *)panGesture {
switch (panGesture.state) {
case UIGestureRecognizerStateBegan:{
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateBegan"];
self.activeIndexPath = [self.freeCollectionView indexPathForItemAtPoint:[panGesture locationInView:self.freeCollectionView]];
if (nil == self.activeIndexPath) {
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateBegan self.activeIndexPath = nil"];
break;
}
OCFTFreeCombinationCollectionViewCell *cell = (OCFTFreeCombinationCollectionViewCell *)[self.freeCollectionView cellForItemAtIndexPath:self.activeIndexPath];
self.activeCell = cell;
if ((nil != self.activeIndexPath) && (0 == self.activeIndexPath.section)) {
[PAFFToast showToast:@"除代理人外,其他角色可拖动" duration:2.0f];
self.activeCell.isFixed = YES;
}else{
self.activeCell.isMoving = YES;
//隐藏拖动section的DecorationView
NSArray *array = [self getDecorationView];
for (NSInteger i = 0; i < array.count; i ++) {
UICollectionSectionColorReusableView *tempView = array[i];
NSArray *array = self.dataMutableArray[self.activeIndexPath.section];
if (1 == array.count && ((tempView.tag - 10000) == self.activeIndexPath.section)) {
self.sectionColorReusableView = tempView;
self.sectionColorReusableView.hidden = YES;
}else{
tempView.hidden = NO;
}
}
}
[self.freeCollectionView beginInteractiveMovementForItemAtIndexPath:self.activeIndexPath];
break;
}
case UIGestureRecognizerStateChanged:{
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateChanged"];
if (nil == self.activeIndexPath) {
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateChanged self.activeIndexPath = nil"];
break;
}
if (0 == self.activeIndexPath.section) {//代理人不可以拖动
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateChanged代理人不可以拖动"];
break;
}
//当前手指位置
self.changedPoint = [panGesture locationInView:self.freeCollectionView];
self.changedIndexPath = [self.freeCollectionView indexPathForItemAtPoint:self.changedPoint];
//超过边界处理
if ((self.changedPoint.x <= 0.f) || (self.changedPoint.y <= 0.f) || (self.changedPoint.x >= self.freeCollectionView.bounds.size.width) || (self.changedPoint.y >= self.freeCollectionView.bounds.size.height)) {
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:超过边界"];
}else{
//没有超过边界,处理相交
[self handleIntersect];
//更新拖动位置
[self.freeCollectionView updateInteractiveMovementTargetPosition:self.changedPoint];
}
break;
}
case UIGestureRecognizerStateEnded:{
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateEnded"];
if (nil == self.activeIndexPath) {
[self.freeCollectionView cancelInteractiveMovement];
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateEnded self.activeIndexPath = nil"];
break;
}
//取消移动
[self.freeCollectionView cancelInteractiveMovement];
//代理人固定样式和cell移动样式
if (0 == self.activeIndexPath.section) {
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateEnded代理人不可以拖动"];
self.activeCell.isFixed = NO;
self.intersectCell = nil;
}else{
self.activeCell.isMoving = NO;
[self delayOneSecondShow];//延迟0.15s显示DecorationView
if (nil == self.intersectCell) {//没有相交
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateEnded没有相交"];
[self handleNoInterest];
}else{//相交
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateEnded有相交过"];
if (!self.intersectCell.isIntersect) {//相交过,但最后手势结束点没有相交
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateEnded最后结束点没有相交"];
[self handleNoInterest];
self.intersectCell = nil;
}else{
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateEnded最后结束点相交"];
//处理是否和代理人相交且拖动的不是代理人
NSIndexPath *empIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
if (empIndexPath == [self.freeCollectionView indexPathForCell:self.intersectCell] && self.intersectCell.isIntersect){
self.intersectCell.isIntersect = NO;
self.intersectCell = nil;
if (!(0 == self.activeIndexPath.section)) {
[PAFFToast showToast:@"代理人不能和其他角色合并" duration:2.0f];
}
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateEnded代理人不能和其他角色合并"];
}else if(0 == self.activeIndexPath.section){
self.activeCell.isFixed = NO;
self.intersectCell = nil;
[PAFFToast showToast:@"除代理人外,其他角色可拖动" duration:2.0f];
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateEnded除代理人外,其他角色可拖动"];
}else{
NSIndexPath *sourceIndexPath = self.activeIndexPath;
NSIndexPath *destinationIndexPath = [self.freeCollectionView indexPathForCell:self.intersectCell];
if ((sourceIndexPath.section == destinationIndexPath.section) && (sourceIndexPath.row == destinationIndexPath.row)) {
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:StateEnded和自己相交还原到自己的位置"];
//重置相交的cell
self.intersectCell.isIntersect = NO;
self.intersectCell = nil;
break;
}
if (self.changedPoint.x < self.intersectCell.center.x ) {//插入到头部
[self freeCombinationMoveItemAtIndexPath:sourceIndexPath toIndexPath:destinationIndexPath destinationFront:YES];
}else{//插入到尾部
[self freeCombinationMoveItemAtIndexPath:sourceIndexPath toIndexPath:destinationIndexPath destinationFront:NO];
}
dispatch_async(dispatch_get_main_queue(), ^{
//重置相交的cell
self.intersectCell.isIntersect = NO;
self.intersectCell = nil;
self.dataSourceArray = [self.dataMutableArray copy];
[self.freeCollectionView reloadData];
//回传数据
if (self.completedBlock) {
self.completedBlock([self getGroupString]);
}
});
}
}
}
}
break;
}
default:{
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:default"];
[self.freeCollectionView cancelInteractiveMovement];
[self delayOneSecondShow];
break;
}
}
}
#pragma mark - private method
- (void)delayOneSecondShow {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.11f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.sectionColorReusableView.hidden = NO;
});
}
//没有相交
- (void)handleNoInterest {
if (nil == self.changedIndexPath) {//拖动到空白处
if (self.changedPoint.y >= [self getCollectionViewLastEmptyPointY]) {//往底部拖动
NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:self.dataMutableArray[self.activeIndexPath.section]];
if ((mutableArray.count > 1) && (self.activeIndexPath != nil)) {//重新单独拖动为一组,拖动的那组count大于1
[self handleSeparateGroup:mutableArray];
}else{
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:拖动超过下边界,不能单独成组"];
}
}else{
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:拖动超过顶左右边界"];
}
}else{
if (self.activeIndexPath == self.changedIndexPath) {
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:handleNoInterest自己相交"];
}else{
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:异常情况,不存在"];
NSString *stringContent = [NSString stringWithFormat:@"ABC==self.activeIndexPath:%ld-%ld,self.changedIndexPath:%ld-%ld",self.activeIndexPath.section,self.activeIndexPath.row,self.changedIndexPath.section,self.changedIndexPath.row];
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:stringContent];
}
}
}
//单独成组
- (void)handleSeparateGroup:(NSMutableArray *)mutableArray {
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:拖动超过下边界,可以单独成组"];
if (0 == self.activeIndexPath.row) {//移除头部
OCFTFreeCombinationDataModel *nextModel = mutableArray[self.activeIndexPath.row + 1];
nextModel.excuteRoleShow = YES;
}
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:removeObject"];
OCFTFreeCombinationDataModel *model = mutableArray[self.activeIndexPath.row];
[mutableArray removeObjectAtIndex:self.activeIndexPath.row];
[self.dataMutableArray replaceObjectAtIndex:self.activeIndexPath.section withObject:[mutableArray copy]];
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:replaceObjectAtIndex"];
//数据移动处理
[self handleDataMove];
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:handleDataMove"];
//获取空数组的下标
NSInteger index = [self getEmptyArrayWithIndex];
NSMutableArray *lastMutableArray = [NSMutableArray arrayWithArray:self.dataMutableArray[index]];
model.excuteRoleShow = YES;
[lastMutableArray addObject:model];
[self.dataMutableArray replaceObjectAtIndex:index withObject:[lastMutableArray copy]];
dispatch_async(dispatch_get_main_queue(), ^{
self.dataSourceArray = [self.dataMutableArray copy];
[self.freeCollectionView reloadData];
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:reloadData之后"];
//回传数据
if (self.completedBlock) {
self.completedBlock([self getGroupString]);
}
});
}
//处理相交
- (void)handleIntersect {
for (OCFTFreeCombinationCollectionViewCell *cell in self.freeCollectionView.visibleCells) {
if ([self.freeCollectionView indexPathForCell:cell] == self.activeIndexPath) {
continue;
}
CGRect rect1 = CGRectMake(fabs(self.changedPoint.x - cell.bounds.size.width/2), fabs(self.changedPoint.y - cell.bounds.size.height/2), cell.bounds.size.width, cell.bounds.size.height);
CGRect rect2 = cell.frame;
if (CGRectIntersectsRect(rect1, rect2)) {//相交
OCFTFreeCombinationCollectionViewCell *lastCell = [self getClosestDistanceCell];//获取最近相交的cell
if ([self.freeCollectionView indexPathForCell:cell] == [self.freeCollectionView indexPathForCell:lastCell]) {
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:相交changed"];
cell.isIntersect = YES;
self.intersectCell = cell;
}else{
cell.isIntersect = NO;
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:不相交changed1"];
}
}else{
cell.isIntersect = NO;
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:不相交changed2"];
}
}
}
//获取相交的数组
- (NSArray *)getIntersectCellWithArray {
NSMutableArray *mutableArray = [NSMutableArray array];
for (OCFTFreeCombinationCollectionViewCell *cell in self.freeCollectionView.visibleCells) {
if ([self.freeCollectionView indexPathForCell:cell] == self.activeIndexPath) {
continue;
}
CGRect rect1 = CGRectMake(fabs(self.changedPoint.x - cell.bounds.size.width/2), fabs(self.changedPoint.y - cell.bounds.size.height/2), cell.bounds.size.width, cell.bounds.size.height);
CGRect rect2 = cell.frame;
if (CGRectIntersectsRect(rect1, rect2)) {//相交
[mutableArray addObject:cell];
}
}
return [mutableArray copy];
}
//获取相交最近的Cell
- (OCFTFreeCombinationCollectionViewCell *)getClosestDistanceCell {
NSArray *array = [self getIntersectCellWithArray];
if (0 == array.count) {
return nil;
}else if (1 == array.count){
OCFTFreeCombinationCollectionViewCell *cell = [array firstObject];
return cell;
}else{
NSMutableArray *tempArray = [NSMutableArray array];
for (NSInteger i = 0; i < array.count; i ++) {
OCFTFreeCombinationCollectionViewCell *cell = array[i];
CGFloat space = sqrtf(pow(self.changedPoint.x - cell.center.x, 2) + powf(self.changedPoint.y - cell.center.y, 2));
[tempArray addObject:[NSNumber numberWithFloat:space]];
}
//查找出最小距离
CGFloat minSpace = 0.f;
for (NSInteger j = 0; j < tempArray.count; j ++) {
NSNumber *number = tempArray[j];
if (0 == j) {
minSpace = [number floatValue];
}else{
if (minSpace > [number floatValue]) {
minSpace = [number floatValue];
}
}
}
NSInteger index = [tempArray indexOfObject:[NSNumber numberWithFloat:minSpace]];
OCFTFreeCombinationCollectionViewCell *cell1 = array[index];
return cell1;
}
}
- (CGFloat)getCollectionViewLastEmptyPointY {
NSInteger index = 0;
for (NSInteger k = self.dataMutableArray.count - 1;k >= 0; k --) {
NSArray *array = self.dataMutableArray[k];
if (array.count > 0) {
index ++;
}
}
CGFloat pointY = index * 16 + index * 44.f - 8.f;
return pointY;
}
- (NSInteger)getEmptyArrayWithIndex {
NSInteger index = 0;
for (NSInteger k = 0; k < self.dataMutableArray.count; k ++) {
NSArray *array = self.dataMutableArray[k];
if (array.count == 0) {
index = k;
break;
}
}
return index;
}
- (void)handleDataMove {
for (NSInteger i = 0; i < self.dataMutableArray.count; i ++) {
NSArray *array = self.dataMutableArray[i];
if (0 == array.count) {
[self.dataMutableArray removeObject:array];
}
}
for (NSInteger j = 0; j < (self.roleCount - self.dataMutableArray.count); j ++) {
[self.dataMutableArray addObject:[NSArray array]];
}
}
- (void)freeCombinationMoveItemAtIndexPath:(NSIndexPath )sourceIndexPath toIndexPath:(NSIndexPath)destinationIndexPath destinationFront:(BOOL)destinationFront {
if (destinationIndexPath.section == sourceIndexPath.section) {//同一个section移动
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:同一个section移动"];
NSArray *sameSectionArray = [NSArray arrayWithArray:self.dataMutableArray[destinationIndexPath.section]];
BOOL canChange = (sameSectionArray.count > sourceIndexPath.item) && (sameSectionArray.count > destinationIndexPath.item);
if (destinationFront) {//插入到destinationIndexPath的头部
if (canChange) {
if (sourceIndexPath == [NSIndexPath indexPathForRow:(destinationIndexPath.row - 1) inSection:destinationIndexPath.section]) {
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:头部,移动到原来的位置不用处理"];
}else{
[self handleDatasourceExchangeWithSourceIndexPath:sourceIndexPath destinationIndexPath:destinationIndexPath withArray:sameSectionArray];
}
}
}else{//插入到destinationIndexPath的尾部
if (canChange) {
if (sourceIndexPath == [NSIndexPath indexPathForRow:(destinationIndexPath.row + 1) inSection:destinationIndexPath.section]) {
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:尾部,移动到原来的位置不用处理"];
}else{
if (destinationIndexPath.row == (sameSectionArray.count - 1)) {//添加到最后一个元素
NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:sameSectionArray];
OCFTFreeCombinationDataModel *sourceModel = mutableArray[sourceIndexPath.row];
sourceModel.excuteRoleShow = NO;
[mutableArray insertObject:sourceModel atIndex:destinationIndexPath.row + 1];
if (sourceIndexPath.row < mutableArray.count) {
[mutableArray removeObjectAtIndex:sourceIndexPath.row];
}else{
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:移除数据不存在2"];
return;
}
for (NSInteger i = 0; i < mutableArray.count; i ++) {
OCFTFreeCombinationDataModel *model = mutableArray[i];
if (0 == i) {
model.excuteRoleShow = YES;
}else if(i == (mutableArray.count - 1)){
model.excuteRoleShow = NO;
}else{
model.excuteRoleShow = NO;
}
}
[self.dataMutableArray replaceObjectAtIndex:destinationIndexPath.section withObject:[mutableArray copy]];
}else{
[self handleDatasourceExchangeWithSourceIndexPath:sourceIndexPath destinationIndexPath:destinationIndexPath withArray:sameSectionArray];
}
}
}
}
}else{//不同section移动
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:不同section移动"];
NSMutableArray *sourceArray = [NSMutableArray arrayWithArray:self.dataMutableArray[sourceIndexPath.section]];
NSMutableArray *destinationArray = [NSMutableArray arrayWithArray:self.dataMutableArray[destinationIndexPath.section]];
OCFTFreeCombinationDataModel *sourceModel = sourceArray[sourceIndexPath.row];
if (destinationFront) {//插入到destinationIndexPath的头部
//目标数据
if (destinationIndexPath.row == 0) {//插入到头部
OCFTFreeCombinationDataModel *destinationModel = destinationArray[destinationIndexPath.row];
destinationModel.excuteRoleShow = NO;
sourceModel.excuteRoleShow = YES;
[destinationArray insertObject:sourceModel atIndex:destinationIndexPath.row];
}else if(destinationIndexPath.row == destinationArray.count){//插入到尾部
sourceModel.excuteRoleShow = NO;
[destinationArray insertObject:sourceModel atIndex:destinationIndexPath.row];
}else{//插入到中间
sourceModel.excuteRoleShow = NO;
[destinationArray insertObject:sourceModel atIndex:destinationIndexPath.row];
}
[self.dataMutableArray replaceObjectAtIndex:destinationIndexPath.section withObject:[destinationArray copy]];
//源数据
if (sourceIndexPath.row == 0) {//移除头部
if (1 == sourceArray.count) {
[sourceArray removeObject:sourceModel];
}else if(sourceArray.count >= 2){
OCFTFreeCombinationDataModel *lastModel = sourceArray[sourceIndexPath.row + 1];
lastModel.excuteRoleShow = YES;
[sourceArray removeObject:sourceModel];
}
}else if((sourceIndexPath.row + 1) == sourceArray.count){//移除尾部
if (1 == sourceArray.count) {
[sourceArray removeObject:sourceModel];
}else if(sourceArray.count >= 2){
[sourceArray removeObject:sourceModel];
}
}else{//移除中间
[sourceArray removeObject:sourceModel];
}
[self.dataMutableArray replaceObjectAtIndex:sourceIndexPath.section withObject:[sourceArray copy]];
}else{//插入到destinationIndexPath的尾部
//目标数据
if (destinationIndexPath.row == (destinationArray.count - 1)) {//添加到最后一个元素
sourceModel.excuteRoleShow = NO;
[destinationArray insertObject:sourceModel atIndex:destinationIndexPath.row + 1];
}else{
sourceModel.excuteRoleShow = NO;
[destinationArray insertObject:sourceModel atIndex:destinationIndexPath.row + 1];
}
[self.dataMutableArray replaceObjectAtIndex:destinationIndexPath.section withObject:[destinationArray copy]];
//源数据
if (sourceIndexPath.row == 0) {//移除头部
if (1 == sourceArray.count) {
[sourceArray removeObject:sourceModel];
}else if(sourceArray.count >= 2){
OCFTFreeCombinationDataModel *lastModel = sourceArray[sourceIndexPath.row + 1];
lastModel.excuteRoleShow = YES;
[sourceArray removeObject:sourceModel];
}
}else if((sourceIndexPath.row + 1) == sourceArray.count){//移除尾部
if (1 == sourceArray.count) {
[sourceArray removeObject:sourceModel];
}else if(sourceArray.count >= 2){
[sourceArray removeObject:sourceModel];
}
}else{//移除中间
[sourceArray removeObject:sourceModel];
}
[self.dataMutableArray replaceObjectAtIndex:sourceIndexPath.section withObject:[sourceArray copy]];
}
}
[self objArraToJSON:self.dataMutableArray];
}
- (NSArray *)getDecorationView {
NSMutableArray *viewArray = [NSMutableArray array];
for (UIView *view in self.freeCollectionView.subviews) {
if ([view isKindOfClass:[UICollectionSectionColorReusableView class]]) {
[viewArray addObject:view];
}
}
return viewArray;
}
#pragma mark - UICollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
// ZNSLLog(@"ABC==:numberOfSections");
return self.dataSourceArray.count;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
// ZNSLLog(@"ABC==:numberOfItems");
NSArray *sectionArray = self.dataSourceArray[section];
return sectionArray.count;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// ZNSLLog(@"ABC==:cellForItemAtIndexPath:%ld,%ld",indexPath.section,(long)indexPath.row);
OCFTFreeCombinationCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIndentifier forIndexPath:indexPath];
NSArray *sectionArray = self.dataSourceArray[indexPath.section];
OCFTFreeCombinationDataModel *model = sectionArray[indexPath.row];
cell.model = model;
return cell;
}
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath )sourceIndexPath toIndexPath:(NSIndexPath)destinationIndexPath {
// ZNSLLog(@"ABC==:moveItemAtIndexPath,此回调方法不能删");
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:@"ABC==:moveItemAtIndexPath,此回调方法不能删"];
}
- (void)handleDatasourceExchangeWithSourceIndexPath:(NSIndexPath *)sourceIndexPath destinationIndexPath:(NSIndexPath *)destinationIndexPath withArray:(NSArray *)array
{
NSMutableArray *tempArray = [NSMutableArray arrayWithArray:array];
NSInteger activeRange = destinationIndexPath.item - sourceIndexPath.item;
BOOL moveForward = activeRange > 0;
NSInteger originIndex = 0;
NSInteger targetIndex = 0;
for (NSInteger i = 1; i <= labs(activeRange); i ++) {//移动元素
NSInteger moveDirection = moveForward ? 1 : -1;
originIndex = sourceIndexPath.item + i * moveDirection;
targetIndex = originIndex - 1 * moveDirection;
OCFTFreeCombinationDataModel *originModel = tempArray[originIndex];
OCFTFreeCombinationDataModel *targetModel = tempArray[targetIndex];
if (0 == originIndex) {//头部
if ((tempArray.count - 1) == targetIndex){//尾部
originModel.excuteRoleShow = NO;
targetModel.excuteRoleShow = YES;
}else{//中间
originModel.excuteRoleShow = NO;
targetModel.excuteRoleShow = YES;
}
}else if ((tempArray.count - 1) == originIndex){//尾部
if (0 == targetIndex){//头部
originModel.excuteRoleShow = YES;
targetModel.excuteRoleShow = NO;
}else{//中间
}
}else{//中间
if (0 == targetIndex) {//头部
originModel.excuteRoleShow = YES;
targetModel.excuteRoleShow = NO;
}else if ((tempArray.count - 1) == targetIndex){//尾部
}else{//中间
}
}
[tempArray exchangeObjectAtIndex:originIndex withObjectAtIndex:targetIndex];
}
[self.dataMutableArray replaceObjectAtIndex:destinationIndexPath.section withObject:[tempArray copy]];
}
- (NSString *)objArraToJSON:(NSArray *)array {
NSString *jsonStr = @"";
for (NSInteger i = 0; i < array.count; i ++) {
NSArray *tempArray = array[i];
if (0 == tempArray.count) {
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:[NSString stringWithFormat:@"ABC==第%ld组:空",(i + 1)]];
}else{
for (NSInteger j = 0; j <tempArray.count ; j ++) {
OCFTFreeCombinationDataModel *model = tempArray[j];
if (0 == j) {
jsonStr = [jsonStr stringByAppendingString:model.name];
}else{
jsonStr = [jsonStr stringByAppendingString:[NSString stringWithFormat:@",%@",model.name]];
}
}
ZNSLLog(@"ABC==第%ld组:%@",(i + 1),jsonStr);
[ZNSLLogTool logWithLevel:ZNSLLocalLogLevelInfo type:ZNSLLocalLogType_AUDIO_VIDEO content:[NSString stringWithFormat:@"ABC==第%ld组:%@",(i + 1),jsonStr]];
jsonStr = @"";
}
}
return jsonStr;
}
#pragma mark - UICollectionViewDelegate
//拖动时固定Cell不被挤压
- (NSIndexPath *)collectionView:(UICollectionView *)collectionView targetIndexPathForMoveFromItemAtIndexPath:(NSIndexPath *)originalIndexPath toProposedIndexPath:(NSIndexPath *)proposedIndexPath {
// ZNSLLog(@"ABC==:targetIndexPathForMoveFromItemAtIndexPath");
return originalIndexPath;
}
#pragma mark - UICollectionViewDelegateFlowLayout
//定义每个Item的大小
- (CGSize)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGFloat itemWidth = ([UIScreen mainScreen].bounds.size.width - 32 - 7)/3.f;
if (itemWidth < OCFTItemWidth) {
return CGSizeMake(itemWidth, 44.f);
}else{
return CGSizeMake(115.f, 44.f);
}
}
//通过调整inset使单元格顶部和底部都有间距(inset次序: 上,左,下,右边)
- (UIEdgeInsets)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
NSArray *array = self.dataSourceArray[section];
if (0 == array.count) {
return UIEdgeInsetsZero;
}else{
return UIEdgeInsetsMake(8, 7, 8, 0);
}
}
//设置单元格间的横向间距
- (CGFloat)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 0.f;
}
//设置纵向的行间距
- (CGFloat)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 0.f;
}
#pragma mark - OCFTUICollectionViewDelegateLeftAlignedFlowLayout
- (UIColor *)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout backgroundColorForSection:(NSInteger)section {
return [UIColor whiteColor];
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout cornerRadiusForSection:(NSInteger)section {
return 4.f;
}
- (UIColor *)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout shadowColorForSection:(NSInteger)section {
return [UIColor colorWithRed:0.f green:0.f blue:0.f alpha:0.15f];
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout shadowRadiusForSection:(NSInteger)section {
return 4.36;
}
#pragma mark - getter and setter
- (UICollectionView *)freeCollectionView {
if (!_freeCollectionView) {
OCFTUICollectionViewLeftAlignedFlowLayout *leftAlignedLayout = [[OCFTUICollectionViewLeftAlignedFlowLayout alloc]init];
_freeCollectionView = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:leftAlignedLayout];
_freeCollectionView.dataSource = self;
_freeCollectionView.backgroundColor = UIColorFromHex(0xFAFAFA);
_freeCollectionView.layer.masksToBounds = YES;
_freeCollectionView.layer.cornerRadius = 4.f;
_freeCollectionView.delegate = self;
[_freeCollectionView registerClass:[OCFTFreeCombinationCollectionViewCell class] forCellWithReuseIdentifier:cellIndentifier];
}
return _freeCollectionView;
}
@end