web-dev-qa-db-ja.com

UIScrollView-スクロールバーを表示

おそらくシンプルなものです!

UIScrollViewのスクロールバーを常に表示する方法を知っている人はいますか?

ユーザーがスクロールしているときに表示されるため、ユーザーはスクロールビューのどの位置にいるかを確認できます。

しかし、スクロールが使用可能であることはユーザーにはすぐにはわからないため、常に表示したい

アドバイスをいただければ幸いです。

55
Tom G

いいえ、常に表示することはできませんが、一時的に点滅させることはできます。

[myScrollView flashScrollIndicators];

これらはスクロールバーではなく、スクロールインジケータです。スクロールには使用できません。

83
Mongus Pong

私のソリューション スクロールインジケーターを常に表示する場合

#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ビットでいくつかの問題を引き起こします。詳細については こちら

6
SAKrisT

私の知る限り、これは不可能です。スクロールインジケータの表示を制御する唯一のAPIコールは showsVerticalScrollIndicator であり、インジケータの表示のみを無効にすることができます。

flashScrollIndicators ビューが表示されると、ユーザーはスクロールビューのどこにいるかを知ることができます。

4
Ben S

これは私のために働いた:

#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

3
sciasxp

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

このメソッドをビュービューコントローラーに追加します。スクロールビュー(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サイクルの垂直スクロールインジケーターと2番目のforサイクルの水平スクロールインジケーター)は常に画面に表示されます。インジケーターが1つだけ必要な場合は、このforサイクルのみをコードに残し、別のインジケーターを削除します。

1
Accid Bright

組み込みのiOSのように機能するScrollBarですが、色と幅を台無しにすることができます。

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

iOSはAPIを提供していません。ただし、これが本当に必要な場合は、デモと同様に、カスタムインジケーターを追加してスクロールビューを表示し、自分でレイアウトすることができます。

void)layoutSubviews 
 {
 [super layoutSubviews]; 
 
 if(self.showsVerticalScrollIndicatorAlways){
 scroll_indicator_position( self、k_scroll_indicator_vertical); 
} 
 
 if(self.showsHorizo​​ntalScrollIndicatorAlways){
 scroll_indicator_position(self、k_scroll_indicator_horizo​​ntal); 
} 
} 

リンクは---(https://github.com/flexih/MazeScrollView です

0
flexih

Swift

ScrollView.subviewsを使用してスクロールバーにアクセスし、ここに示すようにアルファを変更できます。わたしにはできる。

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
        }
    }
}
0
Alfred

Swift 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

0
chinnuabhi

最新のSDKの最初のサブビューがスクロールビューであるWebビューの場合、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を使用してコンテンツを少し揺らしたり、バウンスしたり、スクロールしたり、スケールしたりすることもできます。

0
PapaSmurf