web-dev-qa-db-ja.com

scrollViewWillEndDragging:withVelocity:targetContentOffset:UISCrollViewの端で機能しない

スクロール可能で、各タブバー項目にページングがあるカスタムタブバーを実装しようとしています。そのため、私はデリゲートscrollViewWillEndDragging:withVelocity:targetContentOffset:を使用しています。これは1つの問題で完全に機能します。

私のページングが機能する方法は、contentOffsetが適切なアイテムの近くにある場合、targetContentOffsetがそのアイテムのオフセットに変更されることです。左側も同じです。

問題は、最初の項目の左半分と最後の項目の右側(スクロールビューが水平方向に機能する)にいるときはいつでも、ContentOffset 0と右端の項目のコンテンツオフセット(マイナスの項目を除く)に移動することです。画面)、しかしそれはしません。

デバッガーで確認したところ、targetContentOffset-> xは確かに0です(最初の場合-左端の項目の左側)。したがって、問題はUIScrollViewがそこでスクロールしないことです。道に迷いました。

ここに私の実装されたデリゲートがあります:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                 withVelocity:(CGPoint)velocity
          targetContentOffset:(inout CGPoint *)targetContentOffset{
     NSInteger index = lrintf(targetContentOffset->x/self.tabWidth);
     targetContentOffset->x = index * self.tabWidth;
}

これは私が何をしたいかを説明する図です。

|-------|-------|-------|-------|-------|-------|-------|
|       |       |       |       |       |       |       |
|       |       |       |       |       |       |       |
|_______|_______|_______|_______|_______|_______|_______|

        |_______________________________________|
         where it is and i scroll it to the left

   <----|

   |_______________________________________|
              where it would stop

|_______________________________________|
        where i want it to stop
28
dvieira

これは既知の問題のようです。いくつかの調査と他の人々との話し合いの後、それはバグである可能性が示唆されましたが、それは正しいことが判明しました。私はそれをApple=に報告し、重複としてマークされていましたが、まだ開いています。同じ問題を抱えている人のために答えるだけです。BigPapooが示唆するように、私が欲しいもの(0.1はそれをするようです)右端についても同じです。

15
dvieira

IOS 6.0で修正された問題。

これで正常に機能します。

9
Rany Ishak

Big Papooが提案するように、最終オフセットをゼロまたはコンテンツサイズからわずかにずらした値に設定してみましたが、これによりオーバースクロールのバウンスが除去されていることに気付きました。これに対する私の解決策は、元のtargetContentOffsetをチェックして、それがゼロまたはcontentSizeに等しいかどうかを確認し、等しい場合はそのままにすることでした。

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {

    float expectedOffset = targetContentOffset->x;
    if (expectedOffset == 0 || expectedOffset == scrollView.contentSize.width) return; // Scroll view will bounce so leave the targetContentOffset.

    float targetOffset = [self roundedOffset:expectedOffset]; // Round your offset.

    // Adjust the offset to make sure it works.
    if (targetOffset == 0) targetOffset = 1;
    else if (targetOffset == SCROLLVIEW_WIDTH) targetOffset = SCROLLVIEW_WIDTH - 1;

    targetContentOffset->x = targetOffset;
}

もちろんscrollViewDidEndDecelerating: toでスクロールビューを1ポイント移動します。

8
Adam Swinden

調査できる文書化されていない2つの動作が見つかりました:-最終オフセットが機能しないため、ゼロを設定します。1またはゼロより大きい値を入力することをお勧めします(0.5は機能する可能性があり、テストされていません)-速度記号を確認して計算することをお勧めしますユーザーが削除した現在のポイントの左側または右側にある最終オフセットは指です。スクロールを反対側に戻そうとしないでください。

3
Big Papoo

水平テーブルビューを使用している場合は、scrollViewWillEndDragging:withVelocity:targetContentOffset:関数内で、次を呼び出すことができます。

[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:<index> inSection:<section>] atScrollPosition:UITableViewScrollPositionTop animated:YES];

これは、水平テーブルビューでtargetContentOffset-> yを操作するよりもはるかにうまく機能することがわかりました。

0
Mr. T