如果标题含糊不清,我很抱歉,但目前我有UICollectionView
张图片。我最近发现了一种使用DominantColor找到UIImage
的主色的方法。有了这个,我试图改变UICollectionView
的背景颜色,因为用户从一个UIImage
单元格滚动到下一个单元格,即背景颜色将慢慢从imageX的主色渐变到imageX + 1的主导色。
但是,我已经花了好几天时间而且在更改UICollectionView
的背景颜色不透明度时非常困难,因为单元格开始滚动到下一个/上一张图像。
我的用户界面:
背景代码:
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,因为该问题涉及2个静态页面,而我正在处理{{1}页面,所以我不得不重新计算colorsArray.count - 1
。
我遇到的问题在pageOffset
withPercentage
{。}}内。
当我从Image1-&gt; Image2开始滚动时,颜色会逐渐消失。但是,一旦Image2停止,背景颜色立即跳转到Image3中的颜色,并输入scrollViewDidScroll
语句。
举例说明,这是在iPhone 7模拟器上运行的image1-&gt; image2输出的颜色不透明度:
else
这是我知道我的计算已经完成的地方,但是我正在努力实现这一目标。
答案 0 :(得分:0)
很难准确读取您的代码示例,因为某些变量/标识符未在示例文本中定义,例如percentageHorizontalOffset
如果将scrollViewDidScroll func的else子句中的行更改为:
,该怎么办?var color1 = prompt("Enter first color: yellow, red or blue");
var color2 = prompt("Enter second color: yellow, red or blue");
if (color1 == "yellow" && color2 == "yellow"){
console.log("mixing of these two colors makes yellow");
}
if (color1 == "red" && color2 == "red"){
console.log("mixing of these two colors makes red");
}
if (color1 == "blue" && color2 == "blue"){
console.log("mixing of these two colors makes blue");
}
if (color1 == "yellow" && color2 == "red" || color1 == "red" && color2 == "yellow"){
console.log("mixing of these two colors makes orange");
}
if (color1 == "yellow" && color2 == "blue" || color1 == "blue" && color2 == "yellow"){
console.log("mixing of these two colors makes green");
}
if (color1 == "blue" && color2 == "red" || color1 == "red" && color2 == "blue"){
console.log("mixing of these two colors makes purple");
}
答案 1 :(得分:0)
在fadeFromColorToColor
中,如果百分比为负数,则交换toColor
和fromColor
并转为percent
为正。
答案 2 :(得分:0)
这里有一些准备粘贴到游乐场的代码。打开助理编辑器以使用集合视图。那是你在找什么?
import UIKit
import PlaygroundSupport
extension UIColor {
func components() -> (r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) {
var r: CGFloat = 0.0
var g: CGFloat = 0.0
var b: CGFloat = 0.0
var a: CGFloat = 0.0
getRed(&r, green: &g, blue: &b, alpha: &a)
return (r, g, b, a)
}
}
class Controller: UICollectionViewController {
// some test data instead of images:
let pages = [#colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1), #colorLiteral(red: 0.2196078449, green: 0.007843137719, blue: 0.8549019694, alpha: 1), #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1), #colorLiteral(red: 0.9372549057, green: 0.3490196168, blue: 0.1921568662, alpha: 1), #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1), #colorLiteral(red: 0.4666666687, green: 0.7647058964, blue: 0.2666666806, alpha: 1)]
// these should be your significant colors from the images:
let colorsArray = [#colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1), #colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1), #colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1), #colorLiteral(red: 0.9568627477, green: 0.6588235497, blue: 0.5450980663, alpha: 1), #colorLiteral(red: 0.9764705896, green: 0.850980401, blue: 0.5490196347, alpha: 1), #colorLiteral(red: 0.721568644, green: 0.8862745166, blue: 0.5921568871, alpha: 1)]
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
collectionView?.contentInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return pages.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
cell.backgroundColor = pages[indexPath.item]
return cell
}
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
let currentHorizontalOffset = collectionView!.contentOffset.x + collectionView!.contentInset.left
let pageWidth = scrollView.bounds.size.width
let page = Int(max(0, floor(currentHorizontalOffset / pageWidth)))
// Don't change the background color when scrolling past the last page:
guard page < pages.count - 1 else {
return
}
let partialPageVisibleWidth = currentHorizontalOffset - CGFloat(page) * pageWidth
let ratio = max(0, partialPageVisibleWidth / pageWidth)
let leftColor = colorsArray[page]
let rightColor = colorsArray[page + 1]
scrollView.backgroundColor = blend(leftColor, rightColor, ratio: ratio)
}
/**
Blends two colors by the given ratio
- returns: `lhs` if t == 0; `rhs` if t == 1; otherwise a blend of `lhs` and `rhs` by using a linear interpolation function
*/
func blend(_ lhs: UIColor, _ rhs: UIColor, ratio t: CGFloat) -> UIColor
{
let (r1, g1, b1, a1) = lhs.components()
let (r2, g2, b2, a2) = rhs.components()
// Interpolation function:
func f(_ from: CGFloat, _ to: CGFloat) -> CGFloat {
return from * (1 - t) + to * t
}
// create a new color by interpolating two colors:
return UIColor(
red: f(r1, r2),
green: f(g1, g2),
blue: f(b1, b2),
alpha: f(a2, a2)
)
}
}
// Test code:
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = CGSize(width: 280, height: 400)
layout.minimumLineSpacing = 40
let controller = Controller(collectionViewLayout: layout)
controller.view.frame = CGRect(x: 0, y: 0, width: 320, height: 480)
PlaygroundPage.current.liveView = controller.view