UIScrollview动画取决于内容偏移量

问题描述 投票:6回答:3

我正在使用水平的UIScrollView,并且我希望背景颜色过渡取决于内容偏移量的x值。

示例: UIScrollView的宽度为640px。当内容偏移等于0px时,背景色必须为红色。当内容偏移为320像素时,背景必须为黄色。但是最重​​要的部分是,当UIScrollview在0px和320px之间时,背景颜色必须在红色和黄色之间。

提示:从搜索向左滑动时,iOS的twitter应用程序具有相同的动画。导航上的标签略微消失。

ios xcode animation uiscrollview contentoffset
3个回答
18
投票

您需要根据偏移百分比创建颜色。

在这种颜色之间进行转换的最简单方法是使用HSB颜色空间。

而且,这不是动画。滚动视图将为您提供“动画”效果。您只需要在每次滚动视图更改时设置颜色。

在委托方法中,您可以执行以下操作。

编辑以使其更灵活

// this just calculates the percentages now and passes it off to another method.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    // vertical
    CGFloat maximumVerticalOffset = scrollView.contentSize.height - CGRectGetHeight(scrollView.frame);
    CGFloat currentVerticalOffset = scrollView.contentOffset.y;

    // horizontal
    CGFloat maximumHorizontalOffset = scrollView.contentSize.width - CGRectGetWidth(scrollView.frame);
    CGFloat currentHorizontalOffset = scrollView.contentOffset.x;

    // percentages
    CGFloat percentageHorizontalOffset = currentHorizontalOffset / maximumHorizontalOffset;
    CGFloat percentageVerticalOffset = currentVerticalOffset / maximumVerticalOffset;

    [self scrollView:scrollView didScrollToPercentageOffset:CGPointMake(percentageHorizontalOffset, percentageVerticalOffset)];
}

// this just gets the percentage offset.
// 0,0 = no scroll
// 1,1 = maximum scroll
- (void)scrollView:(UIScrollView *)scrollView didScrollToPercentageOffset:(CGPoint)percentageOffset
{
    UIColor *HSBColor = [self HSBColorForOffsetPercentage:percentageOffset.x];

    UIColor *RGBColor = [self RGBColorForOffsetPercentage:percentageOffset.x];
}

// HSB color just using Hue
- (UIColor *)HSBColorForOffsetPercentage:(CGFloat)percentage
{
    CGFloat minColorHue = 0.0;
    CGFloat maxColorHue = 0.2; // this is a guess for the yellow hue.

    CGFloat actualHue = (maxColorHue - minColorHue) * percentage + minColorHue;

    // change these values to get the colours you want.
    // I find reducing the saturation to 0.8 ish gives nicer colours.
    return [UIColor colorWithHue:actualHue saturation:1.0 brightness:1.0 alpha:1.0];
}

// RGB color using all R, G, B values
- (UIColor *)RGBColorForOffsetPercentage:(CGFloat)percentage
{
    // RGB 1, 0, 0 = red
    CGFloat minColorRed = 1.0;
    CGFloat minColorGreen = 0.0;
    CGFloat minColorBlue = 0.0;

    // RGB 1, 1, 0 = yellow
    CGFloat maxColorRed = 1.0;
    CGFloat maxColorGreen = 1.0;
    CGFloat maxColorBlue = 0.0;

    // if you have specific beginning and end RGB values then set these to min and max respectively.
    // it should even work if the min value is greater than the max value.

    CGFloat actualRed = (maxColorRed - minColorRed) * percentage + minColorRed;
    CGFloat actualGreen = (maxColorGreen - minColorGreen) * percentage + minColorGreen;
    CGFloat actualBlue = (maxColorBlue - minColorBlue) * percentage + minColorBlue;

    return [UIColor colorWithRed:actualRed green:actualGreen blue:actualBlue alpha:1.0];
}

我不知道RGB方法将如何对中间值执行。中间可能会变成棕色,等等...但是您可以玩耍。

这应该使您了解如何使用滚动视图作为控制它的方式来动画ANYTHING

使用此方法,您可以控制不透明度,大小,旋转度,字体大小等。您甚至可以结合多种方式(就像我对RGB所做的那样。


0
投票

受到@Fogmeister的回答的启发,我迅速将各个部分放在一起。

extension UIColor {
    static func color(between start: UIColor, and end: UIColor, percentage: CGFloat) -> UIColor {
        let startRGB = start.rgba
        let stopRGB = end.rgba

        let red: CGFloat = (stopRGB.red - startRGB.red) * percentage + startRGB.red;
        let green: CGFloat = (stopRGB.green - startRGB.green) * percentage + startRGB.green;
        let blue: CGFloat = (stopRGB.blue - startRGB.blue) * percentage + startRGB.blue;
        let alpha: CGFloat = (stopRGB.alpha - startRGB.alpha) * percentage + startRGB.alpha;

        return UIColor(red: red, green: green, blue: blue, alpha: alpha)
    }

    var rgba: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
        var red: CGFloat = 0
        var green: CGFloat = 0
        var blue: CGFloat = 0
        var alpha: CGFloat = 0
        getRed(&red, green: &green, blue: &blue, alpha: &alpha)
        return (red, green, blue, alpha)
    }
}

现在您可以执行以下操作:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let offset = scrollView.contentOffset.y
    let scrolledDistance = offset + scrollView.contentInset.top
    let progress = max(0, min(1, scrolledDistance / scrollView.contentSize.height))

    someLabel.textColor = UIColor.color(between: .red, and: .green, percentage: progress)
}

-3
投票

在您的scrollView委托中,尝试如下操作:

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    CGPoint a = self.mainScrollView.contentOffset;
    if(a.x >= 320){
        [UIView animateWithDuration:0.5 animations:^{
            [self.view setBackgroundColor:[UIColor redColor]];
        }];
    }
    else{
        [UIView animateWithDuration:0.5 animations:^{
            [self.view setBackgroundColor:[UIColor yellowColor]];
        }];
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.