前言:
万万没想到啊,做cell滑动放大的这一天终于还是来了。
Swift
代码地址:https://github.com/gityuency/Autolayout
示例代码类名 【Coll_1_ViewController】 【YXCellScaleFlowLayout】
效果图:
布局代码FlowLayout
import UIKit
class YXCellScaleFlowLayout: UICollectionViewFlowLayout {
private let K_CELL_WIDTH: CGFloat = 260
override init() {
super.init()
itemSize = CGSize(width: K_CELL_WIDTH, height: 360)
scrollDirection = .horizontal
minimumLineSpacing = 0
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}
var collectionViewFrameWidth: CGFloat = 0 {
didSet {
collectionViewFrameWidthHalf = collectionViewFrameWidth / 2
}
}
var collectionViewFrameWidthHalf: CGFloat = 0
var collectionViewFrameHeight: CGFloat = 0
var visibleRect = CGRect.zero
func needViewInfo() {
if collectionViewFrameWidth != collectionView?.frame.width {
collectionViewFrameWidth = collectionView?.frame.width ?? 0
let offsetXY = (collectionViewFrameWidth - K_CELL_WIDTH) / 2
sectionInset = UIEdgeInsets(top: 0, left: offsetXY, bottom: 0, right: offsetXY)
}
if collectionViewFrameHeight != collectionView?.frame.height {
collectionViewFrameHeight = collectionView?.frame.height ?? 0
}
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
needViewInfo()
visibleRect.origin = collectionView?.contentOffset ?? CGPoint.zero
visibleRect.size = collectionView?.frame.size ?? CGSize.zero
let centerX = visibleRect.midX
let array = super.layoutAttributesForElements(in: visibleRect) ?? []
for attributes in array {
let distance = abs(centerX - attributes.center.x)
let scaleRate = distance / (collectionView?.bounds.width ?? 0)
let scale = abs(cos(scaleRate * 1.1))
attributes.transform3D = CATransform3DMakeScale(scale, scale, 1)
}
return array
}
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
let horizontalCenter = proposedContentOffset.x + collectionViewFrameWidthHalf
let targetRect = CGRect(x: proposedContentOffset.x, y: 0.0, width: collectionViewFrameWidth, height: collectionViewFrameHeight)
let array = super.layoutAttributesForElements(in: targetRect) ?? []
var nearestCenterOne = CGFloat(MAXFLOAT)
var shouldBeX: CGFloat = 0
for layoutAttributes in array {
let currentX = layoutAttributes.center.x
let currentDistance = abs(currentX - horizontalCenter)
if currentDistance < nearestCenterOne {
nearestCenterOne = currentDistance
shouldBeX = currentX
}
}
let X = shouldBeX - collectionViewFrameWidthHalf
return CGPoint(x: X , y: proposedContentOffset.y)
}
}