在项目中需要实现用户对可显示分类的自由配置(添加、删除、排序),不是对分类的编辑添加,而是在总分类中选择显示。只是做一下笔记,积累知识。
为了实现分类的拖动排序,尝试了多种插件,
在https://github.com/lxcid/LXReorderableCollectionViewFlowLayout
插件的基础上修改使用实现效果。
.h代码
#import <UIKit/UIKit.h>
#import "LXReorderableCollectionViewFlowLayout.h"
@interface SetViewController : UIViewController< LXReorderableCollectionViewDataSource,LXReorderableCollectionViewDelegateFlowLayout>
@property (strong, nonatomic) UICollectionView *selectedview;
@property (strong, nonatomic) UICollectionView *no1selectedview;
@property (strong, nonatomic) UICollectionView *no2selectedview;
@property (strong, nonatomic) IBOutlet UILabel *firstLabel;
@property (strong, nonatomic) UILabel *secondLabel;
@property (strong, nonatomic) UISegmentedControl *selectApp;
@property (strong, nonatomic) NSMutableArray *deck;
@property(nonatomic,strong) NSMutableArray *selectedcategory;
@property(nonatomic,strong) NSMutableArray *selected1category;
@property(nonatomic,strong) NSMutableArray *no1category;
@property(nonatomic,strong) NSMutableArray *selected2category;
@property(nonatomic,strong) NSMutableArray *no2category;
@end
使用了三个UICollectionView实现(上部分选中的selectedview,下部分Ano1selectedview,Bno2selectedview)
-(void)initCollectionView{
CGRect r = [[UIScreen mainScreen] applicationFrame];
int n=r.size.width/100;
int m=ceilf((float)(self.deck.count+1)/n) ;
LXReorderableCollectionViewFlowLayout *layout=[[LXReorderableCollectionViewFlowLayout alloc]init];
self.selectedview=[[UICollectionView alloc]initWithFrame:CGRectMake(2, self.firstLabel.frame.origin.y+25, r.size.width-4, m*50) collectionViewLayout:layout];
[self.selectedview registerClass:[SelectedCollectionViewCell class] forCellWithReuseIdentifier:kCellID];
self.selectedview.backgroundColor=[UIColor whiteColor];
self.selectedview.delegate=self;
self.selectedview.dataSource=self;
self.selectedview.tag=10001;
self.selectedview.alwaysBounceVertical=YES;
[self.view addSubview:self.selectedview];
}
-(void)initNoSelectionCollectionView{
CGRect r = [[UIScreen mainScreen] applicationFrame];
NSInteger hight=r.size.height-self.selectApp.frame.origin.y-45;
LXReorderableCollectionViewFlowLayout *layout=[[LXReorderableCollectionViewFlowLayout alloc]init];
self.no1selectedview=[[UICollectionView alloc]initWithFrame:CGRectMake(2, self.selectApp.frame.origin.y+45, r.size.width-4, hight) collectionViewLayout:layout];
[self.no1selectedview registerClass:[SelectedCollectionViewCell class] forCellWithReuseIdentifier:@"no1selectedviewcell"];
self.no1selectedview.backgroundColor=[UIColor whiteColor];
self.no1selectedview.delegate=self;
self.no1selectedview.dataSource=self;
self.no1selectedview.tag=10002;
self.no1selectedview.alwaysBounceVertical=YES;
[self.view addSubview:self.no1selectedview];
LXReorderableCollectionViewFlowLayout *layout2=[[LXReorderableCollectionViewFlowLayout alloc]init];
self.no2selectedview=[[UICollectionView alloc]initWithFrame:CGRectMake(2, self.selectApp.frame.origin.y+45, r.size.width-4,hight) collectionViewLayout:layout2];
[self.no2selectedview registerClass:[SelectedCollectionViewCell class] forCellWithReuseIdentifier:@"no2selectedviewcell"];
self.no2selectedview.backgroundColor=[UIColor whiteColor];
self.no2selectedview.delegate=self;
self.no2selectedview.dataSource=self;
self.no2selectedview.tag=10003;
self.no2selectedview.hidden=YES;
self.no2selectedview.alwaysBounceVertical=YES;
[self.view addSubview:self.no2selectedview];
}
使用@property (strong, nonatomic) NSMutableArray *deck;
存储已选择的分类
从本地存储中获取所有分类,已选择分类,去重获得未选择分类。
- (NSMutableArray *)constructsDeck {
//缓存中的 用户配置的分类
NSUserDefaults *userDefaults=[NSUserDefaults standardUserDefaults];
NSString *access_token=[userDefaults stringForKey:@"access_token"];
if([access_token isEqualToString:@"0"]){
//未登录情况下 使用未登录的分类
self.selectedcategory =[[userDefaults arrayForKey:@"NotLoginUserCategory"] mutableCopy];
}else{
//读取本地缓存的已配置的分类
self.selectedcategory =[[userDefaults arrayForKey:@"UserCategory"] mutableCopy];
}
self.no1category =[[userDefaults arrayForKey:@"All1Category"] mutableCopy];
self.no2category =[[userDefaults arrayForKey:@"All2Category"] mutableCopy];
NSMutableArray *deleteCate=[NSMutableArray arrayWithCapacity:10];
for (NSDictionary *cates in self.selectedcategory) {
for (NSDictionary *no1 in self.no1category) {
if ([[no1 classId]integerValue]==[[cates classId]integerValue]) {
[deleteCate addObject:no1];
}
}
for (NSDictionary *no2 in self.no2category) {
if ([[no2 classId]integerValue]==[[cates classId]integerValue]) {
[deleteCate addObject:no2];
}
}
}
[self.no1category removeObjectsInArray:deleteCate];
[self.no2category removeObjectsInArray:deleteCate];
return self.selectedcategory;
}
需要实现LXReorderableCollectionViewFlowLayout中的必须实现的方法
#pragma mark - UICollectionViewDataSource methods
- (NSInteger)collectionView:(UICollectionView *)theCollectionView numberOfItemsInSection:(NSInteger)theSectionIndex {
NSInteger count=0;
if (theCollectionView.tag==10001) {
count=[self.deck count] +1;
//多了一个默认分类
}else if(theCollectionView.tag==10002){
count=[self.no1category count];
}else{
count=[self.no2category count];
}
return count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CGRect r = [[UIScreen mainScreen] applicationFrame];
SelectedCollectionViewCell *selectCell ;
if (collectionView.tag==10001) {
selectCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Selectedcell" forIndexPath:indexPath];
selectCell.nameLabel.frame=CGRectMake(1, 1, 88, 38);
[selectCell.nameLabel setTextAlignment:NSTextAlignmentCenter];
if (indexPath.item==0) {
selectCell.nameLabel.text=[NSString stringWithFormat:@"推荐"];
selectCell.nameLabel.tag=0;
selectCell.nameLabel.textColor=[UIColor lightGrayColor];
}else{
selectCell.nameLabel.text=[NSString stringWithFormat:@"%@",[self.deck[indexPath.item-1] classNames]];
selectCell.nameLabel.tag=[[self.deck[indexPath.item-1] classId]integerValue];
selectCell.nameLabel.textColor=[UIColor blackColor];
}
selectCell.nameLabel.numberOfLines=0;
selectCell.nameLabel.layer.borderColor=[[UIColor lightGrayColor]CGColor];
selectCell.nameLabel.layer.borderWidth=1;
selectCell.nameLabel.layer.cornerRadius=10;
selectCell.nameLabel.font=[UIFont fontWithName:@"Helvetica Neue" size:15];
//尝试过在这里直接addview一个uilabel,但是在删除或者拖动排序的时候会有多个label重叠。
}else if(collectionView.tag==10002){
selectCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"no1selectedviewcell" forIndexPath:indexPath];
selectCell.nameLabel.frame=CGRectMake(10, 0, r.size.width-50, 28);
selectCell.nameLabel.text=[NSString stringWithFormat:@"%@",[self.no1category[indexPath.item] classNames]];
selectCell.nameLabel.tag=[[self.no1category[indexPath.item] classId]integerValue];
selectCell.nameLabel.font=[UIFont fontWithName:@"Helvetica Neue" size:15];
selectCell.nameLabel.textColor=[UIColor grayColor];
UIImageView *add=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"add"]];
add.frame=CGRectMake(r.size.width-40, 5, 20, 20);
[selectCell addSubview:add];
UILabel *line=[[UILabel alloc]initWithFrame:CGRectMake(5, 30, r.size.width-10, 1)];
line.backgroundColor=[UIColor lightGrayColor];
[selectCell addSubview:line];
}else{
selectCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"no2selectedviewcell" forIndexPath:indexPath];
selectCell.nameLabel.frame=CGRectMake(10, 0, r.size.width-50, 28);
selectCell.nameLabel.text=[NSString stringWithFormat:@"%@",[self.no2category[indexPath.item] classNames]];
selectCell.nameLabel.tag=[[self.no2category[indexPath.item] classId]integerValue];
selectCell.nameLabel.font=[UIFont fontWithName:@"Helvetica Neue" size:15];
selectCell.nameLabel.textColor=[UIColor grayColor];
UIImageView *add=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"add"]];
add.frame=CGRectMake(r.size.width-40, 5, 20, 20);
[selectCell addSubview:add];
UILabel *line=[[UILabel alloc]initWithFrame:CGRectMake(5, 30, r.size.width-10, 1)];
line.backgroundColor=[UIColor lightGrayColor];
[selectCell addSubview:line];
}
return selectCell;
}
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
CGRect r = [[UIScreen mainScreen] applicationFrame];
CGSize size=CGSizeMake(90,40);
if (collectionView.tag!=10001) {
size=CGSizeMake(r.size.width, 30);
}
return size;
}
#pragma mark - LXReorderableCollectionViewDataSource methods
- (void)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath willMoveToIndexPath:(NSIndexPath *)toIndexPath {
NSMutableArray *temp=[self.deck mutableCopy];
[self.deck removeObjectAtIndex:fromIndexPath.item-1];
[self.deck insertObject:temp[fromIndexPath.item-1] atIndex:toIndexPath.item-1];
}
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath {
if (collectionView.tag!=10001) {
return NO;
}
if (indexPath.item==0) {
return NO;
}
return YES;
}
- (BOOL)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath canMoveToIndexPath:(NSIndexPath *)toIndexPath {
if (collectionView.tag!=10001) {
return NO;
}
if (toIndexPath.item==0) {
return NO;
}
return YES;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
if (collectionView.tag==10001) {
//点击删除
if(indexPath.item!=0){
if (self.deck.count<=1) {
[CommenData showMsgError:self.navigationController.view showMsg:@"请至少保留一个分类"];
}else{
NSDictionary *category=self.deck[indexPath.item-1];
[self.deck removeObjectAtIndex:indexPath.item-1];
[collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
if ([[category appId]integerValue]==1) {
//a
[self.no1category addObject:category];
[self.no1selectedview insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:[self.no1category count]-1 inSection:0]]];
}else{
//b
[self.no2category addObject:category];
[self.no2selectedview insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:[self.no2category count]-1 inSection:0]]];
}
}
}
}else if(collectionView.tag==10002){
//点击添加
NSDictionary *category=self.no1category[indexPath.item];
[self.deck addObject:category];
[self.selectedview insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:[self.deck count] inSection:0]]];
//a
[self.no1category removeObjectAtIndex:indexPath.item];
[self.no1selectedview deleteItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
}else{
//点击添加
NSDictionary *category=self.no2category[indexPath.item];
[self.deck addObject:category];
[self.selectedview insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:[self.deck count] inSection:0]]];
//b
[self.no2category removeObjectAtIndex:indexPath.item];
[self.no2selectedview deleteItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
}
[self updateFrame];
NSUserDefaults *userDefaults=[NSUserDefaults standardUserDefaults];
NSString *access_token=[userDefaults stringForKey:@"access_token"];
if([access_token isEqualToString:@"0"]){
//未登录情况下 使用未登录的分类
[userDefaults setObject:self.deck forKey:@"NotLoginUserCategory"];
}else{
[userDefaults setObject:self.deck forKey:@"UserCategory"];
}
[userDefaults setBool:TRUE forKey:@"updateSet"];
[userDefaults synchronize];
}
-(void)updateFrame{
CGRect r = [[UIScreen mainScreen] applicationFrame];
int n=r.size.width/100;
int m=ceilf((float)(self.deck.count+1)/n) ;
NSInteger fhight=r.size.height-self.firstLabel.frame.origin.y-25-m*50-80;
self.selectedview.frame=CGRectMake(2, self.firstLabel.frame.origin.y+25, r.size.width-4, m*50);
if(fhight<70){
//给未选择的分类留个高度
self.selectedview.frame=CGRectMake(2, self.firstLabel.frame.origin.y+25, r.size.width-4, r.size.height-self.firstLabel.frame.origin.y-25-150);
}
self.secondLabel.frame=CGRectMake(self.firstLabel.frame.origin.x, self.selectedview.frame.origin.y+self.selectedview.frame.size.height, 100, 27);
self.selectApp.frame=CGRectMake((r.size.width-288)/2, self.secondLabel.frame.origin.y+35, 288, 29);
NSInteger hight=r.size.height-self.selectApp.frame.origin.y-45;
self.no1selectedview.frame=CGRectMake(2, self.selectApp.frame.origin.y+45, r.size.width-4, hight);
self.no2selectedview.frame=CGRectMake(2, self.selectApp.frame.origin.y+45, r.size.width-4, hight);
}
#pragma mark - LXReorderableCollectionViewDelegateFlowLayout methods
- (void)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout willBeginDraggingItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"will begin drag");
}
- (void)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout didBeginDraggingItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"did begin drag");
}
- (void)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout willEndDraggingItemAtIndexPath:(NSIndexPath *)indexPath {
isUpdate=true;
NSLog(@"will end drag");
NSUserDefaults *userDefaults=[NSUserDefaults standardUserDefaults];
NSString *access_token=[userDefaults stringForKey:@"access_token"];
if([access_token isEqualToString:@"0"]){
//未登录情况下 使用未登录的分类
[userDefaults setObject:self.deck forKey:@"NotLoginUserCategory"];
}else{
[userDefaults setObject:self.deck forKey:@"UserCategory"];
}
[userDefaults setBool:TRUE forKey:@"updateSet"];
[userDefaults synchronize];
}
SelectedCollectionViewCell
#import <UIKit/UIKit.h>
@interface SelectedCollectionViewCell : UICollectionViewCell
@property (strong, nonatomic) UILabel *nameLabel;
@end
#import "SelectedCollectionViewCell.h"
@implementation SelectedCollectionViewCell
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, frame.size.width, frame.size.height)];
[self.contentView addSubview:self.nameLabel];
}
return self;
}
@end