仿网易新闻栏目选择页面的基本效果,今天抽了点时间教大家如何实现UICollectionView拖动的效果!

其实实现起来并不复杂,这里只是基本的功能,没有实现细节上的修改,连UI都是丑丑的样子,随手画的。

相信大家都使用过网易新闻客户端,里面的效果确定被不少人模仿,很多同类型的app都采用了人家的UI样式,那么今天就教大家如何去实现。

效果图

这是简略的效果图,样子是有点丑,将就看看吧:

实现原理

给UICollectionView添加一个手势或者其他方式,在长按时手动触发拖动开始,在移动过程中又要不断手动地更新位置,而在完成时手动触发完成操作,在取消时也要手动触发取消移动操作。

而要实现移动,必须设置是否可移动。比如我们的demo中第一个分区是要求移动的,而第二个分区是不允许移动的,因此我们需要通过代理来设置是否可移动。

在移动完成时,会有代理回调,此时我们要做的就是交换数据源来更新。

移动API介绍

首先我们必须要明确,这几个API是在iOS9之后才能使用的。这几个API来配合起来使用,才能最终达到我们期望的效果。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
 
// 开始
- (BOOL)beginInteractiveMovementForItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);
 
// 更新位置
- (void)updateInteractiveMovementTargetPosition:(CGPoint)targetPosition NS_AVAILABLE_IOS(9_0);
 
// 完成
- (void)endInteractiveMovement NS_AVAILABLE_IOS(9_0);
 
// 取消
- (void)cancelInteractiveMovement NS_AVAILABLE_IOS(9_0);
 

这四个API组合起来才是完整的动作。

添加长按手势

我们需要将手势放到CollectionView上,因为我们要的是操作全范围的!

 
1
2
3
4
5
6
 
self.collectionView.pagingEnabled = NO;
    
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongPressed:)];
[self.collectionView addGestureRecognizer:longPress];
 

处理手势

这个基本是固定的,大家可以copy一下我的代码过去用就可以了:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
- (void)onLongPressed:(UILongPressGestureRecognizer *)sender {
  CGPoint point = [sender locationInView:sender.view];
  NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:point];
  
  // 只允许第一区可移动
  if (indexPath.section != 0) {
    return;
  }
  
  switch (sender.state) {
    case UIGestureRecognizerStateBegan: {
      if (indexPath) {
        [self.collectionView beginInteractiveMovementForItemAtIndexPath:indexPath];
      }
      break;
    }
    case UIGestureRecognizerStateChanged: {
        [self.collectionView updateInteractiveMovementTargetPosition:point];
      break;
    }
    case UIGestureRecognizerStateEnded: {
      [self.collectionView endInteractiveMovement];
      break;
    }
    default: {
      [self.collectionView cancelInteractiveMovement];
      break;
    }
  }
}
 

是否允许移动

这里是只有在编辑状态下且第一分区才能拖动重排,所以通过添加条件来控制是否可移动:

 
1
2
3
4
5
6
7
8
9
 
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath {
  if (self.isEditing && indexPath.section == 0) {
    return YES;
  }
  
  return NO;
}
 

完成移动更新源

我们只有第一分区可以操作,而这里只有一个数组,所以直接交换一下数据源就OK了:

 
1
2
3
4
5
6
7
 
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
  if (sourceIndexPath.section == 0 && destinationIndexPath.section == 0) {
    [self.firstList exchangeObjectAtIndex:sourceIndexPath.item withObjectAtIndex:destinationIndexPath.item];
  }
}
 

添加删除移动效果

在点击第一分区时或者第二分区的cell时,会自动移动到第二分区或者第一分区。我们希望有移动的动画效果的话,就需要通过collectionview提供的API来完成,而编辑状态下有删除按钮,而到二分区时就不能显示,而在一分区在编辑状态下又可以显示:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 
#pragma mark - UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
  if (indexPath.section == 0) {
    if (self.isEditing) {
      TestModel *model = [self.secondList hyb_objectAtIndex:indexPath.item];
      [self.firstList addObject:model];
      [self.secondList removeObject:model];
      
      NSInteger index = self.firstList.count - 1;
      if (self.firstList.count == 0) {
        index = 0;
      }
      
      TestColumnCell *cell = (TestColumnCell *)[collectionView cellForItemAtIndexPath:indexPath];
      cell.isEditing = NO;
      [collectionView moveItemAtIndexPath:indexPath toIndexPath:[NSIndexPath indexPathForItem:index inSection:1]];
      [self saveColumns];
    } else {
      // 选择某一个
    }
  } else {
    TestModel *model = [self.firstList hyb_objectAtIndex:indexPath.item];
    [self.secondList addObject:model];
    [self.firstList removeObject:model];
    
    NSInteger index = self.secondList.count - 1;
    if (self.secondList.count == 0) {
      index = 0;
    }
 
    if (self.isEditing) {
      TestColumnCell *cell = (TestColumnCell *)[collectionView cellForItemAtIndexPath:indexPath];
      cell.isEditing = YES;
    }
    
    [collectionView moveItemAtIndexPath:indexPath toIndexPath:[NSIndexPath indexPathForItem:index inSection:0]];
    [self saveColumns];
  }
  
  [collectionView reloadData];
}

iOS仿网易新闻栏目拖动重排添加删除效果的更多相关文章

  1. iOS界面-仿网易新闻左侧抽屉式交互 续(添加新闻内容页和评论页手势)

     本文转载至  http://blog.csdn.net/totogo2010/article/details/8637430       1.介绍 有的博友看了上篇博文iOS界面-仿网易新闻左侧抽屉 ...

  2. 仿网易新闻app下拉标签选择菜单

    仿网易新闻app下拉标签选择菜单 仿网易新闻app下拉标签选择菜单,长按拖动排序,点击增删标签控件 ##示例  ##EasyTagDragView的使用 在layout布局里添加:  

  3. Android 开源框架ActionBarSherlock 和 ViewPager 仿网易新闻客户端

    转载请注明出处:http://blog.csdn.net/xiaanming/article/details/9971721 大家都知道Android的ActionBar是在3.0以上才有的,那么在3 ...

  4. Android Studio精彩案例(一)《ActionBar和 ViewPager版仿网易新闻客户端》

    转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 为了能更好的分享高质量的文章,所以开设了此专栏.文章代码都以Android Studio亲测运行,读者朋友可在后面直接下载源码.该专栏 ...

  5. 类似掌盟的Tab页 Android 开源框架ViewPageIndicator 和 ViewPager 仿网易新闻客户端Tab标签 (转)

    原博客地址  :http://blog.csdn.net/xiaanming/article/details/10766053 本文转载,记录学习用,如有需要,请到原作者网站查看(上面这个网址) 之前 ...

  6. Android应用经典主界面框架之二:仿网易新闻client、CSDN client (Fragment ViewPager)

    另外一种主界面风格则是以网易新闻.凤凰新闻以及新推出的新浪博客(阅读版)为代表.使用ViewPager+Fragment,即ViewPager里适配器里放的不是一般的View.而是Fragment.所 ...

  7. Android 开源框架ViewPageIndicator 和 ViewPager 仿网易新闻clientTab标签

    之前用JakeWharton的开源框架ActionBarSherlock和ViewPager实现了对网易新闻clientTab标签的功能,ActionBarSherlock是在3.0下面的机器支持Ac ...

  8. Android 开源框架ViewPageIndicator 和 ViewPager 仿网易新闻客户端Tab标签

    转载请注明出处:http://blog.csdn.net/xiaanming/article/details/10766053 之前用JakeWharton的开源框架ActionBarSherlock ...

  9. iOS动画案例(2) 仿网易新闻标题动画

      由于产品的需要,做了一个和网易新闻标题类似的动画效果,现在新闻类的APP都是采用这样的动画效果,来显示更多的内容.先看一下动画效果:   由于这个动画效果在很多场合都有应用,所以我专门封装了一个控 ...

随机推荐

  1. storm安装笔记以及提交拓扑任务

    Storm -- Distributed and fault-tolerant realtime computation 这是一个分布式的.容错的实时计算系统 把Storm依赖组件的版本贴出来供各位参 ...

  2. python 代码片段24

    #coding=utf-8 #内部类 class MyClass(object): class InnerClass: pass # 正则表达式 # 通过re模块来访问 import re m=re. ...

  3. 编写unit test以及自动化测试WebDriver

    http://msdn.microsoft.com/en-us/library/hh694602.aspx#BKMK_Quick_starts   http://www.seleniumhq.org/ ...

  4. 一些有用的HTML5 pattern属性

    最近在做手机页面时,遇到数字输入的键盘的问题,之前的做法只是一刀切的使用 type="tel",不过一直觉得九宫格的电话号码键盘上的英文字母太碍事了.于是想要尝试其它的实现方案,最 ...

  5. ACM 关于521

    关于521 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述 Acm队的流年对数学的研究不是很透彻,但是固执的他还是想一头扎进去. 浏览网页的流年忽然看到了网上有人用玫 ...

  6. Codeforces Round #210 (Div. 2) A. Levko and Table

    让对角线的元素为k就行 #include <iostream> using namespace std; int main() { int n,k; cin >> n > ...

  7. 【POJ】3744 Scout YYF I

    http://poj.org/problem?id=3744 题意:直线上n个地雷,n<=10,范围在[1, 100000000],每一次有p的概率向前走一步,1-p的概率向前走两步,问安全通过 ...

  8. 【BZOJ1051】1051: [HAOI2006]受欢迎的牛 tarjan求强连通分量+缩点

    Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认 ...

  9. hdu1240 bfs 水题

    原题链接 思路:水题,直接搜 #include "map" #include "queue" #include "math.h" #incl ...

  10. [LintCode] Binary Tree Paths 二叉树路径

    Given a binary tree, return all root-to-leaf paths.Example Given the following binary tree: 1 /   \2 ...