ios - collectionview - 滚动前缩放中心单元

标签 ios swift xcode uicollectionview swift3

我有一个垂直的collectionView,我正在调用一个函数来缩放中心单元格并使两侧的单元格淡入淡出。问题是它只在滚动开始后发生。我尝试从 viewdidloadviewwillappear 调用,但在首次填充 collectionview 时在滚动之前无法发生这种情况。 这就是它的名字。

self.collectionView.setScaledDesginParam(scaledPattern: .verticalCenter, maxScale: 1.2, minScale: 0.5, maxAlpha: 1.0, minAlpha: 0.5)
self.collectionView.scaledVisibleCells()
self.collectionView.reloadData()

这是主要功能

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))
    }
}

最佳答案

viewWillAppear 方法中使用以下代码行:

self.collectionView.reloadData()
self.collectionView.setScaledDesginParam(scaledPattern: .verticalCenter, maxScale: 1.2, minScale: 0.5, maxAlpha: 1.0, minAlpha: 0.5)
self.collectionView.scaledVisibleCells()

首先重新加载 Collection View ,然后缩放它。

关于ios - collectionview - 滚动前缩放中心单元,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41324559/

相关文章:

ios - Swift 中 UITableView 的动态搜索功能

html - 当我指定了视口(viewport)时,为什么智能应用程序横幅会部分/完全隐藏在 Safari 中?

ios - 如何在 swift 中为 SKSpriteNode 创建翻转效果

objective-c - 当一个 Action 已经在进行时,用一个按钮开始一个 Action

ios - 如何以编程方式布局 Storyboard上的 View ?

arrays - 无法使用类型为 '[ClassName.StructName]' 的索引下标类型为 'ClassName.StructName' 的值

xcode - 为什么 Xcode 断点不起作用?

swift - 无法将 Collection View 连接到 View Controller 代码。 'Error unrecognized selector sent to instance'

iphone - 核心数据 : Ubiquity: Using local storage: 1 never becomes 0

objective-c - 如何检测 iPhone 中的抖动