2012-03-17 22 views
0

私はテーブルビューのVCを持っています。イベントが発生すると、メインビューの上部からUIViewにドロップします。ユーザーがテーブルビューをスクロールすると、ドロップされたビューが「スクロールする」ようにビューのレイアウトを変更したい。私はupperViewのフレームを移動し、テーブルビューのサイズを変更することで(スクロールオフセットに関連して)これを行うと考えました。私は次のようにほぼ動作しています。スクロールでUITableViewのサイズを変更する

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { 

    CGFloat contentOffsetY = scrollView.contentOffset.y; 

    if (contentOffsetY > 0) { 
     CGFloat upperHeight = self.upperView.frame.size.height; 
     CGFloat fullTableHeight = self.view.frame.size.height; 

     CGFloat offsetY = (contentOffsetY < upperHeight)? -scrollView.contentOffset.y : -upperHeight; 

     self.upperView.frame = CGRectMake(0, offsetY, 320, upperHeight); 
     scrollView.frame = CGRectMake(0, upperHeight+offsetY, 320, fullTableHeight-(upperHeight+offsetY)); 
    } 
    NSLog(@"%f", self.upperView.frame.origin.y); 
} 

上位ビューの起点は0,0から始まります。

問題は、前後に少しドラッグした後で、その上のビューの上の数ピクセルを失うことです。それがゼロに戻って起源であるように見えることはできません。ロギングは負の値を読み取り、最も慎重にドラッグするだけで-1になります。誰かがこれのような何かをしましたか?あなたが助けることができれば大いに義務づけられます。

答えて

1

ドロップインビューを表示すると、常にテーブルビューを一番上にスクロールするように思えます。その場合、これを行うより良い方法があります。

UITableViewcontentInsetプロパティを継承します。UIScrollViewです。 contentInsetプロパティは、スクロールビューの各端に境界線を定義します。各境界線には独自の太さがあり、デフォルトではゼロです。これらの罫線は、スクロールビューがコンテンツをスクロールできるようにするための距離に影響します。コンテンツを隠すことはありません。一番上のインセットをゼロより大きく設定し、スクロールビューに負のY起点を持つサブビューを与えると、そのサブビューは境界線に表示され、スクロールビューの残りのコンテンツとともにスクロールします。

したがって、テーブルビューの一番上のインセットをドロップインビューの高さに設定し、ドロップインビューをテーブルビューのサブビューとして追加し、その起点を高さの負数に設定します。これにより、テーブルビューの最初の行の上の画面に完全に収まるようになり、テーブルビューとともにスクロールします。ドロップインビューが完全に画面外にスクロールされたことを検出すると、テーブルビューから削除し、テーブルビューの一番上のインセットを0に戻すことができます。私はちょうどドロップでビューをトリガーするボタンを使用し、私のテストプロジェクトで

typedef enum { 
    DropInViewStateHidden, 
    DropInViewStateAppearing, 
    DropInViewStateVisible 
} DropInViewState; 

@implementation ViewController { 
    DropInViewState _dropInViewState; 
} 

は、我々はドロップインビューの現在の状態を追跡するインスタンス変数が必要になります。

- (IBAction)dropIn { 
    if (_dropInViewState != DropInViewStateHidden) 
     return; 

    CGRect frame = self.dropInView.frame; 
    frame.origin.y = -frame.size.height; 
    self.dropInView.frame = frame; 
    [self.tableView addSubview:self.dropInView]; 

    self.tableView.contentInset = UIEdgeInsetsMake(frame.size.height, 0, 0, 0); 
    [self.tableView setContentOffset:frame.origin animated:YES]; 

    _dropInViewState = DropInViewStateAppearing; 
} 

テーブルビューがスクロールすると、ドロップインビューの状態がチェックされます。それが「可視」状態にあり、画面外にスクロールされている場合は、非表示にします。ドロップインビューを表示して画面上にスクロールすると、ドロップインビューが非表示になっていると思われるメッセージscrollViewDidScroll:を受け取ることができるので、面倒なことがあります。そのため、DropInViewStateAppearingの状態から始めて、ビューが現れたことがわかったらDropInViewVisible状態に移行するのはこのためです。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { 
    switch (_dropInViewState) { 
     case DropInViewStateHidden: 
      break; 
     case DropInViewStateVisible: 
      if (scrollView.contentOffset.y >= 0) { 
       // dropInView has been scrolled off-screen 
       self.tableView.contentInset = UIEdgeInsetsZero; 
       [self.dropInView removeFromSuperview]; 
       _dropInViewState = DropInViewStateHidden; 
       break; 
      } 
     case DropInViewStateAppearing: 
      // When I first add dropInView to tableView and tell tableView 
      // to scroll to reveal dropInView, I may get a bunch of 
      // scrollViewDidScroll: messages with contentOffset.y >= 0. 
      // I don't want those messages to hide dropInView, so I sit in 
      // DropInViewStateAppearing until contentOffset.y goes negative, 
      // which means at least part of dropInView is actually on-screen. 
      if (scrollView.contentOffset.y < 0) 
       _dropInViewState = DropInViewStateVisible; 
      break; 
    } 
} 
+0

私は検索バーともその上のインセットエリアの競合プルにリフレッシュものを持っているので、私は製図板ではまだだけど、良い、徹底的な答えてくれてありがとう。 – danh

0

図:UITableViewは、バウンス中にdidScrollに完全にメッセージしません。これが私がいくつかのピクセルを欠いていた理由です。バウンス中にサイズを変更するとバウンスが混ざり合って停止します。上のコードでは、バウンスが動作するように(テーブルのサイズを変更しないで)移動し、バウンス中に上部ビューが正しく配置されるようにします(contentOffset.y < = 0の場合)。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { 

    CGFloat contentOffsetY = scrollView.contentOffset.y; 

    CGFloat upperHeight = self.upperView.frame.size.height; 
    CGFloat fullTableHeight = self.view.frame.size.height; 

    CGFloat offsetY = (contentOffsetY < upperHeight)? -scrollView.contentOffset.y : -upperHeight; 

    if (contentOffsetY > 0) { 
     self.upperView.frame = CGRectMake(0, offsetY, 320, upperHeight); 
     scrollView.frame = CGRectMake(0, upperHeight+offsetY, 320, fullTableHeight-(upperHeight+offsetY)); 
    } else { 
     self.upperView.frame = CGRectMake(0, 0, 320, upperHeight); 
     scrollView.frame = CGRectMake(0.0, upperHeight, 320, scrollView.frame.size.height); 
    } 
    [super scrollViewDidScroll:scrollView]; 
} 
関連する問題