SwipUP 上的 collectionView 动画?
collectionView Animation on SwipUP?
我想根据内容偏移为滑动时的 collectionView 制作动画。它就像一个页面控制器,但只显示一次滑动。我附上了视频,因为我知道解释不好。
您可以从那里下载视频。
有多种方法可以满足您的需求,这里是一种方法:
我正在设置 UIImageView
以及固定到主视图的前导、尾随、顶部和底部锚点的叠加层 UIView
。
我的目标是像您的示例一样向上滑动集合视图,然后根据在集合视图中点击的单元格更改覆盖视图的颜色。
这里有一些变量和初始设置:
class SwipeCollectionView: UIViewController
{
private var collectionView: UICollectionView!
private let imageView = UIImageView()
private let overlayView = UIView()
// Collection view data source
private let colors: [UIColor] = [.red,
.systemBlue,
.orange,
.systemTeal,
.purple,
.systemYellow]
// Store the collection view's bottom anchor which is used
// to animate the collection view
private var cvBottomAnchor: NSLayoutConstraint?
// Use this flag to disable swipe actions when carousel is showing
private var isCarouselShowing = false
// Use this to check if we are swiping up
private var previousSwipeLocation: CGPoint?
// Random width and height, change as you wish
private let cellWidth: CGFloat = 100
private let collectionViewHeight: CGFloat = 185
private let reuseIdentifier = "cell"
override func viewDidLoad()
{
super.viewDidLoad()
configureNavigationBar()
configureOverlayView()
configureCollectionView()
}
private func configureNavigationBar()
{
title = "Swipe CV"
let appearance = UINavigationBarAppearance()
// Color of the nav bar background
appearance.backgroundColor = .white // primary black for you
navigationController?.navigationBar.standardAppearance = appearance
navigationController?.navigationBar.scrollEdgeAppearance = appearance
}
现在完成一些基本设置后,下面是图像和叠加视图的设置方式。这里没什么特别的,但要注意添加到叠加视图的手势识别器
private func configureOverlayView()
{
imageView.image = UIImage(named: "dog")
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFill
overlayView.backgroundColor = colors.first!.withAlphaComponent(0.5)
overlayView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(imageView)
view.addSubview(overlayView)
// Auto layout pinning the image view and overlay view
// to the main container view
view.addConstraints([
imageView.leadingAnchor
.constraint(equalTo: view.leadingAnchor),
imageView.topAnchor
.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
imageView.trailingAnchor
.constraint(equalTo: view.trailingAnchor),
imageView.bottomAnchor
.constraint(equalTo: view.bottomAnchor),
overlayView.leadingAnchor
.constraint(equalTo: view.leadingAnchor),
overlayView.topAnchor
.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
overlayView.trailingAnchor
.constraint(equalTo: view.trailingAnchor),
overlayView.bottomAnchor
.constraint(equalTo: view.bottomAnchor)
])
// We will observe a swipe gesture to check if it is a swipe
// upwards and then react accordingly
let swipeGesture = UIPanGestureRecognizer(target: self,
action: #selector(didSwipe(_:)))
overlayView.addGestureRecognizer(swipeGesture)
}
现在一旦完成,我们需要创建一个水平滚动的 uicollectionview,它位于屏幕外,当我们向上滑动时可以在其中动画,这是完成的方法
private func configureCollectionView()
{
collectionView = UICollectionView(frame: .zero,
collectionViewLayout: createLayout())
collectionView.backgroundColor = .clear
collectionView.register(UICollectionViewCell.self,
forCellWithReuseIdentifier: reuseIdentifier)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.showsHorizontalScrollIndicator = false
// Add some padding for the content on the left
collectionView.contentInset = UIEdgeInsets(top: 0,
left: 15,
bottom: 0,
right: 0)
collectionView.dataSource = self
collectionView.delegate = self
overlayView.addSubview(collectionView)
// Collection View should start below the screen
// We need to persist with this constraint so we can change it later
let bottomAnchor = overlayView.safeAreaLayoutGuide.bottomAnchor
cvBottomAnchor
= collectionView.bottomAnchor.constraint(equalTo: bottomAnchor,
constant: collectionViewHeight)
// Collection View starts as hidden and will be animated in swipe up
collectionView.alpha = 0.0
// Add collection view constraints
overlayView.addConstraints([
collectionView.leadingAnchor.constraint(equalTo: overlayView.leadingAnchor),
cvBottomAnchor!,
collectionView.trailingAnchor.constraint(equalTo: overlayView.trailingAnchor),
collectionView.heightAnchor.constraint(equalToConstant: collectionViewHeight)
])
}
private func createLayout() -> UICollectionViewFlowLayout
{
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = CGSize(width: cellWidth, height: collectionViewHeight)
layout.minimumInteritemSpacing = 20
return layout
}
到目前为止的代码应该是这样的:
您仍然看不到集合视图,为此,执行平移手势的 didSwipe
动作
@objc
private func didSwipe(_ gesture: UIGestureRecognizer)
{
if !isCarouselShowing
{
let currentSwipeLocation = gesture.location(in: view)
if gesture.state == .began
{
// record the swipe location when we start the pan gesture
previousSwipeLocation = currentSwipeLocation
}
// On swipe continuation, verify the swipe is in the upward direction
if gesture.state == .changed,
let previousSwipeLocation = previousSwipeLocation,
currentSwipeLocation.y < previousSwipeLocation.y
{
isCarouselShowing = true
revealCollectionView()
}
}
}
// Animate the y position of the collection view and the alpha
private func revealCollectionView()
{
// We need to set the top constraint (y position)
// to be somewhere above the screen plus some padding
cvBottomAnchor?.constant = 0 - 75
UIView.animate(withDuration: 0.25) { [weak self] in
// animate change in constraints
self?.overlayView.layoutIfNeeded()
// reveal the collection view
self?.collectionView.alpha = 1.0
} completion: { (finished) in
// do something
}
}
最后,为了完整起见,这里是集合视图数据源和委托:
extension SwipeCollectionView: UICollectionViewDataSource
{
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int
{
return colors.count
}
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell
= collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier,
for: indexPath)
cell.layer.cornerRadius = 20
cell.clipsToBounds = true
cell.contentView.backgroundColor = colors[indexPath.item]
return cell
}
}
extension SwipeCollectionView: UICollectionViewDelegate
{
func collectionView(_ collectionView: UICollectionView,
didSelectItemAt indexPath: IndexPath)
{
overlayView.backgroundColor
= colors[indexPath.item].withAlphaComponent(0.5)
}
}
现在 运行 当您向上滑动时,这应该会给您这样的体验:
我相信这应该足以让您入门
更新
示例的完整源代码可在 gist here
我想根据内容偏移为滑动时的 collectionView 制作动画。它就像一个页面控制器,但只显示一次滑动。我附上了视频,因为我知道解释不好。
您可以从那里下载视频。
有多种方法可以满足您的需求,这里是一种方法:
我正在设置 UIImageView
以及固定到主视图的前导、尾随、顶部和底部锚点的叠加层 UIView
。
我的目标是像您的示例一样向上滑动集合视图,然后根据在集合视图中点击的单元格更改覆盖视图的颜色。
这里有一些变量和初始设置:
class SwipeCollectionView: UIViewController
{
private var collectionView: UICollectionView!
private let imageView = UIImageView()
private let overlayView = UIView()
// Collection view data source
private let colors: [UIColor] = [.red,
.systemBlue,
.orange,
.systemTeal,
.purple,
.systemYellow]
// Store the collection view's bottom anchor which is used
// to animate the collection view
private var cvBottomAnchor: NSLayoutConstraint?
// Use this flag to disable swipe actions when carousel is showing
private var isCarouselShowing = false
// Use this to check if we are swiping up
private var previousSwipeLocation: CGPoint?
// Random width and height, change as you wish
private let cellWidth: CGFloat = 100
private let collectionViewHeight: CGFloat = 185
private let reuseIdentifier = "cell"
override func viewDidLoad()
{
super.viewDidLoad()
configureNavigationBar()
configureOverlayView()
configureCollectionView()
}
private func configureNavigationBar()
{
title = "Swipe CV"
let appearance = UINavigationBarAppearance()
// Color of the nav bar background
appearance.backgroundColor = .white // primary black for you
navigationController?.navigationBar.standardAppearance = appearance
navigationController?.navigationBar.scrollEdgeAppearance = appearance
}
现在完成一些基本设置后,下面是图像和叠加视图的设置方式。这里没什么特别的,但要注意添加到叠加视图的手势识别器
private func configureOverlayView()
{
imageView.image = UIImage(named: "dog")
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFill
overlayView.backgroundColor = colors.first!.withAlphaComponent(0.5)
overlayView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(imageView)
view.addSubview(overlayView)
// Auto layout pinning the image view and overlay view
// to the main container view
view.addConstraints([
imageView.leadingAnchor
.constraint(equalTo: view.leadingAnchor),
imageView.topAnchor
.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
imageView.trailingAnchor
.constraint(equalTo: view.trailingAnchor),
imageView.bottomAnchor
.constraint(equalTo: view.bottomAnchor),
overlayView.leadingAnchor
.constraint(equalTo: view.leadingAnchor),
overlayView.topAnchor
.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
overlayView.trailingAnchor
.constraint(equalTo: view.trailingAnchor),
overlayView.bottomAnchor
.constraint(equalTo: view.bottomAnchor)
])
// We will observe a swipe gesture to check if it is a swipe
// upwards and then react accordingly
let swipeGesture = UIPanGestureRecognizer(target: self,
action: #selector(didSwipe(_:)))
overlayView.addGestureRecognizer(swipeGesture)
}
现在一旦完成,我们需要创建一个水平滚动的 uicollectionview,它位于屏幕外,当我们向上滑动时可以在其中动画,这是完成的方法
private func configureCollectionView()
{
collectionView = UICollectionView(frame: .zero,
collectionViewLayout: createLayout())
collectionView.backgroundColor = .clear
collectionView.register(UICollectionViewCell.self,
forCellWithReuseIdentifier: reuseIdentifier)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.showsHorizontalScrollIndicator = false
// Add some padding for the content on the left
collectionView.contentInset = UIEdgeInsets(top: 0,
left: 15,
bottom: 0,
right: 0)
collectionView.dataSource = self
collectionView.delegate = self
overlayView.addSubview(collectionView)
// Collection View should start below the screen
// We need to persist with this constraint so we can change it later
let bottomAnchor = overlayView.safeAreaLayoutGuide.bottomAnchor
cvBottomAnchor
= collectionView.bottomAnchor.constraint(equalTo: bottomAnchor,
constant: collectionViewHeight)
// Collection View starts as hidden and will be animated in swipe up
collectionView.alpha = 0.0
// Add collection view constraints
overlayView.addConstraints([
collectionView.leadingAnchor.constraint(equalTo: overlayView.leadingAnchor),
cvBottomAnchor!,
collectionView.trailingAnchor.constraint(equalTo: overlayView.trailingAnchor),
collectionView.heightAnchor.constraint(equalToConstant: collectionViewHeight)
])
}
private func createLayout() -> UICollectionViewFlowLayout
{
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = CGSize(width: cellWidth, height: collectionViewHeight)
layout.minimumInteritemSpacing = 20
return layout
}
到目前为止的代码应该是这样的:
您仍然看不到集合视图,为此,执行平移手势的 didSwipe
动作
@objc
private func didSwipe(_ gesture: UIGestureRecognizer)
{
if !isCarouselShowing
{
let currentSwipeLocation = gesture.location(in: view)
if gesture.state == .began
{
// record the swipe location when we start the pan gesture
previousSwipeLocation = currentSwipeLocation
}
// On swipe continuation, verify the swipe is in the upward direction
if gesture.state == .changed,
let previousSwipeLocation = previousSwipeLocation,
currentSwipeLocation.y < previousSwipeLocation.y
{
isCarouselShowing = true
revealCollectionView()
}
}
}
// Animate the y position of the collection view and the alpha
private func revealCollectionView()
{
// We need to set the top constraint (y position)
// to be somewhere above the screen plus some padding
cvBottomAnchor?.constant = 0 - 75
UIView.animate(withDuration: 0.25) { [weak self] in
// animate change in constraints
self?.overlayView.layoutIfNeeded()
// reveal the collection view
self?.collectionView.alpha = 1.0
} completion: { (finished) in
// do something
}
}
最后,为了完整起见,这里是集合视图数据源和委托:
extension SwipeCollectionView: UICollectionViewDataSource
{
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int
{
return colors.count
}
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell
= collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier,
for: indexPath)
cell.layer.cornerRadius = 20
cell.clipsToBounds = true
cell.contentView.backgroundColor = colors[indexPath.item]
return cell
}
}
extension SwipeCollectionView: UICollectionViewDelegate
{
func collectionView(_ collectionView: UICollectionView,
didSelectItemAt indexPath: IndexPath)
{
overlayView.backgroundColor
= colors[indexPath.item].withAlphaComponent(0.5)
}
}
现在 运行 当您向上滑动时,这应该会给您这样的体验:
我相信这应该足以让您入门
更新
示例的完整源代码可在 gist here