iOS Swift UICollectionView横向分页滚动,cell左右排版问题详解

情况

Swift对于一门新的iOS编程语言,他的崛起是必然的,我们这群老程序员们学习新的技能也是必然的,不接受新技能将被这大群体无情的淘汰。

最近因为工作的需求,在做表情键盘时遇到一个问题,我用UICollectionView来布局表情,使用横向分页滚动,但在最后一页出现了如图所示的情况

情况分析图

是的,现在的item分布就是这个鬼样子

现在想要做的,就是将现在这个鬼样子变成另外一种样子,如图

那怎么办?只好重新布局item了

解决方案

我是自定了一个Layout(LXFChatEmotionCollectionLayout) ,让UICollectionView在创建的时候使用了它

在 LXFChatEmotionCollectionLayout.swift 中

添加一个属性来保存所有item的attributes

// 保存所有item的attributes
fileprivate var attributesArr: [UICollectionViewLayoutAttributes] = []

重新布局

// MARK:- 重新布局
override func prepare() {
 super.prepare()
 let itemWH: CGFloat = kScreenW / CGFloat(kEmotionCellNumberOfOneRow)
 // 设置itemSize
 itemSize = CGSize(width: itemWH, height: itemWH)
 minimumLineSpacing = 0
 minimumInteritemSpacing = 0
 scrollDirection = .horizontal
 // 设置collectionView属性
 collectionView?.isPagingEnabled = true
 collectionView?.showsHorizontalScrollIndicator = false
 collectionView?.showsVerticalScrollIndicator = true
 let insertMargin = (collectionView!.bounds.height - 3 * itemWH) * 0.5
 collectionView?.contentInset = UIEdgeInsetsMake(insertMargin, 0, insertMargin, 0)
 /// 重点在这里
 var page = 0
 let itemsCount = collectionView?.numberOfItems(inSection: 0) ?? 0
 for itemIndex in 0..<itemsCount {
  let indexPath = IndexPath(item: itemIndex, section: 0)
  let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
  page = itemIndex / (kEmotionCellNumberOfOneRow * kEmotionCellRow)
  // 通过一系列计算, 得到x, y值
  let x = itemSize.width * CGFloat(itemIndex % Int(kEmotionCellNumberOfOneRow)) + (CGFloat(page) * kScreenW)
  let y = itemSize.height * CGFloat((itemIndex - page * kEmotionCellRow * kEmotionCellNumberOfOneRow) / kEmotionCellNumberOfOneRow)
  attributes.frame = CGRect(x: x, y: y, width: itemSize.width, height: itemSize.height)
  // 把每一个新的属性保存起来
  attributesArr.append(attributes)
 }
}

返回所有当前可见的Attributes

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
 var rectAttributes: [UICollectionViewLayoutAttributes] = []
 _ = attributesArr.map({
  if rect.contains($0.frame) {
   rectAttributes.append($0)
  }
 })
 return rectAttributes
}

大功告成

完整代码

import UIKit
let kEmotionCellNumberOfOneRow = 8
let kEmotionCellRow = 3
class LXFChatEmotionCollectionLayout: UICollectionViewFlowLayout {
 // 保存所有item
 fileprivate var attributesArr: [UICollectionViewLayoutAttributes] = []
 // MARK:- 重新布局
 override func prepare() {
  super.prepare()
  let itemWH: CGFloat = kScreenW / CGFloat(kEmotionCellNumberOfOneRow)
  // 设置itemSize
  itemSize = CGSize(width: itemWH, height: itemWH)
  minimumLineSpacing = 0
  minimumInteritemSpacing = 0
  scrollDirection = .horizontal
  // 设置collectionView属性
  collectionView?.isPagingEnabled = true  collectionView?.showsHorizontalScrollIndicator = false
  collectionView?.showsVerticalScrollIndicator = true
  let insertMargin = (collectionView!.bounds.height - 3 * itemWH) * 0.5
  collectionView?.contentInset = UIEdgeInsetsMake(insertMargin, 0, insertMargin, 0)
  var page = 0
  let itemsCount = collectionView?.numberOfItems(inSection: 0) ?? 0
  for itemIndex in 0..<itemsCount {
   let indexPath = IndexPath(item: itemIndex, section: 0)
   let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
   page = itemIndex / (kEmotionCellNumberOfOneRow * kEmotionCellRow)
   // 通过一系列计算, 得到x, y值
   let x = itemSize.width * CGFloat(itemIndex % Int(kEmotionCellNumberOfOneRow)) + (CGFloat(page) * kScreenW)
   let y = itemSize.height * CGFloat((itemIndex - page * kEmotionCellRow * kEmotionCellNumberOfOneRow) / kEmotionCellNumberOfOneRow)
   attributes.frame = CGRect(x: x, y: y, width: itemSize.width, height: itemSize.height)
   // 把每一个新的属性保存起来
   attributesArr.append(attributes)
  }
 }
 override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
  var rectAttributes: [UICollectionViewLayoutAttributes] = []
  _ = attributesArr.map({
   if rect.contains($0.frame) {
    rectAttributes.append($0)
   }
  })
  return rectAttributes
 }
}

附上相关项目:Swift 3.0 高仿微信

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Swift下使用UICollectionView 实现长按拖拽功能

    导读 简单用Swift写了一个collectionview的拖拽点击排序效果; 拖拽排序是新闻类的App可以说是必有的交互设计,如今日头条,网易新闻等. GitHub地址:https://github.com/wangliujiayou/Swift-dragLabel 欢迎Star. 效果 主要代码 手势长按移动 1.给CollectionViewCell添加一个长按手势. private lazy var collectionView: UICollectionView = { let clv

  • iOS中关于Swift UICollectionView横向分页的问题

    下面通过图文并茂的形式给大家介绍UICollectionView横向分页的问题,具体内容详情如下所示: 情况 直接看图 滚前 滚后 已经设置collectionView的isPagingEnabled为true了,可是出现了这种情况,原因就是collectionView的contentSize不够. <UICollectionView: 0x7fc565076000; frame = (0 0; 375 197); clipsToBounds = YES; gestureRecognizers

  • Swift实现可自定义分页宽度的UIScrollView

    最近在开发新版的APP时需要一个可自定义分页宽度的图片轮播组件.刚开始自己觉得在这个万能的互联网上早就应该有一个大侠为我们封装好了,我只需要下载.拷贝.粘贴.修改一下代码就可以了.谁知一圈下来,不知道是自己没搜到,还是什么其它原因,根本就找不到.所以,一狠心就自己开干了. 我们先看一下需要的效果,如下图: 总起来说,所需要功能有如下几项: 可自定义分页的宽度,并且在两边可以显示相邻两项的一部分,从而用户知道可以滑动: 可以无限轮播: 可以自动轮播. 对于无限轮播和自动轮播在网上一搜索一大把.这里

  • iOS Swift UICollectionView横向分页滚动,cell左右排版问题详解

    情况 Swift对于一门新的iOS编程语言,他的崛起是必然的,我们这群老程序员们学习新的技能也是必然的,不接受新技能将被这大群体无情的淘汰. 最近因为工作的需求,在做表情键盘时遇到一个问题,我用UICollectionView来布局表情,使用横向分页滚动,但在最后一页出现了如图所示的情况 情况分析图 是的,现在的item分布就是这个鬼样子 现在想要做的,就是将现在这个鬼样子变成另外一种样子,如图 那怎么办?只好重新布局item了 解决方案 我是自定了一个Layout(LXFChatEmotion

  • 低门槛开发iOS、Android、小程序应用的前端框架详解

    现如今跨平台开发技术已不是什么新鲜话题了,在市面上也有一些开源的框架可供选择,然而技术成熟.产品服务健全的平台并不多,其中也不乏推陈出新的框架值得关注. 比如最近使用的AVM,由APICloud迭代推出的多端开发框架,基于JavaScript,兼容多语法,如果是Vue.React的用户,可直接上手,没什么学习成本,具备虚拟DOM,可一次编写多端渲染:主要是APICloud上线已有7年,相对已经成熟,所以我把自己的一些认知和实践结合AVM官方文档的内容做了一下整理,希望能对需要使用跨平台开发技术的

  • el autocomplete支持分页上拉加载使用详解

    目录 el-autocomplete使用 template 实现需求分析 输入框为空时聚焦或失焦后又重新聚焦不会触发请求数据接口 缓存上一次已查询的数据&搜索条件:blurArr.blurTxt 滚动加载指令(监听容器的scroll事件并进行防抖处理) 分页加载 获取数据,并进行格式化 关闭加载圈 分页加载事件 清空输入框,重置上次记录的数据 选中时记录相关数据 数据展示不稳定问题 完整的 scss 文件 完整的 js 文件 el-autocomplete使用 效果图 template <t

  • iOS开发中以application/json上传文件实例详解

    本文通过实例代码给大家讲解iOS中以application/json上传文件的形式,具体内容详情大家参考下本文. 在和sever后台交互的过程中.有时候.他们需要我们iOS开发者以"application/json"形式上传. NSString *accessUrl = [NSString stringWithFormat:@"%@/xxx",@"https://www.xxxxx.com:xxxx"]; NSMutableURLRequest

  • IOS 简单的本地json格式文件解析的实例详解

    IOS 简单的本地json格式文件解析的实例详解 ljweibo.json文件 { "data":[{ "name" : "孙悟空", "content" : "7月12日的国务院常务会议上,李克强明确要求,要将已审议的<快递条例(草案)>向社会公开征求意见.在会上,总理说了这么一段话:"几年前,快递业刚刚开始发展的时候,有些城市不允许快递存在,理由是影响市容整洁,快递员骑的摩的也不允许停放.但

  • iOS Webview自适应实际内容高度的4种方法详解

    //第一种方法 - (void)webViewDidFinishLoad:(UIWebView *)webView { CGFloat webViewHeight=[webView.scrollView contentSize].height; CGRect newFrame = webView.frame; newFrame.size.height = webViewHeight; webView.frame = newFrame; _webTablewView.contentSize = C

  • Bootstrap分页插件之Bootstrap Paginator实例详解

    Bootstrap Paginator是一款基于Bootstrap的js分页插件,功能很丰富,个人觉得这款插件已经无可挑剔了.它提供了一系列的参数用来支持用户的定制,提供了公共的方法可随时获得插件状态的改变,以及事件来监听用户的动作.目前经过测试的浏览器包括: Firefox 5+, Chrome 14+, Safari 5+, Opera 11.6+ and IE 7+. 官网地址:http://bootstrappaginator.org/ DownloadVisit Project in

  • jQuery Ajax自定义分页组件(jquery.loehpagerv1.0)实例详解

    简单的两个步骤即可实现分页功能 <script src="<%=basePath%>/resources/js/jquery-1.7.1.min.js"></script> <script src="<%=basePath%>/resources/js/jquery.loehpagerv1.0.js"></script> <script type="text/JavaScript

  • Swift 5.1 之类型转换与模式匹配的教程详解

    类型转换在Swift中使用 is 和 as 操作符实现. 类型检查 使用操作符 is 检查一个实例是否是某个确定的类以及其继承体系的父类或子类类型.如果是某个确定的类(该类继承体系的父类或子类)类型,则返回 true ,否则返回 false . class Cat { func hairColor() -> String { return "五颜六色" } } class WhiteCat: Cat { override func hairColor() -> String

随机推荐