web-dev-qa-db-ja.com

UIScrollViewでスクロールをプログラムで強制的に停止するにはどうすればよいですか?

注: ここに記載されている回答 は機能しません。

UIScrollView(テーブルビューではなく、単なるカスタムビュー)があり、ユーザーが特定のアクションを実行したときに、ビュー内のスクロール(ドラッグまたは減速)をすべて終了したい。私は例えばやってみましたこの:

[scrollView scrollRectToVisible:CGRectInset([scrollView bounds], 10, 10) animated:NO];

すでに可視であることがわかっている長方形を考えると、スクロールはそれがどこにあるかだけ停止しますが、これは効果がないことがわかります-明らかに、スクロールビューは指定された長方形が境界内にあり、何もしない。 Ican間違いなくoutside現在表示されている境界ですが、ビューのcontentSize内です。これは予想どおりビューを停止しているように見えますが、他の場所にジャンプする原因にもなります。これを適度にうまく動作させるために余白で少し遊んでもいいでしょうが、スクロールビューを停止するクリーンな方法を知っている人はいますか?

ありがとう。

71
Ben Zotto

私はあなたのオリジナルのソリューションを少し試しましたが、これはうまくいくようです。私はあなたがそれをほとんど持っていたと思うが、あなたはあなたがあまりにも多く使用した長方形を相殺し、そしてあなたが元の長方形までまっすぐに長方形をスクロールできることを忘れていた。

スクロールアクションの一般的なソリューションは次のとおりです。

- (void)killScroll 
{
    CGPoint offset = scrollView.contentOffset;
    offset.x -= 1.0;
    offset.y -= 1.0;
    [scrollView setContentOffset:offset animated:NO];
    offset.x += 1.0;
    offset.y += 1.0;
    [scrollView setContentOffset:offset animated:NO];
}

[編集] iOS 4.3(および場合によってはそれ以前)でも動作するようです

- (void)killScroll 
{
    CGPoint offset = scrollView.contentOffset;
    [scrollView setContentOffset:offset animated:NO];
}
98
David Liu

実際の一般的な答えは、[scrollView setContentOffset:offset animated:NO]同じではない[scrollView setContentOffset:offset]です!

  • [scrollView setContentOffset:offset animated:NO]は、実行中のアニメーションを実際に停止します。
  • [scrollView setContentOffset:offset]は、実行中のアニメーションを停止しません。
  • scrollView.contentOffset = offsetについても同じ:実行中のアニメーションを停止しません。

それはどこにも文書化されていませんが、それはiOS 6.1およびiOS 7.1でテストされた動作です-おそらく以前にも。

そのため、実行中のアニメーション/減速を停止するsolutionはそのように単純です:

[scrollView setContentOffset:scrollView.contentOffset animated:NO];

基本的に、David Liuが編集した回答で言ったことです。しかし、これら2つのAPIは[〜#〜] not [〜#〜]同じであることを明確にしたかったのです。

スウィフト3:

scrollView.setContentOffset(scrollView.contentOffset, animated: false)
76
calimarkus

私にとっては、 上記のDavid Luiの受け入れられた答え はうまくいきませんでした。これは私がやったことです:

- (void)killScroll {
    self.scrollView.scrollEnabled = NO;
    self.scrollView.scrollEnabled = YES;
}

価値があるものとして、iOS 6.0 iPhone Simulatorを使用しています。

68
TPoschel

Swiftでスクロールを停止します:

scrollView.setContentOffset(scrollView.contentOffset, animated: false)
17
budidino

これは、スクロールビューと他のすべての関連サブクラスに対して行うことです。

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
 {
    *targetContentOffset = scrollView.contentOffset;
 }

これにより、targetContentOffsetscrollViewの現在のオフセットに設定され、ターゲットに到達したためにスクロールが停止します。ユーザーがターゲットのcontentOffsetを設定できるようにすることを目的とするメソッドを使用することは実際に理にかなっています。

Swift

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    targetContentOffset.pointee = scrollView.contentOffset
}
17
funct7

実際には...最も「現代的な」方法は--->

scrollview.panGestureRecognizer.enabled = false;
scrollview.panGestureRecognizer.enabled = true;

これにより、現在のタッチを強制終了するほんの一瞬のスクロールを担当するジェスチャ認識機能が無効になります。ユーザーは、再度スクロールを開始するには、指を持ち上げて下に戻す必要があります。

編集:これは実際にはユーザーの現在のドラッグを強制終了しますが、スクロールビューが現在この状態にある場合、減速をすぐに停止しません。これを行うには、受け入れられた回答の編集がxDの最良の方法です

[scrollview setContentOffset: scrollview.contentOffset animated:false];
12
Xatian

最もクリーンな方法は、UIScrollViewをサブクラス化し、独自のsetContentOffsetメソッドを提供することです。これは、freeze booleanプロパティをオンにしていない場合、onlyでメッセージを渡します。

そのようです:

BOOL freeze; // and the @property, @synthesize lines..

-(void)setContentOffset:(CGPoint)offset
{
    if ( !freeze ) [super setContentOffset:offset];
}

次に、フリーズするには:

scrollView.freeze = YES;
5
mvds

この答えは私のために働いた: IScrollViewの減速を無効にする

-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{
    [scrollView setContentOffset:scrollView.contentOffset animated:YES];
}
4
Johnny Rockex

スクロールビュー内の特定のUIViewがスワイプ中のタッチのソースである場合にのみ、スクロールを無効にしたいと考えました。複雑なビュー階層があるため、UIViewをUIScrollViewの外側に移動するには、かなりのリファクタリングが必要でした。

回避策として、単一のUIPanGestureRecognizerをサブビューに追加して、スクロールを防止したいと考えました。このUIPanGestureRecognizerはcancelsTouchesInViewになり、UIScrollViewのpanGestureのアクティブ化を防ぎます。

それは少し「ハック」ですが、それは非常に簡単な変更であり、XIBまたはストーリーボードを使用している場合、必要なことは問題のサブビューにパンジェスチャーをドラッグすることです。

0
Daniel Williams

Collectionviewでこのメソッドを試しました:

self.collectionView.collectionViewLayout.finalizeCollectionViewUpdates()

0
Kalerfu

これはSwift 4.2で動作します:

   func killScroll() {
    self.scrollView.isScrollEnabled = false;
    self.scrollView.isScrollEnabled = true;
}

...拡張として:

extension UIScrollView {
    func killScroll() {
        self.isScrollEnabled = false;
        self.isScrollEnabled = true;

    }
}
0