UIScrollView - 显示滚动条

时间:2009-12-11 15:02:04

标签: iphone objective-c uiscrollview scrollbar

可能是一个简单的!

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

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

但是我希望它能够不断展示,因为用户不会立即明白滚动是否可用

任何建议都将受到高度赞赏。

10 个答案:

答案 0 :(得分:82)

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

[myScrollView flashScrollIndicators];

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

答案 1 :(得分:6)

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

UPDATE :此解决方案会导致64位问题。有关详细信息,请查看here

答案 2 :(得分:4)

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

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

答案 3 :(得分:3)

这个对我有用:

#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

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

答案 4 :(得分:1)

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

将此方法添加到视图控制器,您可以在其中具有滚动视图(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个周期,然后删除另一个。

答案 5 :(得分:0)

对于网页浏览,第一个子视图是滚动视图,在最新的SDK中,如果HTML页面比框架长,则不显示滚动条,如果html内容恰好与框架对齐,或者您在框架的底部有一个空格,它看起来像没有需要滚动而且没有任何东西在线下。在这种情况下,我认为你应该明确地闪烁委托的

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

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

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

使用HTML,水平内容会自动换行,因此请检查webscroller高度。

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

闪存太短了,在加载视图时发生,可以忽略它。要解决这个问题,您还可以通过通用的UIView commitAnimations轻微地微动或反弹,滚动或缩放内容

答案 6 :(得分:0)

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

- (void)layoutSubviews
{
    [super layoutSubviews];

    if (self.showsVerticalScrollIndicatorAlways) {
        scroll_indicator_position(self, k_scroll_indicator_vertical);
    }

    if (self.showsHorizontalScrollIndicatorAlways) {
        scroll_indicator_position(self, k_scroll_indicator_horizontal);
    }
}

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

答案 7 :(得分:0)

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

答案 8 :(得分:0)

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

答案 9 :(得分:0)

快速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