xcode UIScrollview 动画取决于内容偏移

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26159012/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 05:46:05  来源:igfitidea点击:

UIScrollview animation depending on content offset

iosxcodeanimationuiscrollviewcontentoffset

提问by Berendschot

I'm using a horizontal UIScrollView, and I want a background color transition depending on the x value of the content offset.

我正在使用水平 UIScrollView,并且我想要根据内容偏移量的 x 值进行背景颜色转换。

Example:The width of UIScrollView is 640px. When the content offset is equal to 0px, the background color must be red. When the content offset is 320 px, the background must be yellow. But the most important part is, when the UIScrollview is between 0px and 320px the background color must be between red and yellow.

示例:UIScrollView 的宽度为 640px。当 content offset 等于 0px 时,背景颜色必须是红色。当内容偏移量为 320 px 时,背景必须为黄色。但最重要的是,当 UIScrollview 介于 0px 和 320px 之间时,背景颜色必须介于红色和黄色之间。

Hint: The twitter app for iOS has the same animation when you swipe to the left from a search. The the label on the navigation slightly disappears.

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

回答by Fogmeister

You need to create the colour depending on the offset percentage.

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

The easiest way to create a shift between colours like this is to use the HSB colour space.

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

Also, this isn't an animation. The "animation" effect is given to you by the scrollview. You just need to set the colour every time the scroll view changes.

另外,这不是动画。“动画”效果由滚动视图提供给您。每次滚动视图更改时,您只需要设置颜色。

In the delegate method you could do something like this.

在委托方法中,你可以做这样的事情。

Edit to make more flexible

编辑以使其更灵活

// 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];
}

I don't know how the RGB method will perform on mid values. It may go brown in the middle etc... but you can play around.

我不知道 RGB 方法在中间值上的表现如何。它可能在中间变成棕色等等......但你可以玩。

This should give you an idea of how to animate ANYTHINGusing the scroll view as a way to control it.

这应该让您了解如何使用滚动视图为任何东西设置动画作为控制它的方式。

Using this method you can control the opacity, size, rotation, font size, etc... You can even combine multiple things (like I did with RGB).

使用这种方法,您可以控制不透明度、大小、旋转、字体大小等……您甚至可以组合多种东西(就像我对 RGB 所做的那样)。

回答by Apoc

Inspired by @Fogmeister's answer I put the pieces together in swift.

受到@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)
    }
}

Now you can do something like this:

现在你可以做这样的事情:

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 = .color(between: .red, and: .green, percentage: progress)
}

Warning:This implementation will trigger swiftlints large_tuplerule. But you can disable, simply add ' - large_tuple' into disabled_rulessection.

警告:此实现将触发 swiftlints large_tuple规则。但是您可以禁用,只需将“- large_tuple”添加到disabled_rules部分。

回答by Istvan

In your scrollView delegate try something like this:

在您的 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]];
        }];
    }
}