tutorial source how example data collection ios swift uicollectionview swift3

ios - source - uicollectionview swift 3 programmatically



¿Cómo desaparecer entre diferentes colores de fondo de un `UICollectionView` cuando el usuario se desplaza a una página diferente? (3)

La parte difícil es encontrar un color correspondiente a cada imagen. Una vez usé TDImageColors que funcionó bien: https://www.cocoacontrols.com/controls/tdimagecolors

Entonces, todo lo que tienes que hacer es pasar de un color a otro. Como en @Tonton respuesta.

Intento replicar el menú de listados de eBay en su aplicación de iOS, en el que los usuarios pueden desplazarse por diferentes imágenes de una lista. Noté que el color de fondo es un color sólido que reproduce los colores envolventes del fondo en cada imagen.

A medida que me desplazo por una imagen diferente (página diferente) con un fondo envolvente diferente, el fondo real de UICollectionView cambia para reflejarlo de alguna manera.

Esto es lo que quiero decir:

Como puede ver en la primera imagen, el fondo es de color claro, algo parecido al fondo de la imagen. A medida que avanzo hasta la mitad de la segunda imagen, el fondo se oscurece.

Finalmente:

Mi configuración es similar:

Usando DominantColor , pude establecer el color de fondo de UICollectionView con el color dominante de cada UIImage . A medida que el usuario se desplaza a mitad de camino entre la primera y la segunda página, el color de fondo de UICollectionView se establece en el color dominante de la segunda página de 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] }) } }

Sin embargo, estoy teniendo dificultades para hacer una transición lenta del color de fondo actual al siguiente color de fondo tan pronto como el usuario comience a desplazarse, como se ve en la segunda imagen de arriba.

La forma en que se implementa actualmente como se scrollViewDidScroll arriba en scrollViewDidScroll , comienza a desvanecerse en el siguiente color cuando la página se desplaza a mitad de camino entre la página siguiente, y con una animación de 1 segundo , se convertirá en ese color en 1 segundo, independientemente de si la siguiente página está a la mitad o totalmente mostrada.

¿Cómo puedo conseguir esto?


Si el cambio de color necesita estar sincronizado con el desplazamiento, es decir, cambiando gradualmente el color, probablemente desee los cambios en scrollViewDidScroll utilizando la vista de desplazamiento desde su colección.

Al obtener el color de la imagen de fondo (quizás usando la respuesta de Mike JS Choi), puede comparar sus diferencias. Usando el valor de desplazamiento de 0 a 1, puede cambiar el color gradualmente.

Usa alguna variable local para que el método sepa cuál es tu imagen actual

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 }

Por lo tanto, tendrá que descubrir cómo almacenar su imagen actual y obtener la siguiente imagen (que podría estar desplazando hacia adelante y hacia atrás), y luego usarla dentro del método scrollViewDidScroll. glhf fam


Utilizando la respuesta de Fogmeister en obj-C y la conversión del usuario3344977 a Swift, así como la guía de Tonton , se me ocurrió la siguiente solución:

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

Ahora, cuando el usuario comienza a desplazarse a la página siguiente / anterior, el color de fondo cambiará lentamente debido al cambio de color alfa en el percentageHorizontalOffset Disparo percentageHorizontalOffset .

Gracias a todos los mencionados!