-1

次のコードを使用して、viewWillAppearの条件に基づいてビューとビューが占めるスペースを非表示にしています。

- (void)viewWillAppear:(BOOL)animated {

    Data* data = [Data shared];

    if (data.something == 0) {

        CGRect frame = self.tableView.tableHeaderView.frame;
        frame.size.height = 0;
        self.tableView.tableHeaderView.frame = frame;

        self.tableView.tableHeaderView.hidden = YES;

    } else {

        CGRect frame = self.tableView.tableHeaderView.frame;
        frame.size.height = 44;
        self.tableView.tableHeaderView.frame = frame;

        self.tableView.tableHeaderView.hidden = NO;

    }

}

上記のコードは機能しますが、それが正しい方法ではないと確信しています。tableHeaderViewをnilに設定しようとしましたが、コードが呼び出されると、UITableViewが破棄されるまでheaderViewは失われます(tableHeaderにIBOutletを使用して修正できると思いますが、正しく聞こえません。

UPDATE1:もう一度試してみますが、コードが機能しません:

- (CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section {
   self.tableView.tableHeaderView.hidden = YES;
   return 0; 
}
4

2 に答える 2

4

データソースメソッドは、実際にはテーブルビューのプロパティtableView:heightForHeaderInSection:に関連付けられているビューとは何の関係もありません。tableViewHeaderここには2つの異なるタイプのヘッダーがあります。1つ検索バーなどを配置できるtableViewの上部にあるヘッダーで、もう1つはテーブルビュー内のセクションごとに1つずつ発生させることができる複数のヘッダーです。

私の知る限り、tableViewHeaderビューは通常nibファイルで構成されますが、テーブルビューが、その構成を許可するデータソースメソッドを呼び出すことはわかりません。そのため、手動で行う必要があります。率直に言って、コードが機能する場合、それはそれを行うための良い方法です。それを非表示にすると、テーブルビューはまだそこにあるかのように動作します...完全に削除すると、割り当てが解除されるため、元に戻すことができなくなります。

(ただし、あなたが言ったように、強力な参照を作成する限り、ヘッダービューを指すIBOutletを使用できます。その後、後でテーブルに再挿入できます。...うーん、方法の仕組みはテーブルビューのスクロールビューにビューを追加し、それを正しく配置するのは、おそらく面倒です。)

私の唯一の提案は、フレームの高さをゼロにアニメーション化して、 animateWithDurationのような素晴らしいトランジション効果を得るというものです。しかし、ええ、私はあなたがすでに考え出された最良の方法を持っていると言うでしょう。

編集:

コード、あなたは言いますか?私はそれを挑戦として受け止めます:)

- (void)setTableViewHeaderHidden:(BOOL)hide
{

    // Don't want to muck things up if we are mid an animation.
    if (self.isAnimatingHeader) {
        return;
    }

    // This is our IBOutlet property, I am just saving a bit of typing.
    UIView *theHeader = self.theHeaderView;

    if (hide) {

        // Save the original height into the tag, should only be done once.
        if (!theHeader.tag) {
            theHeader.tag = theHeader.frame.size.height;
        }

        // Transform and hide
        if (theHeader.frame.size.height > 0) {

            self.isAnimatingHeader = YES;

            // New frame...
            CGRect frame = theHeader.frame;
            frame.size.height = 0;

            // Figure out some offsets here so we prevent jumping...
            CGPoint originalOffset = self.tableView.contentOffset;

            CGPoint animOffset = originalOffset;
            animOffset.y += MAX(0, theHeader.tag - animOffset.y);

            CGPoint newOffset = originalOffset;
            newOffset.y = MAX(0, newOffset.y - theHeader.tag);

            // Perform the animation
            [UIView animateWithDuration:0.35
                                  delay:0.0
                                options: UIViewAnimationCurveEaseOut
                             animations:^{
                                 theHeader.frame = frame;
                                 self.tableView.contentOffset = animOffset;
                             }
                             completion:^(BOOL finished){
                                 if (finished) {

                                     // Hide the header
                                     self.tableView.tableHeaderView = nil;
                                     theHeader.hidden = YES;

                                     // Shift the content offset so we don't get a jump
                                     self.tableView.contentOffset = newOffset;

                                     // Done animating.
                                     self.isAnimatingHeader = NO;

                                 }
                             }
             ];

        }

    } else {

        // Show and transform
        if (theHeader.frame.size.height < theHeader.tag) {

            self.isAnimatingHeader = YES;

            // Set the frame to the original before we transform, so that the tableview corrects the cell positions when we re-add it.
            CGRect originalFrame = theHeader.frame;
            originalFrame.size.height = theHeader.tag;
            theHeader.frame = originalFrame;

            // Show before we transform so that you can see it happen
            self.tableView.tableHeaderView = theHeader;
            theHeader.hidden = NO;

            // Figure out some offsets so we don't get the table jumping...
            CGPoint originalOffset = self.tableView.contentOffset;

            CGPoint startOffset = originalOffset;
            startOffset.y += theHeader.tag;
            self.tableView.contentOffset = startOffset; // Correct for the view insertion right off the bat

            // Now, I don't know if you want the top header to animate in or not. If you think about it, you only *need* to animate the header *out* because the user might be looking at it. I figure only animate it in if the user is already scrolled to the top, but hey, this is open to customization and personal preference.

            if (self.animateInTopHeader && originalOffset.y == 0) {

                CGPoint animOffset = originalOffset;

                // Perform the animation
                [UIView animateWithDuration:0.35
                                      delay:0.0
                                    options: UIViewAnimationCurveEaseIn
                                 animations:^{
                                     self.tableView.contentOffset = animOffset;

                                 }
                                 completion:^(BOOL finished){
                                     // Done animating.
                                     self.isAnimatingHeader = NO;
                                 }
                 ];

            } else {
                self.isAnimatingHeader = NO;
            }

        }

    }
}

これは、Xcodeに付属のテーブルビューテンプレートに組み込まれています。それを一緒に投げるために、私はUILongPressGestureRecognizerこのメソッドを指すセレクターアウトレットでを使用しました:

- (IBAction)longPress:(UIGestureRecognizer *)sender
{
    if (sender.state != UIGestureRecognizerStateBegan) {
        return;
    }
    if (self.hidingHeader) {
        self.hidingHeader = NO;
        [self setTableViewHeaderHidden:NO];
    } else {
        self.hidingHeader = YES;
        [self setTableViewHeaderHidden:YES];
    }

}

そして、これらをヘッダーに追加しました。

@property (strong, nonatomic) IBOutlet UIView *theHeaderView;
@property (nonatomic)         BOOL                       hidingHeader;
@property (nonatomic)         BOOL                       isAnimatingHeader;
@property (nonatomic)         BOOL                       animateInTopHeader;

- (IBAction)longPress:(id)sender;

とにかく、それはうまくいきます。私が発見したのは、ヘッダービューへのテーブルビューの参照を完全に削除する必要があることです。そうしないと、テーブルビューは、ヘッダーのフレームの高さに基づいてセルの位置をシフトします。ヘッダープロパティに割り当てられます。さらに、IBOutletを介してヘッダーへの強力な参照を維持する必要があります。そうしないと、テーブルビューのヘッダーへの参照がなくなると破棄されます。

乾杯。

于 2012-10-29T01:51:49.853 に答える
2

それ以外の、

if (1 == 1) {
    CGRect frame = self.viewHeader.frame;
    frame.size.height = 0;
    self.viewHeader.frame = frame;

    self.viewHeader.hidden = YES;
}

として使用して、

if (1 == 1) {
    self.viewHeader.hidden = YES;
}

単に非表示にするのではなく、ビューが不要な[self.viewHeader removeFromSuperview]; 場合は、を使用します。削除後にビューを追加する場合は、[self.view addSubview:self.viewHeader];これらすべてが要件によって異なります。

アップデート:

例:-

if (data.something == 0) {
   //set frame1 as frame without tableHeaderView
   self.tableView.frame = frame1;
   self.tableView.tableHeaderView.hidden = YES;
} else {
   //set frame2 as frame with tableHeaderView
   self.tableView.frame = frame2;
   self.tableView.tableHeaderView.hidden = NO;
}

また、

if (data.something == 0) {
   //set frame1 as frame without tableHeaderView
   self.tableView.frame = frame1;
   self.tableView.tableHeaderView = nil;
} else {
   //set frame2 as frame with tableHeaderView
   self.tableView.frame = frame2;
   self.tableView.tableHeaderView = self.headerView; //assuming that self.headerview is the tableHeaderView created while creating the tableview
}

Update2:これは非常に単純なバージョンのアニメーションブロックです。

if (data.something == 0) {

    [UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationCurveEaseOut
                     animations:^{
                         //set frame1 as frame without tableHeaderView
                         self.tableView.frame = frame1;
                         self.tableView.tableHeaderView.hidden = YES; // or self.tableView.tableHeaderView = nil;

                     }
                     completion:^(BOOL finished){
                         //if required keep self.tableView.frame = frame1;
                     }
     ];

} else {
    [UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationCurveEaseIn
                     animations:^{
                         //set frame2 as frame with tableHeaderView
                         self.tableView.frame = frame2;
                         self.tableView.tableHeaderView.hidden = NO;// or self.tableView.tableHeaderView = self.headerView;
                     }
                     completion:^(BOOL finished){
                         //if required keep self.tableView.frame = frame2;
                     }];
}
于 2012-10-28T18:59:03.377 に答える