web-dev-qa-db-ja.com

スクロールバーを常にUIScrollViewに表示しますか?

スクロールするコンテンツがあることをユーザーが理解できるように、viewDidLoadでスクロールバーを常に表示する必要があります。私は次のことをしました:

[myscrollView flashScrollIndicators];

ただし、スクロールバーは、viewDidLoadの後にしばらく表示され、ユーザーが画面に触れたときに再び表示されるように再び非表示になります。

スクロールバーを常に表示する必要があります。どうすればできますか?

20
Honey

Appleは、スクロールインジケーターを常に表示することを間接的に推奨しません iOSヒューマンインターフェイスガイドライン ガイドラインは理由のための単なるガイドラインであり、すべてのシナリオを考慮していないため、それらを丁寧に無視する必要がある場合があります。

コンテンツビューのスクロールインジケーターは、それらのコンテンツビューのUIImageViewサブビューです。つまり、UIScrollViewのスクロールインジケーターは、他のサブビューと同じようにアクセスできます(つまり、myScrollView.subviews)およびmodifyスクロールインジケーターを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 にクレジットされています。

これは、alphaプロパティのカスタムセッターを定義するUIImageViewのカテゴリを定義します。これは、UIScrollViewの基礎となるコードのある時点で、スクロールインジケーターのalphaプロパティを0に設定して非表示にするためです。この時点で、カテゴリを介して実行され、ホスティングUIScrollViewに適切なタグがある場合、設定されている値は無視され、表示されたままになります。

このソリューションを使用するには、UIScrollViewに適切なタグがあることを確認してください。 Tag

UIScrollViewが表示された瞬間からスクロールインジケーターを表示する場合は、ビューが表示されたときにスクロールインジケーターを点滅させるだけです。

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

追加SO参照:

19

私の解決策を提供したいと思います。カテゴリで最も人気のあるバリアントは好きではありません(同じセレクタを持つ2つのメソッドがあるため、カテゴリ内のメソッドをオーバーライドすると、実行時にどのメソッドを呼び出すかが不明確になることがあります)。代わりにスウィズリングを使用します。また、タグを使用する必要もありません。

このメソッドを、スクロールビュー(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

スクロールインジケーター(この場合は垂直スクロールインジケーター)は常に画面に表示されます。

5
Accid Bright

これはSwift @Accid Brightのバージョン answer です:

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

1つの違いは、スクロールバーの設定が静的メソッドとして抽出されることです。

0
green0range

これがうまくいくかどうかわかりません。しかし、あなたのためのヒントにすぎません。

Scrollview内のScrollbarはImageviewです。 UIScrollviewのサブビューはどれですか

したがって、UIscrollviewのスクロールバーImageviewを取得します。次に、その画像プロパティを非表示に設定するか、アルファ値を変更してみてください

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

こちら から参照を得た

0
iPrabu