#import <UIKit/UIKit.h> @interface DragViewController : UICollectionViewController @end #import "DragViewController.h" #import "DragLayout.h" @implementation DragViewController - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return 70; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { return [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath]; } //對不一樣手勢處理 - (IBAction)handleLongPress:(UIGestureRecognizer *)g { DragLayout *dragLayout = (DragLayout *)self.collectionViewLayout; CGPoint location = [g locationInView:self.collectionView]; // Find the indexPath and cell being dragged NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:location]; UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath]; UIGestureRecognizerState state = g.state; if (state == UIGestureRecognizerStateBegan) { // Change the color and start dragging 開始拖曳動做 [UIView animateWithDuration:0.25 animations:^{ // cell.backgroundColor = [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1]; cell.layer.cornerRadius =10; }]; [dragLayout startDraggingIndexPath:indexPath fromPoint:location];//傳入所點擊項目 } //手勢釋放時 else if (state == UIGestureRecognizerStateEnded || state == UIGestureRecognizerStateCancelled) { // Change the color and stop dragging [UIView animateWithDuration:0.25 animations:^{ cell.backgroundColor = [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1]; }]; //無手勢處理 [dragLayout stopDragging]; } else { // Drag 拖曳必定距離 [dragLayout updateDragLocation:location]; } } @end
#import <UIKit/UIKit.h> @interface DragLayout : UICollectionViewFlowLayout - (void)startDraggingIndexPath:(NSIndexPath *)indexPath fromPoint:(CGPoint)p; - (void)updateDragLocation:(CGPoint)point; - (void)stopDragging; @end #import "DragLayout.h" @interface DragLayout () @property (nonatomic) NSIndexPath *indexPath; @property (nonatomic) UIDynamicAnimator *animator; @property (nonatomic) UIAttachmentBehavior *behavior; @end @implementation DragLayout //開始拖曳 添加動力學效果 修改The anchor point for the attachment behavior - (void)startDraggingIndexPath:(NSIndexPath *)indexPath fromPoint:(CGPoint)p { self.indexPath = indexPath; self.animator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self]; UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForItemAtIndexPath:self.indexPath]; // Raise the item above its peers 把該項目提到其餘項目之上 attributes.zIndex += 1; self.behavior = [[UIAttachmentBehavior alloc] initWithItem:attributes attachedToAnchor:p]; self.behavior.length = 0; self.behavior.frequency = 10;//晃動頻率 [self.animator addBehavior:self.behavior]; // Add a little resistance to keep things stable UIDynamicItemBehavior *dynamicItem = [[UIDynamicItemBehavior alloc] initWithItems:@[attributes]]; dynamicItem.resistance = 10; [self.animator addBehavior:dynamicItem]; [self updateDragLocation:p]; } - (void)updateDragLocation:(CGPoint)p { self.behavior.anchorPoint = p; } //手勢中止 - (void)stopDragging { // Move back to the original location (super) 回到原始位置 UICollectionViewLayoutAttributes * attributes = [super layoutAttributesForItemAtIndexPath:self.indexPath];//所點擊indexPath center [self updateDragLocation:attributes.center]; self.indexPath = nil; self.behavior = nil; } //返回rect中的全部的元素的佈局屬性 - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { // Find all the attributes, and replace the one for our indexPath 找到全部屬性,並替換indexPath中的 NSArray *existingAttributes = [super layoutAttributesForElementsInRect:rect]; NSMutableArray *allAttributes = [NSMutableArray new]; for (UICollectionViewLayoutAttributes *a in existingAttributes) { if (![a.indexPath isEqual:self.indexPath]) { [allAttributes addObject:a]; } } [allAttributes addObjectsFromArray:[self.animator itemsInRect:rect]]; return allAttributes; } @end