在項目中需要實現用戶對可顯示分類的自由配置(添加、刪除、排序),不是對分類的編輯添加,而是在總分類中選擇顯示。只是做一下筆記,積累知識。
爲了實現分類的拖動排序,嘗試了多種插件,
在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