5

ボタンを含む UIScrollView があります。ボタンが押されたら、scrollRectToVisible を使用してビューの一番下までスクロールしたいと思います。

例えば:

CGRect r = CGRectMake(0, myUIScrollView.contentSize.height - 1, 1, 1);
[myUIScrollView scrollRectToVisible:r animated:YES];

アニメーションを NO に設定すると、すべてが期待どおりに機能しますが、YES に設定すると、非常に奇妙な動作が見られます。

  • 基本的に、何も起こりません。
  • ボタンを繰り返しタップすると、数ピクセルスクロールするか、完全にスクロールする場合があります。
  • ボタンを押す前に指でビューを手動でスクロールすると、期待どおりに下にスクロールする可能性がありますが、確実ではありません。

_geScroll_Settings.contentSize を出力しましたが、期待どおりです。

また、タイマーを開始して scrollRectToVisible の呼び出しを遅らせようとしましたが、結果はほとんど同じです。

scrollView はかなりバニラです。インターフェイスビルダーで作成しています。起動時にscrollViewのコンテンツを動的に追加し、contentSizeを適切に調整していますが、すべて正常に機能しているようです。

何かご意見は?

4

2 に答える 2

6

私の賭けは、表示領域が有効ではない (1x1)、またはy オフセットが境界のすぐ外側にあるため、scrollRectToVisible が台無しになっているということです。代わりに、scrollView の表示領域のサイズで設定しようとしましたか?

CGRect rectBottom = CGRectZero;
rectBottom.size = myUIScrollView.frame.size;
rectBottom.origin.y = myUIScrollView.contentSize.height - rectBottom.size.height;
rectBottom.origin.x = 0;

[myUIScrollView scrollRectToVisible:rectBottom animated:YES];

申し訳ありませんが、これ以上お手伝いできませんが、現在 Mac を使用していないため、テストを実行できません。上記のコードは、scrollView の表示部分に収まる正確なサイズの CGRect を作成し、オフセットはその最後の表示部分になります。

于 2011-08-24T02:07:26.860 に答える
0

「アニメーションをNOに設定すると、すべてが期待どおりに機能する」という部分を含む、同様の問題が発生しました。

iOS 6 では、UITextView が最も近い親 UIScrollView を自動スクロールして、ファーストレスポンダーになったときにカーソルを表示することが判明しました。iOS 7 では、そのような動作はありません。UIScrollView は、ほぼ同時に scrollRectToVisible への 2 つの呼び出しによって混乱しているようです。

iOS 6 では、ほとんどの場合、 scrollRectToVisible への明示的な呼び出しは無視されます。iOS 7 のようにすべてではなく、UITextView の最初の行を表示するためだけにスクロールします (自動スクロール)。

テストするには、Xcode 5 で新しいシングル ビュー アプリを作成し、そのデプロイ ターゲットを 6.0 に設定して、ViewController.m に以下のコードを使用します。iOS 6.1 シミュレーターで実行し、スクロールして UITextView を非表示にし、画面の任意の場所をタップします。数回再試行する必要があるかもしれませんが、ほとんどの場合、最初の行だけが表示されます。WORKAROUD定義を再度有効にすると、UITextViewが独自のUIScrollViewに埋め込まれ、scrollRectToVisibleの呼び出しが期待どおりに機能します。

#import "ViewController.h"

//#define WORKAROUND

@interface ViewController ()
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UITextView *textView;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewTap)]];

    self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 240)];
    self.scrollView.contentSize = CGSizeMake(320, 400);
    self.scrollView.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:self.scrollView];

#ifdef WORKAROUND
    UIScrollView* dummyScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(20, 280, 280, 100)];
    self.textView = [[UITextView alloc] initWithFrame:dummyScrollView.bounds];
    [dummyScrollView addSubview:self.textView];
    [self.scrollView addSubview:dummyScrollView];
#else
    self.textView = [[UITextView alloc] initWithFrame:CGRectMake(20, 280, 280, 100)];
    [self.scrollView addSubview:self.textView];
#endif

    self.textView.backgroundColor = [UIColor grayColor];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)viewTap
{
    if (self.textView.isFirstResponder) {
        [self.textView resignFirstResponder];
    }
    else {
        [self.textView becomeFirstResponder];
    }
}

- (void)keyboardWasShown:(NSNotification*)aNotification
{
#ifdef WORKAROUND
    [self.scrollView scrollRectToVisible:CGRectInset(self.textView.superview.frame, 0, -10) animated:YES];
#else
    [self.scrollView scrollRectToVisible:CGRectInset(self.textView.frame, 0, -10) animated:YES];
#endif
}

@end
于 2013-12-21T13:39:02.877 に答える