I'm trying to replicate eBay's listing menu on their iOS app in which users can scroll through different images of a listing. I noticed that the background color is a solid color that replicates the surround colors of the background in each image.
As I scroll through a different image (different page) with a different surround background, the actual background of the UICollectionView
changes to somehow reflect it.
Here's what I mean:
As you can see in the first picture, the background is a light color, somewhat resembling the image's background. As I scroll halfway to the 2nd picture, the background turns darker.
Finally:
My setup is similar:
Using DominantColor, I was able to set the UICollectionView
's background color with each UIImage
's dominant color. As the user scrolls half-way between the first and second page, the UICollectionView
background color is set the 2nd page UIImage
's dominant color.
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]
})
}
}
However, I'm having a difficult time on how to slowly transition from the current background color to the next background color as soon as the user starts scrolling, as seen in the 2nd picture above.
The way it is currently implemented as above in scrollViewDidScroll
, it starts to fade into the next color when the page is half-way scrolled between the next page, and with a 1 second animation, it will become that color within 1 second, regardless of if the next page is half-way or fully shown.
How can I achieve this?
The tricky part is to find a color corresponding to each picture. I once used TDImageColors which worked just fine : https://www.cocoacontrols.com/controls/tdimagecolors
Then all you have to do is transition from one color to another. As in @Tonton answer.
If the change of colour needs to be in sync with the scroll, ie, gradually changing the colour, you would probably want to the changes in scrollViewDidScroll using the scrollview from your collectionView
By getting the 2 background image colour (perhaps using Mike JS Choi's answer), you can compare their differences. Using the scroll value from 0 to 1, you can change the colour gradually.
Use some local variable to let the method know what is your current image
So you will have to figure out how to store your current image is and getting the next image (which you could be scrolling forwards and back), then use those within the scrollViewDidScroll method. glhf fam
Using Fogmeister's answer in obj-C and user3344977's nicely conversion of it to Swift, as well as Tonton's guidance, I came up with the solution:
Now, when the user starts scrolling to the next/prev page, the background color will slowly change due to color alpha change in
percentageHorizontalOffset
.Thanks to all mentioned!