Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ios Changing UIScrollView scrollbar color to different colors

How can we change color of UIScrollview's scroll indicator to something like blue, green etc.

I know we can change it to white, black. But other then these colors.

Many Thanks

like image 597
Mann Avatar asked Aug 17 '12 11:08

Mann


5 Answers

Unfortunately you can't, of course you can always roll your own. These are your options:

UIScrollViewIndicatorStyleDefault:

The default style of scroll indicator, which is black with a white border. This style is good against any content background.

UIScrollViewIndicatorStyleBlack:

A style of indicator which is black and smaller than the default style. This style is good against a white content background.

UIScrollViewIndicatorStyleWhite:

A style of indicator is white and smaller than the default style. This style is good against a black content background.

like image 144
Kaan Dedeoglu Avatar answered Oct 16 '22 07:10

Kaan Dedeoglu


Here's more safe Swift 3 method:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let verticalIndicator = scrollView.subviews.last as? UIImageView
    verticalIndicator?.backgroundColor = UIColor.green
}
like image 32
Andrey Gordeev Avatar answered Oct 16 '22 07:10

Andrey Gordeev


Both UIScrollView indicator are sub view of UIScrollView. So, we can access subview of UIScrollView and change the property of subview.

1 .Add UIScrollViewDelegate

@interface ViewController : UIViewController<UIScrollViewDelegate>
@end

2. Add scrollViewDidScroll in implementation section

-(void)scrollViewDidScroll:(UIScrollView *)scrollView1
{
    //get refrence of vertical indicator
    UIImageView *verticalIndicator = ((UIImageView *)[scrollView.subviews objectAtIndex:(scrollView.subviews.count-1)]);
    //set color to vertical indicator
    [verticalIndicator setBackgroundColor:[UIColor redColor]];


    //get refrence of horizontal indicator
    UIImageView *horizontalIndicator = ((UIImageView *)[scrollView.subviews objectAtIndex:(scrollView.subviews.count-2)]);
    //set color to horizontal indicator
    [horizontalIndicator setBackgroundColor:[UIColor blueColor]];
}

Note:- Because these indicator update every time when you scroll (means reset to default). SO, we put this code in scrollViewDidScroll delegate method.

enter image description hereDemo available on GitHub - https://github.com/developerinsider/UIScrollViewIndicatorColor

like image 11
Vineet Choudhary Avatar answered Oct 16 '22 07:10

Vineet Choudhary


Based on the answer of @Alex (https://stackoverflow.com/a/58415249/3876285), I'm posting just a little improvement to change the color of scroll indicators.

extension UIScrollView {

    var scrollIndicators: (horizontal: UIView?, vertical: UIView?) {

        guard self.subviews.count >= 2 else {
            return (horizontal: nil, vertical: nil)
        }

        func viewCanBeScrollIndicator(view: UIView) -> Bool {
            let viewClassName = NSStringFromClass(type(of: view))
            if viewClassName == "_UIScrollViewScrollIndicator" || viewClassName == "UIImageView" {
                return true
            }
            return false
        }

        let horizontalScrollViewIndicatorPosition = self.subviews.count - 2
        let verticalScrollViewIndicatorPosition = self.subviews.count - 1

        var horizontalScrollIndicator: UIView?
        var verticalScrollIndicator: UIView?

        let viewForHorizontalScrollViewIndicator = self.subviews[horizontalScrollViewIndicatorPosition]
        if viewCanBeScrollIndicator(view: viewForHorizontalScrollViewIndicator) {
            horizontalScrollIndicator = viewForHorizontalScrollViewIndicator.subviews[0]
        }

        let viewForVerticalScrollViewIndicator = self.subviews[verticalScrollViewIndicatorPosition]
        if viewCanBeScrollIndicator(view: viewForVerticalScrollViewIndicator) {
            verticalScrollIndicator = viewForVerticalScrollViewIndicator.subviews[0]
        }
        return (horizontal: horizontalScrollIndicator, vertical: verticalScrollIndicator)
    }

}

If you don't add .subviews[0], you will get the deeper view and when you try to change the color of the indicator, this will appear with a weird white effect. That's because there is another view in front of it:

enter image description here

By adding .subviews[0] to each indicator view, once you try to change the color by calling:

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
    DispatchQueue.main.async() {
        scrollView.scrollIndicators.vertical?.backgroundColor = UIColor.yourcolor
    }
}

You will access to the first view and change the color properly:

enter image description here

Kudos to @Alex who posted a great solution 👍

like image 10
j_gonfer Avatar answered Oct 16 '22 08:10

j_gonfer


in IOS 13

Try this one

func scrollViewDidScroll(_ scrollView: UIScrollView){


        if #available(iOS 13, *) {
            (scrollView.subviews[(scrollView.subviews.count - 1)].subviews[0]).backgroundColor = UIColor.themeColor(1.0) //verticalIndicator
            (scrollView.subviews[(scrollView.subviews.count - 2)].subviews[0]).backgroundColor = UIColor.themeColor(1.0) //horizontalIndicator
        } else {
            if let verticalIndicator: UIImageView = (scrollView.subviews[(scrollView.subviews.count - 1)] as? UIImageView) {
                verticalIndicator.backgroundColor = UIColor.themeColor(1.0)
            }

            if let horizontalIndicator: UIImageView = (scrollView.subviews[(scrollView.subviews.count - 2)] as? UIImageView) {
                horizontalIndicator.backgroundColor = UIColor.themeColor(1.0)
            }
        }
    }
like image 8
Jaydip Avatar answered Oct 16 '22 07:10

Jaydip