用户滚动到不同页面时如何在“UICollectionView”的不同背景颜色之间淡入淡出?

我试图在他们的iOS应用上复制eBay的列表菜单,用户可以在列表中滚动不同的图片。 我注意到,背景颜色是一种纯色,可以在每张图像中复制背景的环绕颜色。

当我用不同的环绕声背景滚动不同的图像(不同的页面)时, UICollectionView的实际背景会以某种方式反映出来。

这是我的意思:

在这里输入图像说明 在这里输入图像说明

正如您在第一张图片中看到的那样,背景是浅色,有点类似于图像的背景。 当我滚动到第二张照片时,背景变暗。

最后:

在这里输入图像说明

我的设置是类似的:

在这里输入图像说明

使用DominantColor ,我能够设置UICollectionView的背景颜色与每个UIImage的主色调。 当用户在第一页和第二页之间中途滚动时, UICollectionView背景色被设置为第二页UIImage的主色。

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as UICollectionViewCell let frame: CGRect = CGRect(x: 0, y: 0, width: imagesView.frame.size.width, height: imagesView.frame.size.height) let subView: UIImageView = UIImageView(frame: frame) subView.image = imagesArray[indexPath.row].image subView.contentMode = UIViewContentMode.scaleAspectFit if colorsArray.count > 0 { // Set background dominant color of first image collectionView.backgroundColor = colorsArray[0] } cell.addSubview(subView) return cell } func scrollViewDidScroll(_ scrollView: UIScrollView) { let scrollValue = (scrollView.contentOffset.x / UIScreen.main.bounds.width) let pageWidth: CGFloat = imagesCollectionView.bounds.size.width let currentPage: Int = Int( floor( (imagesCollectionView.contentOffset.x - pageWidth / 2) / pageWidth) + 1) if scrollValue != 1 { UIView.animate(withDuration: 1, animations: { self.imagesCollectionView.backgroundColor = self.colorsArray[currentPage] }) } else { UIView.animate(withDuration: 1, animations: { self.imagesCollectionView.backgroundColor = self.colorsArray[currentPage] }) } } 

但是,在用户开始滚动时,我很难从当前的背景颜色慢慢转换到下一个背景颜色,如上面的第二张图片所示。

目前在scrollViewDidScroll如上实现的方式,当页面在下一页之间中途滚动时,它开始淡入下一个颜色,并且在1秒钟的animation中,它将在1秒内变成该颜色,而不pipe如果下一页是中途或完全显示。

我怎样才能做到这一点?

通过使用Fogmeister的obj-C和user3344977将其很好地转换成Swift以及Tonton的指导,我提出了这个解决scheme:

 func scrollViewDidScroll(_ scrollView: UIScrollView) { let pageWidth: CGFloat = imagesCollectionView.bounds.size.width let currentPage: Int = Int( floor( (imagesCollectionView.contentOffset.x - pageWidth / 2) / pageWidth) + 1) let maximumHorizontalOffset: CGFloat = scrollView.contentSize.width - scrollView.frame.size.width let currentHorizontalOffset: CGFloat = scrollView.contentOffset.x let percentageHorizontalOffset: CGFloat = currentHorizontalOffset / maximumHorizontalOffset if percentageHorizontalOffset < 0.5 { imagesCollectionView.backgroundColor = fadeFromColor(fromColor: colorsArray[currentPage], toColor: colorsArray[currentPage + 1], withPercentage: percentageHorizontalOffset) } else { imagesCollectionView.backgroundColor = fadeFromColor(fromColor: colorsArray[currentPage - 1], toColor: colorsArray[currentPage], withPercentage: percentageHorizontalOffset) } } func fadeFromColor(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) } 

现在,当用户开始滚动到下一个/ prev页面时,由于percentageHorizontalOffset颜色alpha变化,背景颜色将缓慢变化。

感谢所有提到!

如果颜色的变化需要与滚动同步,即逐渐改变颜色,则可能需要使用scrollViewDidScroll中的滚动视图对collectionView进行更改

通过获得2背景图像的颜色(也许使用Mike JS Choi的答案),你可以比较他们的差异。 使用从0到1的滚动值,可以逐渐改变颜色。

使用一些局部variables让方法知道你当前的图像

 func scrollViewDidScroll(_ scrollView: UIScrollView) { let scrollValue = (scrollView.contentOffset.x / UIScreen.main.bounds.width) - 1 guard let nextColor: UIColor? = getBackgroundColor(from: nextImage) else { return } let currentImage = getBackgroundColor(from: currentImage) let currentIndex = pageControl.currentPage if scrollValue != 0 { backgroundColor = colorDifference(current: currentColor, next: nextColor, transitionValue: abs(scrollValue)) } else { backgroundColor = nextColor } } func colorDifference(current: UIColor, next: UIColor, transitionValue: Int) -> UIColor { var currentRed: Float = 0 var currentGreen: Float = 0 var currentBlue: Float = 0 var currentAlpha: Float = 0 current.getRed(&currentRed, green: &currentGreen, blue: &currentBlue, alpha: &currentAlpha) var nextRed: Float = 0 var nextGreen: Float = 0 var nextBlue: Float = 0 var nextAlpha: Float = 0 next.getRed(&nextRed, green: &nextGreen, blue: &nextBlue, alpha: &nextAlpha) let finalRed = (nextRed - currentRed) * transitionValue let finalGreen = (nextGreen - currentGreen) * transitionValue let finalBlue = (nextBlue - currentBlue) * transitionValue let finalAlpha = (nextAlpha - currentAlpha) * transitionValue let finalColor = UIColor(colorLiteralRed: finalRed, green: finalGreen, blue: finalBlue, alpha: finalAlpha) return finalColor } 

所以你将不得不弄清楚如何存储你当前的图像,并获得下一个图像(你可以向前和向后滚动),然后使用scrollViewDidScroll方法中的图像。 glhf fam

棘手的部分是find与每张照片对应的颜色。 我曾经使用TDImageColors工作得很好: https ://www.cocoacontrols.com/controls/tdimagecolors

那么你所要做的就是从一种颜色转换到另一种颜色。 正如@Tonton的答案。