滚动条在UIScrollView上始终可见?

时间:2012-12-04 06:23:41

标签: iphone ios cocoa-touch uiscrollview uikit

我需要在viewDidLoad上始终显示滚动条,以便用户可以理解存在要滚动的内容。我做了以下事情:

[myscrollView flashScrollIndicators];

但是滚动条只会在viewDidLoad之后显示一段时间并再次消失,只是在用户触摸屏幕时重新出现..

我需要让滚动条始终可见。我该怎么办?

4 个答案:

答案 0 :(得分:18)

Apple间接阻止在iOS Human Interface Guidelines中不断显示滚动指示符,但指南仅仅是指导原因,他们不会考虑每种情况,有时您可能需要礼貌地忽略它们。

任何内容视图的滚动指示符都是这些内容视图的UIImageView子视图。这意味着您可以访问 UIScrollView的滚动指示符,就像其他任何子视图(即myScrollView.subviews)和修改滚动指示符一样和任何UIImageView一样(例如scrollIndicatorImageView.backgroundColor = [UIColor redColor];)。

最流行的解决方案似乎是以下代码:

#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

最初归功于this source

这为UIImageView定义了一个类别,用于定义alpha属性的自定义setter。这是有效的,因为在UIScrollView的基础代码中的某个时刻,它会将其滚动指示器的alpha属性设置为0以隐藏它。此时它将运行我们的类别,如果托管UIScrollView具有正确的标记,它将忽略所设置的值,并将其显示。

要使用此解决方案,请确保UIScrollView具有相应的标记,例如 Tag

如果要显示滚动指示器,只要其UIScrollView可见,只需在视图出现时闪烁​​滚动指示器.e.g

- (void)viewDidAppear:(BOOL)animate
{
    [super viewDidAppear:animate];
    [self.scrollView flashScrollIndicators];
}

其他SO参考:

答案 1 :(得分:4)

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

将此方法添加到视图控制器,您可以在其中滚动视图(在我的情况下为self.categoriesTableView

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // Do swizzling to turn scroll indicator always on
    // Search correct subview with 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;
                    }
                }
            }
        }
    }
    // 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

滚动指示器(本例中为垂直滚动指示器)将始终位于屏幕上。

答案 2 :(得分:0)

我不知道这是否有效。但只是暗示你。

Scrollview内的滚动条是Imageview。这是UIScrollview的子视图

所以获取UIscrollview的Scrollbar Imageview。然后尝试将隐藏的图像属性设置为NO或更改Alpha值

static const int UIScrollViewHorizontalBarIndexOffset = 0;
static const int UIScrollViewVerticalBarIndexOffset = 1;
-(UIImageView *)scrollbarImageViewWithIndex:(int)indexOffset 
{
    int viewsCount = [[yourScrollview subviews] count];
    UIImageView *scrollBar = [[yourScrollview subviews] objectAtIndex:viewsCount - indexOffset - 1];
    return scrollBar;
}

-(void) viewDidLoad
{
    //Some Code
    //Get Scrollbar
    UIImageView *scrollBar = [self scrollbarImageViewWithIndex: UIScrollViewVerticalBarIndexOffset];

    //The try setting hidden property/ alpha value
    scrollBar.hidden=NO;
}

获得here

的参考资料

答案 3 :(得分:0)

这是@Accid Bright的answer的Swift版本:

class AlwaysOpaqueImageView: UIImageView {

    override var alpha: CGFloat {
        didSet {
            alpha = 1
        }
    }

    static func setScrollbarToAlwaysVisible(from scrollView: UIScrollView) {
        // Do swizzling to turn scroll indicator always on
        // Search correct subview with scroll indicator image across tableView subviews
        for view in scrollView.subviews {
            if view.isKind(of: UIImageView.self),
                view.alpha == 0 && view.autoresizingMask == UIView.AutoresizingMask.flexibleLeftMargin,
                view.frame.size.width < 10 && view.frame.size.height > view.frame.size.width,
                scrollView.frame.size.height < scrollView.contentSize.height {
                // Swizzle class for found imageView, that should be scroll indicator
                object_setClass(view, AlwaysOpaqueImageView.self)
                break
            }
        }

        // Ask to flash indicator to turn it on
        scrollView.flashScrollIndicators()
    }
}

区别在于设置滚动条是作为静态方法提取的。