Make background color change during scroll
Asked Answered
M

5

3

I have an onboarding section of my app with 4 pages the users scrolls through horizontally to get an idea of how to use the app (standard). I want the background color to transition as the user scrolls from page to page.

I have the 4 RGB values I want to use:

241,170,170

170,201,241

188,170,241

241,199,170

I know I must use the scroll view delegate + content offset to change the uicolor values, but im not sure how I get it to go to the specific colors ive selected.

Any help would be greatly appreciated. Any implementation would do, swift or objective-c

thanks

Moncton answered 13/4, 2016 at 5:13 Comment(1)
put those in array and on scrolling select random color...Traceytrachea
M
6

For anyone interested. This is the solution. I combined some answers I found on stack and adapted it to use 4 colors

- (void)scrollViewDidScroll:(UIScrollView *)scrollView  {
CGFloat pageWidth = self.scrollView.frame.size.width;
float fractionalPage = self.scrollView.contentOffset.x / pageWidth;
NSInteger page = lround(fractionalPage);
self.pageControl.currentPage = page;

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

// percentages
CGFloat percentageHorizontalOffset = currentHorizontalOffset / maximumHorizontalOffset;

NSLog(@"content offfset: %f", percentageHorizontalOffset);

if (percentageHorizontalOffset < 0.333333) {
    self.view.backgroundColor = [self fadeFromColor:self.colorArray[0] toColor:self.colorArray[1] withPercentage:percentageHorizontalOffset*3];
} else if (percentageHorizontalOffset >= 0.333333 && percentageHorizontalOffset < 0.666667) {
    self.view.backgroundColor = [self fadeFromColor:self.colorArray[1] toColor:self.colorArray[2] withPercentage:(percentageHorizontalOffset-0.333333)*3];
} else if (percentageHorizontalOffset >= 0.666667) {
    self.view.backgroundColor = [self fadeFromColor:self.colorArray[2] toColor:self.colorArray[3] withPercentage:(percentageHorizontalOffset-0.666667)*3];
}
}

- (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];
}    
Moncton answered 13/4, 2016 at 13:11 Comment(2)
this is exactly what I'm looking to do, I'm doing something similar here: #41215706 can you assist?Sauternes
When i'm trying your solution, I got everyTime the same color (In Swift)Unlearn
E
2

To enable paging in scrollview you have to enable the paging property of scrollview first from attribute inspector.

As per your requirement you have 4 pages. so your scrollview content size will be like scrollviewWidth * 4

Put this code in viewDidLoad

[self.scrollVw setContentSize:CGSizeMake(self.scrollVw.frame.size.width * 4,0)];

Then take an array to store color values something like below.

 arrColor = [[NSMutableArray alloc]init];

 [arrColor addObject:[UIColor colorWithRed:(241.0f/255.0f) green:(170.0f/255.0f) blue:(170.0f/255.0f) alpha:1.0f]];

 [arrColor addObject:[UIColor colorWithRed:(170.0f/255.0f) green:(201.0f/255.0f) blue:(241/255.0f) alpha:1.0f]];
 [arrColor addObject:[UIColor colorWithRed:(188.0f/255.0f) green:(170.0f/255.0f) blue:(241.0f/255.0f) alpha:1.0f]];
 [arrColor addObject:[UIColor colorWithRed:(241.0f/255.0f) green:(199.0f/255.0f) blue:(170.0f/255.0f) alpha:1.0f]];

 [self.scrollVw setBackgroundColor:[arrColor objectAtIndex:0]]; //this is for first time to display first color when scrollview is load. you can avoid this by directly setting color from UI

Scrollview delegate method code.

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
 [self.scrollVw setBackgroundColor:[arrColor objectAtIndex:currentPage]]; //currentPage overhere is simple int variable which i had incremented and decremented its values based on current offset of scrollview. Also currentPage value should not be > 4.
}

Hope this will help you out. Happy coding :)

Eckmann answered 13/4, 2016 at 6:45 Comment(1)
Thanks for the response but this just changes the color when I get to the next page. Im looking to transition from color to color. (like an animation, fading into the next color). As the user is scrolling, not when he gets to the next page.Moncton
K
2
    var currPage = 0
    let colors: [UIColor] = [.red, .blue, .green, .yellow, .purple, .orange]

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        // for horizontal scrolling
        let progress = scrollView.contentOffset.x / scrollView.bounds.width
        let page = Int(progress)
        if currPage != page { currPage = page }
        let nextPage = Int(progress + 1)
        let prog = 1 - (CGFloat(Int(progress + 1)) - progress)
        print("\(currPage) \(nextPage) \(prog)")
        if currPage >= 0 && currPage < colors.count && nextPage >= 0 && nextPage < colors.count {
            let interColor = colorBetween(col1: colors[currPage], col2: colors[nextPage], percent: prog)
            scrollView.backgroundColor = interColor.withAlphaComponent(0.5)
        }
    }

    // calculates intermediate color, percent should in between 0.0 - 1.0
    func colorBetween(col1: UIColor, col2: UIColor, percent: CGFloat) -> UIColor {
        let c1 = CIColor(color: col1)
        let c2 = CIColor(color: col2)
        
        let alpha = (c2.alpha - c1.alpha) * percent + c1.alpha
        let red = (c2.red - c1.red) * percent + c1.red
        let blue = (c2.blue - c1.blue) * percent + c1.blue
        let green = (c2.green - c1.green) * percent + c1.green
        
        return UIColor(red: red, green: green, blue: blue, alpha: alpha)
    }

Edit: Another type of calculation

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let progress = scrollView.contentOffset.x / scrollView.bounds.width
    let page = CGFloat(round(progress))
    let move = progress - page
    let nextPage = Int(move < 0 ? page + floor(move) : page + ceil(move))
    let currPage = Int(page)
    print(currPage, nextPage)
    if currPage >= 0, currPage < colors.count, nextPage >= 0, nextPage < colors.count {
        let interColor = colorBetween(col1: colors[currPage], col2: colors[nextPage], percent: abs(move))
        scrollView.backgroundColor = interColor.withAlphaComponent(0.5)
    }
}
Kathlyn answered 10/5, 2019 at 7:13 Comment(0)
T
1

Set scroll view delegate and use below method

//This method is called when scroll view ends scrolling
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self updateColor];
}
Tripura answered 13/4, 2016 at 5:21 Comment(0)
L
0

You can use a delegate based on your need. If you when to change the background colour simultaneously when when scrolling you should use scrollViewDidScroll method where you can get the contentOffSet dynamically and change the background colour. If you wants it after completing the scroll you can use as @Chetan said

Lingonberry answered 13/4, 2016 at 6:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.