在 UICollectionView 中选择时将单元格扩展到全屏
Posted
技术标签:
【中文标题】在 UICollectionView 中选择时将单元格扩展到全屏【英文标题】:Expand a cell to full screen when selected inside UICollectionView 【发布时间】:2017-06-29 17:14:06 【问题描述】:在 didSelectItemAt 中选择时,我无法让 UICollectionViewCell 扩展到全屏宽度和高度。第一个单元格展开得非常好,但其他单元格在被选中时会在屏幕外显示动画。滚动 CollectionView 内的单元格时,X 和 Y 坐标似乎不为 0。试图让它在 Swift 中工作。非常感谢任何帮助。
struct itemStruct
// Set your values here...
internal let itemWidth: CGFloat = 200
internal let itemHeight: CGFloat = 300
internal let minimumInteritemSpacing: CGFloat = 30
internal let animationDuration: Double = 0.2
internal let transformScale = CGAffineTransform(scaleX: 0.8, y: 0.8)
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource
private let options = itemStruct()
private var cv: UICollectionView!
private var isfirstTimeTransform: Bool = true
override func viewDidLoad()
super.viewDidLoad()
self.initViews()
// MARK: - UI
private func initViews()
// Collection View Layout
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = CGSize(width: options.itemWidth, height: options.itemHeight)
layout.minimumLineSpacing = options.minimumInteritemSpacing
let horizontalInset: CGFloat = (self.view.frame.size.width - options.itemWidth) / 2
let verticalInset: CGFloat = (self.view.frame.size.height - options.itemHeight) / 2
layout.sectionInset = UIEdgeInsetsMake(verticalInset, horizontalInset, verticalInset, horizontalInset)
// Collection View
cv = UICollectionView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height), collectionViewLayout: layout)
cv.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
cv.backgroundColor = UIColor.darkGray
cv.alwaysBounceVertical = false
cv.isPagingEnabled = true
cv.delegate = self
cv.dataSource = self
self.view.addSubview(cv)
// MARK: UICollectionView Data Source
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 10
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath as IndexPath)
cell.backgroundColor = UIColor.white
if indexPath.row == 0 && isfirstTimeTransform
isfirstTimeTransform = false
else
cell.transform = options.transformScale
return cell
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
let item = cv.cellForItem(at: indexPath) // or whatever you collection view cell class name is.
UIView.animate(withDuration: 1.0, animations:
self.view.bringSubview(toFront: self.cv)
collectionView.bringSubview(toFront: item!)
item?.frame.origin = self.view.frame.origin /// this view origin will be at the top of the scroll content, you'll have to figure this out
item?.frame.size.width = self.view.frame.width
item?.frame.size.height = self.view.frame.height
)
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
let pageWidth: CGFloat = options.itemWidth + options.minimumInteritemSpacing; // width + space
let currentOffset: CGFloat = scrollView.contentOffset.x;
let targetOffset: CGFloat = targetContentOffset.pointee.x;
var newTargetOffset: CGFloat = 0
if targetOffset > currentOffset
newTargetOffset = ceil(currentOffset / pageWidth) * pageWidth
else
newTargetOffset = floor(currentOffset / pageWidth) * pageWidth
if newTargetOffset < 0
newTargetOffset = 0
else if newTargetOffset > scrollView.contentSize.width
newTargetOffset = scrollView.contentSize.width
targetContentOffset.pointee.x = currentOffset
scrollView.setContentOffset(CGPoint(x: newTargetOffset, y: 0), animated: true)
var index = Int(newTargetOffset / pageWidth)
if index == 0
// If first index
var cell = self.cv.cellForItem(at: IndexPath(row: index, section: 0))
UIView.animate(withDuration: options.animationDuration, animations:
cell?.transform = .identity
)
cell = self.cv.cellForItem(at: IndexPath(row: index + 1, section: 0))
UIView.animate(withDuration: options.animationDuration, animations:
cell?.transform = self.options.transformScale
)
else
var cell = self.cv.cellForItem(at: IndexPath(row: index, section: 0))
UIView.animate(withDuration: options.animationDuration, animations:
cell?.transform = .identity
)
index -= 1 // Left
cell = self.cv.cellForItem(at: IndexPath(row: index, section: 0))
UIView.animate(withDuration: options.animationDuration, animations:
cell?.transform = self.options.transformScale
)
index += 2 // Right
cell = self.cv.cellForItem(at: IndexPath(row: index, section: 0))
UIView.animate(withDuration: options.animationDuration, animations:
cell?.transform = self.options.transformScale
)
【问题讨论】:
【参考方案1】:用与item
相同的帧初始化一个单独的UIView
,如果item
有图像或其他东西,则将其内容设置为UIView
,最后将UIView
的帧转换/缩放到全屏。
然后,您可以根据需要通过动画使其消失或将其转换回身份。你不应该改变CollectionViewCell
的框架。
【讨论】:
以上是关于在 UICollectionView 中选择时将单元格扩展到全屏的主要内容,如果未能解决你的问题,请参考以下文章
在 uicollectionview 上录制时将图像快速传递给详细视图控制器
从 uicollectionView 选择创建 UITableViewCell
点击时将图像设置为 UICollectionView 单元格