实现collectionViewCell的移动(长按或者直接拖拽)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现collectionViewCell的移动(长按或者直接拖拽)相关的知识,希望对你有一定的参考价值。
参考技术A 最近在实现类似网易新闻的首页滑块的编辑效果: 长按后进入编辑界面, 然后可以通过拖拽实现cell的移动, 研究后发现两种实现方式: 第一种是直接利用系统提供的UICollectionView API实现移动, 不过只能在ios9上面使用. 所以这里就介绍另外一种方式.源码效果示例:
2 在selector中处理手势的响应
a. 记录下当前的indexPath以便于在手指移动的过程中进入.Changed状态的时候使用
b. 通过这个indexPath获取到对应的cell
c. 获取到这个cell截图
d. 并且设置截图的初始位置
e. 隐藏当前的cell
f. 将截图添加到collectionView中
a. 如果在began状态中没有获取到截图直接返回
b. 设置截图的位置, 以达到和手指同步移动
c. 如果新获取到的indexPath有效并且和原来的不相同
d. 移动cell, 更新dataSource
e. 设置新的cell的属性
f. 更新当前的indexPath
a. 获取到当前移动完成的cell
b. 使用动画移除截图并且设置当前的移动完成的cell的属性
如何实现可以显示图像或作为输入属性提供的自定义 UIView 的 CollectionViewCell?
【中文标题】如何实现可以显示图像或作为输入属性提供的自定义 UIView 的 CollectionViewCell?【英文标题】:How to implement a CollectionViewCell that can either display an image or a custom UIView provided as input property? 【发布时间】:2017-01-18 20:36:50 【问题描述】:我有一个collectionView 单元格,它应该显示一个图像或一个生成为自定义UIView
的图标(比如说IconView
)。
目前,我通过将UIImageView
和IconView
作为子视图添加到容器视图来实现这一点。
当提供图像时,UIImageView
的图像属性会简单地更新。当提供新的IconView
时,它当前总是作为子视图添加到容器视图中。因此,在添加之前,首先检查IconView
是否已经添加,如果已经添加,则删除。
虽然这个实现有效,但它不是很优雅,而且似乎效率不高,因为当行数增加时会导致滚动问题。
是否有更好(更有效)的方法来为单个 CollectionViewCell 实现这一点?
class CustomCell: UICollectionViewCell
internal var image: UIImage?
didSet
self.imageView.image = image!
internal var iconView: IconView?
didSet
if !(self.iconContainerView.subviews.flatMap $0 as? IconView.isEmpty)
self.iconView!.removeFromSuperview()
self.iconView!.translatesAutoresizingMaskIntoConstraints = false
self.iconContainerView.addSubview(self.iconView!)
self.image = nil
fileprivate var imageView: UIImageView!
fileprivate var iconContainerView: UIView!
fileprivate var layoutConstraints = [NSLayoutConstraint]()
override init(frame: CGRect)
super.init(frame: frame)
// ContainerView
self.iconContainerView = UIView()
self.iconContainerView.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(self.iconContainerView)
// ImageView
self.imageView = UIImageView()
self.imageView.translatesAutoresizingMaskIntoConstraints = false
self.iconContainerView.addSubview(self.imageView)
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
override func layoutSubviews()
super.layoutSubviews()
self.iconContainerView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor).isActive = true
self.iconContainerView.widthAnchor.constraint(equalToConstant: 60).isActive = true
self.iconContainerView.heightAnchor.constraint(equalToConstant: 60).isActive = true
self.iconContainerView.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor).isActive = true
// Deactivate non-reusable constraints
_ = self.layoutConstraints.map $0.isActive = false
self.layoutConstraints = [NSLayoutConstraint]()
if let iconView = self.iconView
self.imageView.isHidden = true
self.layoutConstraints.append(iconView.centerYAnchor.constraint(equalTo: self.iconContainerView.centerYAnchor))
self.layoutConstraints.append(iconView.centerXAnchor.constraint(equalTo: self.iconContainerView.centerXAnchor))
self.layoutConstraints.append(iconView.heightAnchor.constraint(equalToConstant: 40))
self.layoutConstraints.append(iconView.widthAnchor.constraint(equalToConstant: 40))
else
self.imageView.isHidden = false
self.iconView?.isHidden = true
self.layoutConstraints.append(self.imageView.leadingAnchor.constraint(equalTo: self.iconContainerView.leadingAnchor))
self.layoutConstraints.append(self.imageView.trailingAnchor.constraint(equalTo: self.iconContainerView.trailingAnchor))
self.layoutConstraints.append(self.imageView.topAnchor.constraint(equalTo: self.iconContainerView.topAnchor))
self.layoutConstraints.append(self.imageView.bottomAnchor.constraint(equalTo: self.iconContainerView.bottomAnchor))
_ = self.layoutConstraints.map $0.isActive = true
【问题讨论】:
你不能使用两个不同的UICollectionViewCell
s有什么原因吗?
我使用的 collectionView 单元格相当长,图像/图标是唯一的布局差异。我不知道两个 UICollectionView 是否会提高性能,因为可以重用的单元格更少。此外,它需要在每个类和一个公共父类中重复所有约束。不是很有吸引力,但如果这是我会考虑的唯一方式。但是真的不能在单个单元格中显示自定义视图吗?
【参考方案1】:
设置时不要广告和删除 IconView。将两者添加到同一位置并更改 isHidden、alpha 或不透明度或bringSubviewToFront。这对主线程的密集程度要低得多。
【讨论】:
是的,但是每次渲染单元格时都应该显示一个全新的“IconView”。如果仅更新了 IconView 的属性,您的建议将是正确的(就像我已经为 UIImageView 所做的那样,在提供 IconView 时将被设置为隐藏)。理想情况下,IconView 也应该作为属性提供......有什么想法吗?以上是关于实现collectionViewCell的移动(长按或者直接拖拽)的主要内容,如果未能解决你的问题,请参考以下文章
如何实现可以显示图像或作为输入属性提供的自定义 UIView 的 CollectionViewCell?
为啥我的 collectionViewCell 显示异常行为?
如何更改自定义 CollectionViewCell 的背景颜色?