根据 UIScrollView 的 contentOffset 改变颜色

Posted

技术标签:

【中文标题】根据 UIScrollView 的 contentOffset 改变颜色【英文标题】:Changing between colors based on UIScrollView's contentOffset 【发布时间】:2015-08-27 22:33:18 【问题描述】:

我有一个宽度为960 的水平UIScrollView,足以容纳3 个UIViewController 视图。

每个视图都只有一个背景颜色。第一个是粉红色,第二个是蓝色,第三个是绿色。

我想在用户滚动时将可见颜色混合/混合/淡化。

因此,如果您从第 1 页(粉红色)滚动到第 2 页(蓝色),在用户完全滑动到最终到达最终蓝色之前,会有某种类型的粉红色和蓝色混合/混合/淡入淡出第二页。

我发现了一个关于我正在尝试做什么的问题,我已经实施了可以在这里找到的答案:https://***.com/a/26159561/3344977

这个答案确实有效,我唯一的问题是这个答案只是为使用 2 个屏幕/颜色而创建的,而我有 3 个屏幕/颜色。

我了解此答案的基础知识,并且它依赖于 UIScrollView 的 contentOffset.x 来计算当前颜色,但除此之外,我的数学很糟糕,这让我无法弄清楚如何修改它以使用第三种颜色。

【问题讨论】:

在这里回答***.com/a/56072529/4568747 【参考方案1】:

Fogmeister 发布的答案完美!

这是翻译成 Swift 的相同答案:

// this just gets the percentage offset.
// 0,0 = no scroll
// 1,1 = maximum scroll

func scrollViewdidScrollToPercentageOffset(scrollView: UIScrollView, percentageOffset: CGPoint) 
    // get your colours to fade between
    var colors = [UIColor.redColor(), UIColor.blueColor(), UIColor.greenColor()]

    // choose the colours to fade between based on the percentage.
    if (percentageOffset.x < 0.5) 
        // multiply the offset by 2 because we want 0.5 to be 100%
        scrollView.backgroundColor = fadeFromColor(colors[0], colors[1], percentageOffset.x*2)
     else 
        // minus 0.5 because we want 0.5 to be 0%
        scrollView.backgroundColor = fadeFromColor(colors[1], colors[2], (percentageOffset.x - 0.5)*2)
    


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

    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
    var red = (toRed - fromRed) * withPercentage + fromRed
    var green = (toGreen - fromGreen) * withPercentage + fromGreen
    var blue = (toBlue - fromBlue) * withPercentage + fromBlue
    var alpha = (toAlpha - fromAlpha) * withPercentage + fromAlpha

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

【讨论】:

我现在在我的应用程序中使用此代码,但是当您提到的屏幕超过 2 个时遇到问题。您是如何设法解决它的,因为偏移量 0.5 不意味着仅适用于 2 个屏幕? 感谢您转换为 Swift。节省了几分钟:)【参考方案2】:

是的,您绝对可以将它用于三种颜色(或更多)。

对于三种颜色(例如红色、绿色、蓝色),红色为 0.0,绿色为 0.5,蓝色为 1.0。所以你只需要在两个淡入淡出之间分离方法(红绿和绿蓝将分别计算)。

在获得方法之前使用我的代码...

// this just gets the percentage offset.
// 0,0 = no scroll
// 1,1 = maximum scroll
- (void)scrollView:(UIScrollView *)scrollView didScrollToPercentageOffset:(CGPoint)percentageOffset

    // get your colours to fade between
    NSArray *colours = @[[UIColor redColor], [UIColor yellowColor], [UIColor purpleColor]];

    // choose the colours to fade between based on the percentage.
    if (percentageOffset.x < 0.5) 
        // multiply the offset by 2 because we want 0.5 to be 100%
        self.backgroundColor = [self fadeFromColor:colours[0] toColor:colours[1] withPercentage:percentageOffset.x*2];
     else 
        // minus 0.5 because we want 0.5 to be 0%
        self.backgroundColor = [self fadeFromColor:colours[1] toColor:colours[2] withPercentage:(percentageOffset.x-0.5)*2];
    


// this is a more generic method to fade between two colours
// it allows the colours to be passed in as parameters
- (UIColor *)fadeFromColor:(UIColor *)fromColor toColor:(UIColor *)toColor withPercentage:(CGFloat)percentage

    // get the RGBA values from the colours
    CGFloat fromRed, fromGreen, fromBlue, fromAlpha;
    [fromColor getRed:&fromRed green:&fromGreen blue:&fromBlue alpha:&fromAlpha];

    CGFloat toRed, toGreen, toBlue, toAlpha;
    [toColor getRed:&toRed green:&toGreen blue:&toBlue alpha:&toAlpha];

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

    // return the fade colour
    return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];

这将在所有三种颜色之间很好地褪色。

您可以为此添加更多颜色并更改其拆分百分比的方式。

【讨论】:

【参考方案3】:

这是使用 Swift 4.2 的任意数量颜色(或 UICollectionView 中的页面)的答案:

func scrollViewDidScroll(_ scrollView: UIScrollView) 
    let maximumOffset = scrollView.contentSize.width - scrollView.frame.width
    let currentOffset = scrollView.contentOffset.x
    let offsetPercentage = currentOffset / maximumOffset
    let sharesCount = CGFloat(colorsArray.count - 1)

    var currentShareIndex: CGFloat = 0
    switch offsetPercentage 
    case  ..<0:
        currentShareIndex = 0
    case 0..<1:
        currentShareIndex = floor(offsetPercentage * sharesCount)
    case 1... :
        currentShareIndex = sharesCount - 1
    default: break
    

    let firstColorIndex = Int(currentShareIndex)
    let secondColorIndex = Int(currentShareIndex) + 1
    let colorPercentage = (offsetPercentage - currentShareIndex / sharesCount) * sharesCount

    scrollView.backgroundColor = UIColor.fade(from: colorsArray[firstColorIndex], to: colorsArray[secondColorIndex], with: colorPercentage)

【讨论】:

以上是关于根据 UIScrollView 的 contentOffset 改变颜色的主要内容,如果未能解决你的问题,请参考以下文章

uiscrollview无法滚动到底部

更改 UIScrollVIew Content Inset 触发 scrollViewDidScroll

根据 UITableView 调整 UIScrollView 高度

contentOffsetcontentSize和contentInset

代码;根据内容自动设置 UIScrollView 的高度

根据 UIScrollView 的 contentOffset 改变颜色