iOS 컨트롤 UICollection View 를 사용 하여 드래그 가능 한 데스크 톱 의 인 스 턴 스 를 생 성 합 니 다.
16818 단어 uicollectionview
우선 이 데모 의 효과 도 를 보 여 드 리 겠 습 니 다.
iOS 장 치 는 현재 화면 녹화 가 가능 한 앱 이 있 는 지 모 르 겠 습 니 다.그러면 제 가 조작 하 는 동작 을 gif 이미지 po 에 올 릴 수 있 습 니 다.여러분 이 추천 하 시 면 알려 주세요!드래그 에 대해 서 는 그림 을 길 게 누 르 면 원 하 는 위치 로 그림 을 끌 어 올 릴 수 있 고,다른 그림 은 순서대로 정렬 되 어 원활 한 체험 을 할 수 있 습 니 다.
UICollection View 를 사용 할 때,우리 클래스 는 이러한 프로 토 콜 을 실현 해 야 합 니 다:UICollection View DataSource,UICollection View Delegate FlowLayout,
UICollectionViewDelegate,UIGestureRecognizerDelegate。
UICollection View DataSource:우리 가 UITableView 에서 실현 해 야 할 UITableView DataSource 와 같은 이치 입 니 다.이 API 에는 다음 과 같은 API 가 포함 되 어 있 습 니 다.
@protocol UICollectionViewDataSource <NSObject>
@required
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section;
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
@optional
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView;
// The view that is returned must be retrieved from a call to -dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath NS_AVAILABLE_IOS(9_0);
@end
UICollection View Delegate FlowLayout:UICollection View FlowLayout 는 collection View 레이아웃 을 관리 하 는 클래스 로 다음 과 같은 함 수 를 실현 하여 우리 인터페이스의 스타일 을 조정 할 수 있 습 니 다.
@protocol UICollectionViewDelegateFlowLayout <UICollectionViewDelegate>
@optional
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section;
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section;
@end
UICollection ViewDelegate:UITable ViewDelegate 와 마찬가지 로 프로 토 콜 에 있 는 함수 po 를 꺼 냅 니 다.안에 있 는 함 수 를 다시 쓰 면 cell 의 클릭 과 드래그 를 실현 할 수 있 습 니 다.UIGesture Recognizer Delegate:드래그 기능 이 하나 더 있 기 때문에 사용자 제스처 프로 토 콜 이 필요 합 니 다.
자,기본 적 인 개념 을 말 했 으 니 이제 우리 가 그 를 실현 하기 시작 합 시다!그대로 원본 코드 보기:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//
[self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"back.jpg"]]];
//
self.dataSource = [[NSMutableArray alloc] initWithObjects:
@"1.png",@"2.png",@"3.png", @"4.png", @"5.png", @"6.png", @"7.png", @"8.png", @"9.png", @"10.png", @"11.jpg", @"12.JPG",
@"13.JPG", @"14.jpg", @"15.JPG", @"16.png", @"17.png", @"18.png", @"19.png", @"20.png", nil nil];
//
self.flow = [[UICollectionViewFlowLayout alloc] init];
self.collect = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:self.flow];
[self.collect setBackgroundColor:[UIColor clearColor]];
// cell
[self.collect registerClass:[CustomCollectionCell class] forCellWithReuseIdentifier:@"CustomCell"];
self.collect.delegate = self;
self.collect.dataSource = self;
[self.collect setFrame:self.view.bounds];
//
self.longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] init];
[self.longPressGestureRecognizer addTarget:self action:@selector(handleLongPressRecognizer:)];
[self.collect addGestureRecognizer:self.longPressGestureRecognizer];
[self.view addSubview:self.collect];
}
view DidLoad 함수 에서 UICollection View FlowLayout 레이아웃 을 초기 화 하 였 으 며,UICollection View 에 맞 춰 사용 해 야 합 니 다.둘 을 합 쳐 사용 해 야'완벽'합 니 다.UITableView 에서 Cell 을 사용 하 는 것 보다 다 르 게 하려 면 UICollection View 에서 Cell 을 먼저 등록 해 야 합 니 다(RegisterClass).그렇지 않 으 면 실행 중 에 오 류 를 보고 할 수 있 습 니 다.어떻게 배열 한 그림 을 끌 수 있 습 니까?여기 서 저 는 UICollection View 에 긴 제스처 UILongPress Gesture Recognizer 를 추 가 했 습 니 다.우리 가 시간 에 맞 춰 handle LongPress Recognizer 를 실행 할 때 코드 는 다음 과 같 습 니 다.
- (void)handleLongPressRecognizer:(UILongPressGestureRecognizer *)gesture{
switch (gesture.state) {
case UIGestureRecognizerStateBegan:{
NSIndexPath *path = [self.collect indexPathForItemAtPoint:[gesture locationInView:gesture.view]];
if(path == nil){
break;
}
[self.collect beginInteractiveMovementForItemAtIndexPath:path];
}
break;
case UIGestureRecognizerStateChanged:
[self.collect updateInteractiveMovementTargetPosition:[gesture locationInView:gesture.view]];
break;
case UIGestureRecognizerStateEnded:
[self.collect endInteractiveMovement];
break;
default:
[self.collect cancelInteractiveMovement];
break;
}
}
예 쁜 화면 이 있어 야 사용자 의 마음 을 사로 잡 을 수 있 습 니 다.여기 서 셀 은 UICollection ViewCell 에서 계승 한 그림 을 사용자 정의 하 였 습 니 다.cell 에서 보 여 준 그림 은 자신의 그림 크기 에 따라 비례 하여 크기 를 조정 합 니 다.그러면 우리 의 데스크 톱 은 가로 그림 과 세로 그림 이 있 을 것 입 니 다.사용자 정의 하지 않 으 면 모두 반듯 한 구 궁 격 입 니 다.디 스 플레이 효 과 를 사용자 정의 하 는 데 신경 을 쓰 세 요!CustomCollection Cell 의 코드 는 다음 과 같 습 니 다.
#import "CustomCollectionCell.h"
@implementation CustomCollectionCell
@synthesize imageV = _imageV;
@synthesize labelV = _labelV;
@synthesize boundView = _boundView;
- (id)initWithFrame:(CGRect) frame{
self = [super initWithFrame:frame];
//init attributes
if(self){
[self setBackgroundColor:[UIColor clearColor]];
self.imageV = [[UIImageView alloc] initWithFrame:CGRectZero];
self.labelV = [[UILabel alloc] initWithFrame:CGRectZero];
self.boundView = [[UIView alloc] initWithFrame:CGRectZero];
[self.boundView setBackgroundColor:[UIColor whiteColor]];
[self.boundView addSubview:self.imageV];
[self addSubview:self.boundView];
[self addSubview:self.labelV];
}
return self;
}
- (void)setImageWithText:(UIImage *)image text:(NSString *)text{
if(!image){
return;
}
CGFloat imgWidth = image.size.width;
CGFloat imgHeight = image.size.height;
CGFloat iconWidth = 0.0;
CGFloat iconHeight = 0.0;
if(imgWidth > imgHeight){
iconHeight = roundf(((self.frame.size.width - 16)*imgHeight)/imgWidth);
iconWidth = self.frame.size.width - 16;
[self.boundView setFrame:CGRectMake(0, self.frame.size.height - iconHeight - 16, iconWidth + 16, iconHeight + 16)];
[self.imageV setFrame:CGRectMake(8, 8, iconWidth, iconHeight)];
}else{
iconWidth = roundf(((self.frame.size.width - 16) *imgWidth)/imgHeight);
iconHeight = self.frame.size.height - 16;
[self.boundView setFrame:CGRectMake(roundf((self.frame.size.width - iconWidth)/2), 0, iconWidth + 16, iconHeight + 16)];
[self.imageV setFrame:CGRectMake(8, 8, iconWidth, iconHeight)];
}
[self.imageV setImage:image];
}
@end
이상 은 바로 이 Demo 를 구성 하 는 중요 한 구성 부분 입 니 다.UICollection View 는 아직도 많은 요소 들 이 여기 서 언급 되 지 않 았 습 니 다.앞으로 저 는 이 컨트롤 을 더욱 고 급 스 럽 게 사용 할 것 입 니 다.이 편 은 마치 식사 전의 애 피타 이 저 와 같 습 니 다.여러분 들 이 좋아 하 시 기 를 바 랍 니 다.이 예 의 원본 코드 를 첨부 합 니 다.
@implementation ViewController
@synthesize dataSource = _dataSource;
@synthesize longPressGestureRecognizer = _longPressGestureRecognizer;
@synthesize flow = _flow;
@synthesize collect = _collect;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//
[self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"back.jpg"]]];
//
self.dataSource = [[NSMutableArray alloc] initWithObjects:
@"1.png",@"2.png",@"3.png", @"4.png", @"5.png", @"6.png", @"7.png", @"8.png", @"9.png", @"10.png", @"11.jpg", @"12.JPG",
@"13.JPG", @"14.jpg", @"15.JPG", @"16.png", @"17.png", @"18.png", @"19.png", @"20.png", nil nil];
//
self.flow = [[UICollectionViewFlowLayout alloc] init];
self.collect = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:self.flow];
[self.collect setBackgroundColor:[UIColor clearColor]];
// cell
[self.collect registerClass:[CustomCollectionCell class] forCellWithReuseIdentifier:@"CustomCell"];
self.collect.delegate = self;
self.collect.dataSource = self;
[self.collect setFrame:self.view.bounds];
//
self.longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] init];
[self.longPressGestureRecognizer addTarget:self action:@selector(handleLongPressRecognizer:)];
[self.collect addGestureRecognizer:self.longPressGestureRecognizer];
[self.view addSubview:self.collect];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)handleLongPressRecognizer:(UILongPressGestureRecognizer *)gesture{
switch (gesture.state) {
case UIGestureRecognizerStateBegan:{
NSIndexPath *path = [self.collect indexPathForItemAtPoint:[gesture locationInView:gesture.view]];
if(path == nil){
break;
}
[self.collect beginInteractiveMovementForItemAtIndexPath:path];
}
break;
case UIGestureRecognizerStateChanged:
[self.collect updateInteractiveMovementTargetPosition:[gesture locationInView:gesture.view]];
break;
case UIGestureRecognizerStateEnded:
[self.collect endInteractiveMovement];
break;
default:
[self.collect cancelInteractiveMovement];
break;
}
}
#pragma mark UICollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return self.dataSource.count;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CustomCollectionCell * cell = (CustomCollectionCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"CustomCell" forIndexPath:indexPath];
UIImage *image = [UIImage imageNamed:[self.dataSource objectAtIndex:indexPath.row]];
[cell setImageWithText:image text:@""];
return cell;
}
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath{
id item = [self.dataSource objectAtIndex:sourceIndexPath.item];
[self.dataSource removeObject:item];
[self.dataSource insertObject:item atIndex:destinationIndexPath.item];
}
#pragma mark UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
TestViewController *test = [[TestViewController alloc] initWithNibName:@"TestViewController" bundle:nil];
NSString *imageName = [self.dataSource objectAtIndex:indexPath.row];
test.imageName = imageName;
[self.navigationController pushViewController:test animated:YES];
}
- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
//
- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath{
// CustomCollectionCell * cell = (CustomCollectionCell *)[collectionView cellForItemAtIndexPath:indexPath];
//
// [UIView animateWithDuration:1 animations:^{
// cell.transform = CGAffineTransformMakeScale(2.0f, 2.0f);
// }];
}
//
- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath{
// CustomCollectionCell * cell = (CustomCollectionCell *)[collectionView cellForItemAtIndexPath:indexPath];
//
// [UIView animateWithDuration:1 animations:^{
// cell.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
// }];
}
#pragma mark UICollectionViewDelegateFlowLayout
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake(100, 100);
}
/*
*
*/
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(15, 15, 15, 15);
}
/*
* item space
*/
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
return 8;
}
/*
* 20
*/
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{
return 10;
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.