【问题标题】:UIScrollView - showing the scroll barUIScrollView - 显示滚动条
【发布时间】:2010-12-25 17:01:48
【问题描述】:

可能很简单!

有谁知道如何让 UIScrollView 的滚动条不断显示?

它在用户滚动时显示,因此他们可以看到他们所在的滚动视图的位置。

但我希望它不断显示,因为用户无法立即看到滚动可用

任何建议将不胜感激。

【问题讨论】:

    标签: iphone objective-c uiscrollview scrollbar


    【解决方案1】:

    不,你不能让它们一直显示,但你可以让它们暂时闪烁。

    [myScrollView flashScrollIndicators];
    

    它们是滚动指示器,而不是滚动条。你不能用它们来滚动。

    【讨论】:

    • 是的,如果他们一直在那里,那将是一种不一致的用户体验。这是正确的做法。
    • 如果您可以控制内容,您可以通过让一些内容与边框重叠来向用户提供内容可滚动的线索。就像只显示部分的图像,这会暗示更多的内容。然后用户很容易尝试并滑动查看更多内容。
    • 它们现在是滚动条 :D
    【解决方案2】:

    my solution 一直显示滚动指示器

    #define noDisableVerticalScrollTag 836913
    #define noDisableHorizontalScrollTag 836914
    
    @implementation UIImageView (ForScrollView)
    
    - (void) setAlpha:(float)alpha {
    
    if (self.superview.tag == noDisableVerticalScrollTag) {
        if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleLeftMargin) {
            if (self.frame.size.width < 10 && self.frame.size.height > self.frame.size.width) {
                UIScrollView *sc = (UIScrollView*)self.superview;
                if (sc.frame.size.height < sc.contentSize.height) {
                    return;
                }
            }
        }
    }
    
    if (self.superview.tag == noDisableHorizontalScrollTag) {
        if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleTopMargin) {
            if (self.frame.size.height < 10 && self.frame.size.height < self.frame.size.width) {
                UIScrollView *sc = (UIScrollView*)self.superview;
                if (sc.frame.size.width < sc.contentSize.width) {
                    return;
                }
            }
        }
    }
    
    [super setAlpha:alpha];
    }
    @end
    

    更新:此解决方案在 64 位上会导致一些问题。更多详情请看here

    【讨论】:

    • 我无法让它工作,我也不太明白它应该做什么。当我们试图显示滚动条时,为什么我们要在滚动条上设置Alpha。你能稍微解释一下这里的概念吗?
    • 这不是一个很好的答案,它是一个覆盖每个 UIImageView setAlpha 方法的类别。它依赖于具有特定标签号的滚动视图指示器,这是一个私有的实现细节,可能会发生变化。
    • 这看起来像是stackoverflow.com/a/20944188/123269 的根本原因 - 在 64 位模式下运行时导致 UI 错误。我建议不要使用此代码。
    【解决方案3】:

    据我所知,这是不可能的。控制滚动指示器显示的唯一 API 调用是 showsVerticalScrollIndicator,它只能完全禁用显示指示器。

    您可以在视图出现时flashScrollIndicators,以便用户知道他们在滚动视图中的位置。

    【讨论】:

      【解决方案4】:

      这个对我有用:

      #define noDisableVerticalScrollTag 836913
      #define noDisableHorizontalScrollTag 836914
      
      @implementation UIImageView (ForScrollView) 
      
      - (void) setAlpha:(float)alpha {
      
          if (self.superview.tag == noDisableVerticalScrollTag) {
              if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleLeftMargin) {
                  if (self.frame.size.width < 10 && self.frame.size.height > self.frame.size.width) {
                      UIScrollView *sc = (UIScrollView*)self.superview;
                      if (sc.frame.size.height < sc.contentSize.height) {
                          return;
                      }
                  }
              }
          }
      
          if (self.superview.tag == noDisableHorizontalScrollTag) {
              if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleTopMargin) {
                  if (self.frame.size.height < 10 && self.frame.size.height < self.frame.size.width) {
                      UIScrollView *sc = (UIScrollView*)self.superview;
                      if (sc.frame.size.width < sc.contentSize.width) {
                          return;
                      }
                  }
              }
          }
      
          [super setAlpha:alpha];
      }
      @end
      

      我从这里得到了这个 sn-p:http://www.developers-life.com/scrollview-with-scrolls-indicators-which-are-shown-all-the-time.html

      【讨论】:

      【解决方案5】:

      斯威夫特 3+

      1) 定时器

      var timerForShowScrollIndicator: Timer?
      

      2) 方法

      /// Show always scroll indicator in table view
      func showScrollIndicatorsInContacts() {
          UIView.animate(withDuration: 0.001) {
              self.tableView.flashScrollIndicators()
          }
      }
      
      /// Start timer for always show scroll indicator in table view
      func startTimerForShowScrollIndicator() {
          self.timerForShowScrollIndicator = Timer.scheduledTimer(timeInterval: 0.3, target: self, selector: #selector(self.showScrollIndicatorsInContacts), userInfo: nil, repeats: true)
      }
      
      /// Stop timer for always show scroll indicator in table view
      func stopTimerForShowScrollIndicator() {
          self.timerForShowScrollIndicator?.invalidate()
          self.timerForShowScrollIndicator = nil
      }
      

      3) 使用

      viewDidAppear 中的 startTimerForShowScrollIndicator

      viewDidDisappear 中的stopTimerForShowScrollIndicator

      【讨论】:

        【解决方案6】:

        我想提供我的解决方案。我不喜欢最流行的类别变体(类别中的覆盖方法可能是一些不确定在运行时应该调用什么方法的原因,因为有两个方法具有相同的选择器)。 我改用调酒。而且我也不需要使用标签。

        将此方法添加到您的视图控制器,在那里您有滚动视图(self.categoriesTableView 属性是一个表格视图,我想在其中显示滚动条)

        - (void)viewDidAppear:(BOOL)animated {
            [super viewDidAppear:animated];
            // Do swizzling to turn scroll indicator always on
            // Search correct subview with vertical scroll indicator image across tableView subviews
            for (UIView * view in self.categoriesTableView.subviews) {
                if ([view isKindOfClass:[UIImageView class]]) {
                    if (view.alpha == 0 && view.autoresizingMask == UIViewAutoresizingFlexibleLeftMargin) {
                        if (view.frame.size.width < 10 && view.frame.size.height > view.frame.size.width) {
                            if (self.categoriesTableView.frame.size.height < self.categoriesTableView.contentSize.height) {
                                // Swizzle class for found imageView, that should be scroll indicator
                                object_setClass(view, [AlwaysOpaqueImageView class]);
                                break;
                            }
                        }
                    }
                }
            }
            // Search correct subview with horizontal scroll indicator image across tableView subviews
            for (UIView * view in self.categoriesTableView.subviews) {
                if ([view isKindOfClass:[UIImageView class]]) {
                    if (view.alpha == 0 && view.autoresizingMask == UIViewAutoresizingFlexibleTopMargin) {
                        if (view.frame.size.height < 10 && view.frame.size.height < view.frame.size.width) {
                            if (self.categoriesTableView.frame.size.width < self.categoriesTableView.contentSize.width) {
                                // Swizzle class for found imageView, that should be scroll indicator
                                object_setClass(view, [AlwaysOpaqueImageView class]);
                                break;
                            }
                        }
                    }
                }
            }
            // Ask to flash indicator to turn it on
           [self.categoriesTableView flashScrollIndicators];
        }
        

        添加新类

        @interface AlwaysOpaqueImageView : UIImageView
        @end
        
        @implementation AlwaysOpaqueImageView
        
        - (void)setAlpha:(CGFloat)alpha {
            [super setAlpha:1.0];
        }
        
        @end
        

        滚动指示器(第一个 for 循环中的垂直滚动指示器和第二个 for 循环中的水平滚动指示器)将始终在屏幕上。如果您只需要一个指标,请在代码中只留下这个 for 循环并删除另一个。

        【讨论】:

        • 您好,我需要对水平指示器进行哪些更改?
        【解决方案7】:

        对于第一个子视图是滚动视图的 webview,在最新的 SDK 中,如果 HTML 页面比框架长,则不会显示滚动条,并且如果 html 内容恰好与框架对齐,或者您在框架的底部有一个空格,它“看起来”就像不需要滚动,并且在该行下方没有任何内容。在这种情况下,我认为您绝对应该在代表的

        中闪烁滚动条
        - (void)webViewDidFinishLoad:(UIWebView *)webView; 
        

        提醒用户“盒子外”还有更多东西的方法。

        NSArray *subViews = [[NSArray alloc] initWithArray:[webView subviews]] ;
        UIScrollView *webScroller = (UIScrollView *)[subViews objectAtIndex:0] ;    
        

        使用 HTML 时,水平内容会自动换行,因此请检查网页滚动条的高度。

                if (webScroller.contentSize.height > webView.frame.size.height) {
                    [webScroller flashScrollIndicators];
                }
        

        flash 很短,并且在加载视图时发生,因此可以忽略。要解决这个问题,您还可以通过通用 UIView commitAnimations 稍微抖动或弹跳或滚动或缩放内容

        【讨论】:

          【解决方案8】:

          iOS 不提供 API。但是如果你真的想要这个,你可以添加你的自定义指示器来滚动视图并自己布局它,就像演示一样:

          - (void)layoutSubviews { [超级布局子视图]; 如果(self.showsVerticalScrollIndicatorAlways){ scroll_indicator_position(self, k_scroll_indicator_vertical); } 如果(self.showsHorizo​​ntalScrollIndicatorAlways){ scroll_indicator_position(自我,k_scroll_indicator_horizo​​ntal); } }

          链接是https://github.com/flexih/MazeScrollView

          【讨论】:

            【解决方案9】:

            ScrollBar 的功能就像 iOS 内置的一样,但你可以弄乱颜色和宽度。

            -(void)persistantScrollBar
            {
                [persistantScrollBar removeFromSuperview];
                [self.collectionView setNeedsLayout];
                [self.collectionView layoutIfNeeded];
            
                if (self.collectionView.contentSize.height > self.collectionView.frame.size.height + 10)
                {
                    persistantScrollBar = [[UIView alloc] initWithFrame:(CGRectMake(self.view.frame.size.width - 10, self.collectionView.frame.origin.y, 5, (self.collectionView.frame.size.height /self.collectionView.contentSize.height) * self.collectionView.frame.size.height))];
                    persistantScrollBar.backgroundColor = [UIColor colorWithRed:207/255.f green:207/255.f blue:207/255.f alpha:0.5f];
                    persistantScrollBar.layer.cornerRadius = persistantScrollBar.frame.size.width/2;
                    persistantScrollBar.layer.zPosition = 0;
                    [self.view addSubview:persistantScrollBar];
                }
            }
            
            -(void)scrollViewDidScroll:(UIScrollView *)scrollView
            {
                CGRect rect = persistantScrollBar.frame;
                rect.origin.y =  scrollView.frame.origin.y + (scrollView.contentOffset.y *(self.collectionView.frame.size.height/self.collectionView.contentSize.height));
                rect.size.height = (self.collectionView.frame.size.height /self.collectionView.contentSize.height) * self.collectionView.frame.size.height;
                if ( scrollView.contentOffset.y <= 0 )
                {
                    rect.origin.y = scrollView.frame.origin.y;
                    rect.size.height = rect.size.height + (scrollView.contentOffset.y);
                }
                else if (scrollView.contentOffset.y + scrollView.frame.size.height >= scrollView.contentSize.height)
                {
                    rect.size.height = rect.size.height - ((scrollView.contentOffset.y + scrollView.frame.size.height) - scrollView.contentSize.height);
                    rect.origin.y =  (self.collectionView.frame.origin.y + self.collectionView.frame.size.height - 5) - rect.size.height;
                }
            
                persistantScrollBar.frame = rect;
            }
            

            【讨论】:

              【解决方案10】:

              斯威夫特 3

              您可以使用 scrollView.subviews 访问滚动条并修改 alpha,如下所示。它对我有用。

              extension UIScrollView {
                  override open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
                      for x in self.subviews {
                          x.alpha = 1.0
                      }
                  }
              }
              
              extension MyScrollViewDelegate : UIScrollViewDelegate {
                  func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
                      for x in scrollView.subviews {
                          x.alpha = 1.0
                      }
                  }
              }
              

              【讨论】:

                猜你喜欢
                • 2012-06-13
                • 2019-04-21
                • 2011-01-02
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多