ios - 滚动到 CollectionView 中的上一张/下一张图像时,正确计算颜色不透明度偏移以更改背景颜色?

标签 ios swift uicollectionview swift3

如果标题不明确,我深表歉意,但目前,我有一个 UICollectionView 图像。我最近发现了一种使用 DominantColor 查找 UIImage 主色的方法.有了这个,我试图在用户从一个 UIImage 单元格滚动到下一个单元格时更改 UICollectionView 的背景颜色,即背景颜色将从 imageX 中慢慢消失imageX+1 的主色。

但是,我在这上面花了几天时间,并且在单元格开始滚动到下一个/上一个图像时,很难更改 UICollectionView 的背景颜色不透明度。

我的界面:

enter image description here

后台代码:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as UICollectionViewCell

    let frame: CGRect = CGRect(x: 0, y: 0, width: imageView.frame.size.width, height: imageView.frame.size.height)

    let subView: UIImageView = UIImageView(frame: frame)

    subView.image = imagesArray[indexPath.row].theImage

    subView.contentMode = UIViewContentMode.scaleAspectFit

    cell.addSubview(subView)

    return cell
}

// The colorsArray will contain a dominant color for each image in the CollectionView
func dominantColorOfImages()
{
    for index in 0..<imagesArray.count
    {
        if let image = imagesArray[index].theImage
        {
            let colors: [UIColor] = image.dominantColors()

            colorsArray[index] = colors[index]
        }
    }

    // Default dominant background color for first image in CollectionView
    imagesCollectionView.backgroundColor = colorsArray[0]

    imagesCollectionView.reloadData()
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
{
    let pageWidth: CGFloat = scrollView.bounds.size.width

    let currentPage: Int = Int( floor( (scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1)

    currentImagePage = currentPage
}

func scrollViewDidScroll(_ scrollView: UIScrollView)
{
    let pageWidth: CGFloat = scrollView.bounds.size.width
    let currentPage: Int = Int( floor( (scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1)

    // Horizontal
    let maximumHorizontalOffset: CGFloat = scrollView.contentSize.width - scrollView.frame.size.width
    let currentHorizontalOffset: CGFloat = scrollView.contentOffset.x


    // This is the offset of how far the right side edge of the current image has pass the end of the left screen (i.e. when the user scrolls the image from the right to the left to get to the next image)
    let pageOffset: CGFloat = ( (pageWidth * CGFloat(currentImagePage) ) + (pageWidth / 2) ) / maximumHorizontalOffset

    if percentageHorizontalOffset < pageOffset
    {

        imagesCollectionView.backgroundColor = fadeFromColorToColor(fromColor: colorsArray[currentImagePage], toColor: colorsArray[currentImagePage + 1], withPercentage: percentageHorizontalOffset * CGFloat(colorsArray.count - 1 ) )

    }
    else
    {

        imagesCollectionView.backgroundColor = fadeFromColorToColor(fromColor: colorsArray[currentImagePage], toColor: colorsArray[currentImagePage + 1], withPercentage: (percentageHorizontalOffset - pageOffset) * CGFloat(colorsArray.count - 1) ))

    }
}

func fadeFromColorToColor(fromColor: UIColor, toColor: UIColor, withPercentage: CGFloat) -> UIColor
{
    var fromRed: CGFloat = 0.0
    var fromGreen: CGFloat = 0.0
    var fromBlue: CGFloat = 0.0
    var fromAlpha: CGFloat = 0.0

    // Get the RGBA values from the colours
    fromColor.getRed(&fromRed, green: &fromGreen, blue: &fromBlue, alpha: &fromAlpha)

    var toRed: CGFloat = 0.0
    var toGreen: CGFloat = 0.0
    var toBlue: CGFloat = 0.0
    var toAlpha: CGFloat = 0.0

    toColor.getRed(&toRed, green: &toGreen, blue: &toBlue, alpha: &toAlpha)

    // Calculate the actual RGBA values of the fade colour
    let red = (toRed - fromRed) * withPercentage + fromRed;
    let green = (toGreen - fromGreen) * withPercentage + fromGreen;
    let blue = (toBlue - fromBlue) * withPercentage + fromBlue;
    let alpha = (toAlpha - fromAlpha) * withPercentage + fromAlpha;

    // Return the fade colour
    return UIColor(red: red, green: green, blue: blue, alpha: alpha)
}

这与此处提供的答案相同:Changing between colors based on UIScrollView's contentOffset ,除了 pageOffset 被硬编码为 0.5 因为当我处理 colorsArray.count - 1 页面时,这个问题涉及 2 个静态页面,所以我不得不重新- 以不同的方式计算 pageOffset

我遇到的问题是在 scrollViewDidScrollwithPercentage 内。

当我开始从 Image1->Image2 滚动时,颜色逐渐淡化。但是当 Image2 停止时,背景颜色会立即跳到 Image3 中假定的颜色并进入 else 语句。

为了展示示例,这里是在 iPhone 7 模拟器上运行的 image1->image2 输出的颜色不透明度:

scrollView.contentSize.width =1125.0
scrollView.frame.size.width =375.0
maximumHorizontalOffset =750.0
currentHorizontalOffset =110.5
pageOffset = 0.5
currentImagePage = 0
percentageHorizontalOffset = 0.147333333333333
IN IF
withPercentage in IF = 0.294666666666667

...

scrollView.contentSize.width =1125.0
scrollView.frame.size.width =375.0
maximumHorizontalOffset =750.0
currentHorizontalOffset =269.0
pageOffset = 0.5
currentImagePage = 0
percentageHorizontalOffset = 0.358666666666667
IN IF
withPercentage in IF = 0.717333333333333

...

scrollView.contentSize.width =1125.0
scrollView.frame.size.width =375.0
maximumHorizontalOffset =750.0
currentHorizontalOffset =374.5
pageOffset = 0.5
currentImagePage = 0
percentageHorizontalOffset = 0.499333333333333
IN IF
withPercentage in IF = 0.998666666666667

scrollView.contentSize.width =1125.0
scrollView.frame.size.width =375.0
maximumHorizontalOffset =750.0
currentHorizontalOffset =375.0
pageOffset = 0.5
currentImagePage = 0
percentageHorizontalOffset = 0.5
IN ELSE
withPercentage in ELSE  = 0.0

这是我知道我的计算有误的地方,但我正在绞尽脑汁想办法实现这一目标。

最佳答案

很难准确阅读您的代码示例,因为某些变量/标识符未在示例文本中定义,例如百分比水平偏移

如果将 scrollViewDidScroll 函数的 else 子句中的行更改为:

    imagesCollectionView.backgroundColor = fadeFromColorToColor(fromColor: colorsArray[currentImagePage], toColor: colorsArray[currentImagePage], withPercentage: (percentageHorizontalOffset - pageOffset) * CGFloat(colorsArray.count - 1) ))

关于ios - 滚动到 CollectionView 中的上一张/下一张图像时,正确计算颜色不透明度偏移以更改背景颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41252049/

相关文章:

ios - 委托(delegate)有问题,我的委托(delegate)总是零,tvOS,swift 2.0

ios - AVCaptureSession addOutput 第二次运行需要很长时间

ios - 如何手动调用UITableView的delegate方法?

ios - 环球银行金融电信协会 : expand/collapse custom cell from UIswitch in the custom cell

ios - 为什么我们在 fetchRequest() 声明之前放置 @nonobjc 属性?

ios - ARKit图像识别——图像跟踪

ios - 从选定的 Collection View 单元格获取信息

iphone - uicollection View 可重用单元格图像在滚动时重新加载

ios - 将对象传递给多个深度级别的 "detailed" View Controller

ios - UINavigationController 堆栈中的阴影