【问题标题】:ios Changing UIScrollView scrollbar color to different colorsios 将 UIScrollView 滚动条颜色更改为不同颜色
【发布时间】:2012-08-17 11:47:56
【问题描述】:

我们如何将 UIScrollview 的滚动指示器的颜色更改为蓝色、绿色等。

我知道我们可以把它改成白色、黑色。但除了这些颜色。

非常感谢

【问题讨论】:

    标签: ios uiscrollview


    【解决方案1】:

    很遗憾,你不能,当然你可以自己滚动。这些是您的选择:

    UIScrollViewIndicatorStyleDefault:

    滚动指示器的默认样式,黑色带白色边框。这种风格适用于任何内容背景。

    UIScrollViewIndicatorStyleBlack:

    一种黑色且小于默认样式的指示器样式。这种风格适合白色内容背景。

    UIScrollViewIndicatorStyleWhite:

    指示器的样式是白色的并且比默认样式小。这种风格适合黑色内容背景。

    【讨论】:

    • 我已经在我的问题中说过我知道我们可以更改为这些颜色。无论如何感谢您的时间
    • 这些样式的属性是“indicatorStyle”
    【解决方案2】:

    这里有更安全的Swift 3方法:

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let verticalIndicator = scrollView.subviews.last as? UIImageView
        verticalIndicator?.backgroundColor = UIColor.green
    }
    

    【讨论】:

    【解决方案3】:

    两个 UIScrollView 指示器都是 UIScrollView 的子视图。所以我们可以 访问 UIScrollView 的子视图并更改子视图的属性。

    1.添加 UIScrollViewDelegate

    @interface ViewController : UIViewController<UIScrollViewDelegate>
    @end
    

    2。在实现部分添加scrollViewDidScroll

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

    注意:- 因为每次滚动时这些指标都会更新 (意味着重置为默认值)。所以,我们把这段代码放在 scrollViewDidScroll 委托方法。

    Demo available on GitHub - https://github.com/developerinsider/UIScrollViewIndicatorColor

    【讨论】:

    • 可能是!!不是100%确定。但是有什么问题呢?我们在不违反任何设计准则的情况下将内容放入滚动视图指示器中......
    • 没有错。我只需要知道提交时这是否不会给我带来问题。
    • 不会的。但这很 hacky,所以建议继承 scrollview 并编写自己的 tracker indicatorView
    • 你如何保证 scrollView.subviews.count-1 和 scrollView.subviews.count-2 是这些指标的正确索引?
    • @PaulBrewczynski 因为滚动指示器在运行时添加为子视图,这意味着当一些滚动滚动视图然后滚动视图添加这两个滚动指示器作为子视图...所以滚动指示器总是在最后和倒数第二个可用用户滚动时的索引
    【解决方案4】:

    根据@Alex (https://stackoverflow.com/a/58415249/3876285) 的回答,我发布了一些改进以更改滚动指示器的颜色。

    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)
        }
    
    }
    

    如果您不添加.subviews[0],您将获得更深的视图,并且当您尝试更改指示器的颜色时,会出现奇怪的白色效果。那是因为它前面还有另一个视图:

    通过在每个指标视图中添加.subviews[0],一旦您尝试通过调用更改颜色:

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

    您将访问第一个视图并正确更改颜色:

    感谢@Alex,他发布了一个很棒的解决方案?

    【讨论】:

    • 此解决方案适用于 ios 14,但不适用于 ios 12.. 它崩溃
    • 很奇怪,它对我有用。你得到什么样的错误?
    • 这行得通,但它是不真实的。 Xcode 13.2、iOS 15.2
    【解决方案5】:

    IOS 13

    试试这个

    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)
                }
            }
        }
    

    【讨论】:

    • 它适用于 ios 14,但在 ios 12 中有两个滚动条
    【解决方案6】:

    Swift 2.0:

    添加 UIScrollView 委托。

    func scrollViewDidScroll(scrollView: UIScrollView){
    let verticalIndicator: UIImageView = (scrollView.subviews[(scrollView.subviews.count - 1)] as! UIImageView)
    verticalIndicator.backgroundColor = UIColor.greenColor()
    
    let horizontalIndicator: UIImageView = (scrollView.subviews[(scrollView.subviews.count - 2)] as! UIImageView)
    horizontalIndicator.backgroundColor = UIColor.blueColor()
    }
    

    【讨论】:

      【解决方案7】:

      试试这个,肯定对你有帮助

          for ( UIView *view in scrollBar.subviews ) {
      
             if (view.tag == 0 && [view isKindOfClass:UIImageView.class])
             {
              UIImageView *imageView      = (UIImageView *)view;
              imageView.backgroundColor   = [UIColor yellowColor];
             }
          }
      

      说明:UIScrollBar 是子视图的集合。这里滚动条指示器(垂直/水平)是子视图之一,它是一个 UIImageView。因此,如果我们为 UIImageView 设置自定义颜色,它会影响滚动条指示器。

      【讨论】:

      • 也请对您的回答提供一些解释。
      • UIScrollBar 是子视图的集合。这里滚动条指示器(垂直/水平)是子视图之一,它是一个 UIImageView。因此,如果我们为 UIImageView 设置自定义颜色,它会影响滚动条指示器。
      【解决方案8】:

      您可以更改指示器的图像,但您应该重复执行此操作

      func scrollViewDidScroll(_ scrollView: UIScrollView) {
          self.chageScrollIndicator()
      }
      
      func chageScrollIndicator (){
          if let indicator = self.collection.subviews.last as? UIImageView {
              let edge = UIEdgeInsets(top: 1.25,
                                      left: 0,
                                      bottom: 1.25,
                                      right: 0)
              indicator.image = UIImage(named: "ScrollIndicator")?.withRenderingMode(.alwaysTemplate).resizableImage(withCapInsets: edge)
              indicator.tintColor = UIConfiguration.textColor
          }
      }
      

      您可以使用这 2 个图像作为模板:

      【讨论】:

        【解决方案9】:

        IOS 13

        由于 iOS13 滚动指示器有类 _UIScrollViewScrollIndicator,而不是 UIImageView。

        很多人使用类似的代码

        let verticalIndicator: UIImageView = (scrollView.subviews[(scrollView.subviews.count - 1)] as! UIImageView)
        

        这不是一个好主意,因为他们承诺最后一个子视图将是 UIImageView :)。现在不是,他们可能会崩溃。

        您可以尝试以下代码来获取滚动视图指标:

        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
                }
        
                let viewForVerticalScrollViewIndicator = self.subviews[verticalScrollViewIndicatorPosition]
                if viewCanBeScrollIndicator(view: viewForVerticalScrollViewIndicator) {
                    verticalScrollIndicator = viewForVerticalScrollViewIndicator
                }
                return (horizontal: horizontalScrollIndicator, vertical: verticalScrollIndicator)
            }
        
        }
        

        如果您只需要一个(h 或 v 指示器) - 最好切断此功能并只保留一个您需要的功能(以提高性能)。

        另外,最好在 DispatchQueue 内部调用 update func,以保持滚动的平滑度。

        func scrollViewDidScroll(_ scrollView: UIScrollView) {
           DispatchQueue.main.async {
               scrollView.updateCustomScrollIndicatorView()
           }
        }
        

        【讨论】:

        • 不工作。滚动视图有空的子视图数组:(
        • 打开显示水平指示器,或/和显示垂直指示器? @SerjRubens
        • 开启@Alex
        • 即使没有这个检查 ^^^,滚动视图也有空的子视图数组。只是 scrollView.subviews.count == 0? (当然,在你添加东西之前)
        • 这是唯一(几乎)对我有用的解决方案,谢谢@Alex!我只需将.subviews[0] 添加到每个指标视图中,以便更改第一层而不是更深层的颜色。将根据您的答案发布新答案?
        【解决方案10】:

        滚动条的颜色是这样改变的:

            //scroll view  
            UIScrollView *scView = [[UIScrollView alloc] init];  
            scView.frame = self.view.bounds; //scroll view occupies full parent views  
            scView.contentSize = CGSizeMake(400, 800);  
            scView.backgroundColor = [UIColor lightGrayColor];  
            scView.indicatorStyle = UIScrollViewIndicatorStyleBlack;  
            scView.showsHorizontalScrollIndicator = NO;  
            scView.showsVerticalScrollIndicator = YES;  
            scView.scrollEnabled = YES;  
            [self.view addSubview: scView];
        

        【讨论】:

        【解决方案11】:

        如果你也想添加图片,这里是 Swift 3 的代码

        func scrollViewDidScroll(_ scrollView: UIScrollView) {
            let verticalIndicator = scrollView.subviews.last as? UIImageView
            verticalIndicator?.image = UIImage(named: "imageName")
        }
        

        这也适用于 UITableView 和 UICollectionView。

        【讨论】:

          【解决方案12】:

          不久前我写了一篇关于这个的文章。不幸的是,此条的颜色由预定义的图像定义,因此如果您要更改条的颜色,则需要进行一些额外的工作。看看下面的链接,你肯定会在这里找到答案,因为我试图解决同样的问题。

          http://leonov.co/2011/04/uiscrollviews-scrollbars-customization/

          【讨论】:

            【解决方案13】:

            我最近遇到了同样的问题,所以我决定为它写一个类别。

            https://github.com/stefanceriu/UIScrollView-ScrollerAdditions

            [someScrollView setVerticalScrollerTintColor:someColor]; 
            [someScrollView setHorizontalScrollerTintColor:someColor];`
            

            它将它与原始图像混合,因此只有颜色会改变。另一方面,也可以对其进行修改以提供自定义图像供滚动条使用。

            【讨论】:

            • 我很困惑,如果你说它不应该在生产代码中使用,那么库的目的是什么?
            【解决方案14】:

            这是我在 Swift 4 中所做的,与之前的答案类似。在我的情况下,我将图像重新着色为不可见,设置正确的角半径并且只执行一次此过程。

            func scrollViewDidScroll(_ scrollView: UIScrollView) {
                let color = UIColor.red
                guard
                    let verticalIndicator = scrollView.subviews.last as? UIImageView,
                    verticalIndicator.backgroundColor != color,
                    verticalIndicator.image?.renderingMode != .alwaysTemplate
                else { return }
                verticalIndicator.layer.masksToBounds = true
                verticalIndicator.layer.cornerRadius = verticalIndicator.frame.width / 2
                verticalIndicator.backgroundColor = color
                verticalIndicator.image = verticalIndicator.image?.withRenderingMode(.alwaysTemplate)
                verticalIndicator.tintColor = .clear
            }
            

            【讨论】:

              【解决方案15】:

              请在 iOS 渲染器上使用以下代码

               private bool _layouted;
               public override void LayoutSubviews()
               {
                     base.LayoutSubviews();
                     if (!_layouted)
                     {
                          this.Layer.BorderColor = UIColor.Red.CGColor;
                          var Verticalbar = (UIImageView)this.Subviews[this.Subviews.Length - 1];
              
                          Verticalbar.BackgroundColor = Color.FromHex("#0099ff").ToUIColor();
                          var Horizontlebar = (UIImageView)this.Subviews[this.Subviews.Length - 2];
              
                          Horizontlebar.BackgroundColor = Color.FromHex("#0099ff").ToUIColor();
                          _layouted = true;
                     }
              }
              

              【讨论】:

              • 添加到代码中,解释为什么这解决了问题提出的问题总是很好的。编辑此帖子以包含详细说明是理想的选择。
              【解决方案16】:

              至于 iOS 13 的子视图发生了变化,所以添加简单的 if,解决了这个问题。

              - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
              if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 13.0) {
                  UIView *verticalIndicator = [scrollView.subviews lastObject];
                  verticalIndicator.backgroundColor = [UIColor redColor];
              } else {
                  UIImageView *verticalIndicator = [scrollView.subviews lastObject];
                  verticalIndicator.backgroundColor = [UIColor redColor];
              }
              }
              

              【讨论】:

                【解决方案17】:

                您可以使用自定义 UIScrollView 滚动条在滚动条中实现颜色。更多详情请看here

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-03-05
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多