Ios 自定义集合视图未缩放上一个图像
因此,我有一个自定义的collectionviewflowlayout,它工作得非常好,但在我的一个集合视图中,它没有按需要缩放图像。我在下面附上了一些图片,你可以看到最后一个单元格没有正确缩放 我不知道为什么这个单元会出现这种缩放问题 collectionview是collectionviewflowlayout的自定义类,用于将单元格捕捉到屏幕中心:Ios 自定义集合视图未缩放上一个图像,ios,swift,xcode,uicollectionview,Ios,Swift,Xcode,Uicollectionview,因此,我有一个自定义的collectionviewflowlayout,它工作得非常好,但在我的一个集合视图中,它没有按需要缩放图像。我在下面附上了一些图片,你可以看到最后一个单元格没有正确缩放 我不知道为什么这个单元会出现这种缩放问题 collectionview是collectionviewflowlayout的自定义类,用于将单元格捕捉到屏幕中心: class VerticalCollectionViewFlow: UICollectionViewFlowLayout { o
class VerticalCollectionViewFlow: UICollectionViewFlowLayout {
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
if let cv = self.collectionView {
let cvBounds = cv.bounds
let halfHeight = cvBounds.size.height * 0.5
print(proposedContentOffset.y)
let proposedContentOffsetCenterY = proposedContentOffset.y + halfHeight
if let attributesForVisibleCells = self.layoutAttributesForElements(in: cvBounds) {
var candidateAttributes : UICollectionViewLayoutAttributes?
for attributes in attributesForVisibleCells {
// == Skip comparison with non-cell items (headers and footers) == //
if attributes.representedElementCategory != UICollectionElementCategory.cell {
continue
}
if (attributes.center.y == 0) || (attributes.center.y > (cv.contentOffset.y + halfHeight) && velocity.y < 0) {
continue
}
// == First time in the loop == //
guard let candAttrs = candidateAttributes else {
candidateAttributes = attributes
continue
}
let a = attributes.center.y - proposedContentOffsetCenterY
let b = candAttrs.center.y - proposedContentOffsetCenterY
if fabsf(Float(a)) < fabsf(Float(b)) {
candidateAttributes = attributes;
}
}
// Beautification step , I don't know why it works!
if(proposedContentOffset.y == -(cv.contentInset.top)) {
return proposedContentOffset
}
if candidateAttributes != nil {
return CGPoint(x: proposedContentOffset.x, y: floor(candidateAttributes!.center.y - halfHeight))
}
}
}
// fallback
return super.targetContentOffset(forProposedContentOffset: proposedContentOffset)
}
}
class VerticalCollectionViewFlow:UICollectionViewFlowLayout{
覆盖func targetContentOffset(forProposedContentOffset proposedContentOffset:CGPoint,使用CrollingVelocity:CGPoint)->CGPoint{
如果让cv=self.collectionView{
设cvBounds=cv.bounds
设半高=cvBounds.size.height*0.5
打印(proposedContentOffset.y)
设proposedContentOffsetCenterY=proposedContentOffset.y+半高
如果let attributesForVisibleCells=self.layouttributesforElements(in:cvBounds){
var CandidateAttribute:UICollectionViewLayoutAttribute?
对于attributesForVisibleCells中的属性{
//==跳过与非单元格项(页眉和页脚)的比较==//
如果attributes.representedElementCategory!=UICollectionElementCategory.cell{
持续
}
if(attributes.center.y==0)| |(attributes.center.y>(cv.contentOffset.y+halfHeight)&&velocity.y<0){
持续
}
//==循环中的第一次==//
guard let candAttrs=候选属性else{
CandidateAttribute=属性
持续
}
设a=attributes.center.y-proposedContentOffsetCenterY
设b=candAttrs.center.y-proposedContentOffsetCenterY
如果fabsf(浮动(a))
缩放是从另一个类处理的,该类从设置UIcollectionViewController委托的主viewcontroller的viewdidload调用
import UIKit
public enum SC_ScaledPattern {
case horizontalCenter
case horizontalLeft
case horizontalRight
case verticalCenter
case verticalBottom
case verticalTop
}
open class ScaledVisibleCellsCollectionView {
static let sharedInstance = ScaledVisibleCellsCollectionView()
var maxScale: CGFloat = 1.0
var minScale: CGFloat = 0.5
var maxAlpha: CGFloat = 1.0
var minAlpha: CGFloat = 0.5
var scaledPattern: SC_ScaledPattern = .verticalCenter
}
extension UICollectionView {
/**
Please always set
*/
public func setScaledDesginParam(scaledPattern pattern: SC_ScaledPattern, maxScale: CGFloat, minScale: CGFloat, maxAlpha: CGFloat, minAlpha: CGFloat) {
ScaledVisibleCellsCollectionView.sharedInstance.scaledPattern = pattern
ScaledVisibleCellsCollectionView.sharedInstance.maxScale = maxScale
ScaledVisibleCellsCollectionView.sharedInstance.minScale = minScale
ScaledVisibleCellsCollectionView.sharedInstance.maxAlpha = maxAlpha
ScaledVisibleCellsCollectionView.sharedInstance.minAlpha = minAlpha
}
/**
Please call at any time
*/
public func scaledVisibleCells() {
switch ScaledVisibleCellsCollectionView.sharedInstance.scaledPattern {
case .horizontalCenter, .horizontalLeft, .horizontalRight:
scaleCellsForHorizontalScroll(visibleCells)
break
case .verticalCenter, .verticalTop, .verticalBottom:
self.scaleCellsForVerticalScroll(visibleCells)
break
}
}
}
extension UICollectionView {
fileprivate func scaleCellsForHorizontalScroll(_ visibleCells: [UICollectionViewCell]) {
let scalingAreaWidth = bounds.width / 2
let maximumScalingAreaWidth = (bounds.width / 2 - scalingAreaWidth) / 2
for cell in visibleCells {
var distanceFromMainPosition: CGFloat = 0
switch ScaledVisibleCellsCollectionView.sharedInstance.scaledPattern {
case .horizontalCenter:
distanceFromMainPosition = horizontalCenter(cell)
break
case .horizontalLeft:
distanceFromMainPosition = abs(cell.frame.midX - contentOffset.x - (cell.bounds.width / 2))
break
case .horizontalRight:
distanceFromMainPosition = abs(bounds.width / 2 - (cell.frame.midX - contentOffset.x) + (cell.bounds.width / 2))
break
default:
return
}
let preferredAry = scaleCells(distanceFromMainPosition, maximumScalingArea: maximumScalingAreaWidth, scalingArea: scalingAreaWidth)
let preferredScale = preferredAry[0]
let preferredAlpha = preferredAry[1]
cell.transform = CGAffineTransform(scaleX: preferredScale, y: preferredScale)
cell.alpha = preferredAlpha
}
}
fileprivate func scaleCellsForVerticalScroll(_ visibleCells: [UICollectionViewCell]) {
let scalingAreaHeight = bounds.height / 2
let maximumScalingAreaHeight = (bounds.height / 2 - scalingAreaHeight) / 2
for cell in visibleCells {
var distanceFromMainPosition: CGFloat = 0
switch ScaledVisibleCellsCollectionView.sharedInstance.scaledPattern {
case .verticalCenter:
distanceFromMainPosition = verticalCenter(cell)
break
case .verticalBottom:
distanceFromMainPosition = abs(bounds.height - (cell.frame.midY - contentOffset.y + (cell.bounds.height / 2)))
break
case .verticalTop:
distanceFromMainPosition = abs(cell.frame.midY - contentOffset.y - (cell.bounds.height / 2))
break
default:
return
}
let preferredAry = scaleCells(distanceFromMainPosition, maximumScalingArea: maximumScalingAreaHeight, scalingArea: scalingAreaHeight)
let preferredScale = preferredAry[0]
let preferredAlpha = preferredAry[1]
cell.transform = CGAffineTransform(scaleX: preferredScale, y: preferredScale)
cell.alpha = preferredAlpha
}
}
fileprivate func scaleCells(_ distanceFromMainPosition: CGFloat, maximumScalingArea: CGFloat, scalingArea: CGFloat) -> [CGFloat] {
var preferredScale: CGFloat = 0.0
var preferredAlpha: CGFloat = 0.0
let maxScale = ScaledVisibleCellsCollectionView.sharedInstance.maxScale
let minScale = ScaledVisibleCellsCollectionView.sharedInstance.minScale
let maxAlpha = ScaledVisibleCellsCollectionView.sharedInstance.maxAlpha
let minAlpha = ScaledVisibleCellsCollectionView.sharedInstance.minAlpha
if distanceFromMainPosition < maximumScalingArea {
// cell in maximum-scaling area
preferredScale = maxScale
preferredAlpha = maxAlpha
} else if distanceFromMainPosition < (maximumScalingArea + scalingArea) {
// cell in scaling area
let multiplier = abs((distanceFromMainPosition - maximumScalingArea) / scalingArea)
preferredScale = maxScale - multiplier * (maxScale - minScale)
preferredAlpha = maxAlpha - multiplier * (maxAlpha - minAlpha)
} else {
// cell in minimum-scaling area
preferredScale = minScale
preferredAlpha = minAlpha
}
return [ preferredScale, preferredAlpha ]
}
}
extension UICollectionView {
fileprivate func horizontalCenter(_ cell: UICollectionViewCell)-> CGFloat {
return abs(bounds.width / 2 - (cell.frame.midX - contentOffset.x))
}
fileprivate func verticalCenter(_ cell: UICollectionViewCell)-> CGFloat {
return abs(bounds.height / 2 - (cell.frame.midY - contentOffset.y))
}
}
导入UIKit
公共枚举SC_缩放模式{
病例水平中心
案例水平左
案例水平权
病例垂直中心
箱底
箱垂直顶部
}
开放类ScaledVisibleCellsCollectionView{
静态let sharedInstance=ScaledVisibleCellsCollectionView()
var maxScale:CGFloat=1.0
var最小刻度:CGFloat=0.5
var maxapha:CGFloat=1.0
var minAlpha:CGFloat=0.5
变量scaledPattern:SC_scaledPattern=.verticalCenter
}
扩展UICollectionView{
/**
请随时准备好
*/
public func setScaledDesginParam(scaledPattern模式:SC_scaledPattern,maxScale:CGFloat,minScale:CGFloat,maxAlpha:CGFloat){
ScaledVisibleCellsCollectionView.sharedInstance.scaledPattern=pattern
ScaledVisibleCellsCollectionView.sharedInstance.maxScale=maxScale
ScaledVisibleCellsCollectionView.sharedInstance.minScale=minScale
ScaledVisibleCellsCollectionView.sharedInstance.maxAlpha=maxAlpha
ScaledVisibleCellsCollectionView.sharedInstance.minAlpha=minAlpha
}
/**
请随时打电话
*/
公共函数scaledVisibleCells(){
切换ScaledVisibleCellsCollectionView.sharedInstance.scaledPattern{
案例.horizontalCenter、.horizontalLeft、.horizontalRight:
scaleCellsForHorizontalScroll(可视单元格)
打破
案例.垂直中心,.垂直顶部,.垂直底部:
self.scaleCellsForeticalScroll(可视单元格)
打破
}
}
}
扩展UICollectionView{
fileprivate func scaleCellsForHorizontalScroll(visibleCells:[UICollectionViewCell]){
设scalingAreaWidth=bounds.width/2
设maximumScalingAreaWidth=(bounds.width/2-scalingAreaWidth)/2
用于可见单元格中的单元格{
var distanceFromMainPosition:CGFloat=0
切换ScaledVisibleCellsCollectionView.sharedInstance.scaledPattern{
案例.水平中心:
距离主位置=水平中心(单元格)
打破
案例.水平左侧:
distanceFromMainPosition=abs(cell.frame.midX-contentOffset.x-(cell.bounds.width/2))
打破
案例.横向权利:
distanceFromMainPosition=abs(bounds.width/2-(cell.frame.midX-contentOffset.x)+(cell.bounds.width/2))
打破
违约:
返回
}
让preferredAry=scaleCells(与主位置的距离,最大缩放区域:最大缩放区域宽度,缩放区域:缩放区域宽度)
让preferredScale=preferredAry[0]
让preferredAlpha=preferredAry[1]
cell.transform=CGAffineTransform(scaleX:preferredScale,y:preferredScale)
cell.alpha=首选alpha
}
}
fileprivate func ScaleCellsServerticalScroll(visibleCells:[UICollectionViewCell]){
让scalingAreaHeight=bounds.height/2
让最大缩放区域高度=
extension JourneyViewController: UIScrollViewDelegate {
//------------------------------------------------------------------ make the scrolling a bit sticky
func scrollViewDidScroll(_ scrollView: UIScrollView) {
self.collectionViewPart.scaledVisibleCells()
let offsetY = scrollView.contentOffset.x
let contentHeight = scrollView.contentSize.width
if offsetY > contentHeight - scrollView.frame.size.width {
self.collectionViewPart.reloadData()
}
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
startingScrollingOffset = scrollView.contentOffset
}
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let cellWidth = collectionViewPart.collectionViewLayout.collectionViewContentSize.width
let page: CGFloat
let proposedPage = scrollView.contentOffset.x / cellWidth
// 10% of next cell to change / 90% of previous cell to change
let delta: CGFloat = scrollView.contentOffset.x > startingScrollingOffset.x ? 0.1 : 0.9
if floor(proposedPage + delta) == floor(proposedPage) {
page = floor(proposedPage)
}
else {
page = floor(proposedPage + 1)
}
}