Objective c 隐藏UITableView标题部分

Objective c 隐藏UITableView标题部分,objective-c,ios,Objective C,Ios,我正在使用以下代码隐藏视图,并且该视图根据视图中的条件占用的空间将显示: - (void)viewWillAppear:(BOOL)animated { Data* data = [Data shared]; if (data.something == 0) { CGRect frame = self.tableView.tableHeaderView.frame; frame.size.height = 0; self.ta

我正在使用以下代码隐藏视图,并且该视图根据视图中的条件占用的空间将显示:

- (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,但一旦调用了代码,headerView就会消失,直到UITableView被销毁(我想我可以使用tableHeader的IBOutlet来修复它,但听起来也不对

更新1:再次尝试,但代码无效:

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

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;
}
或者

更新2:这是一个非常简单的动画块版本

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;
                     }];
}

数据源方法
tableView:heightForHeaderInSection:
实际上与与表视图的
tableViewHeader
属性关联的视图无关。这里有两种不同类型的标题,一种是位于tableView顶部的标题,可以在其中放置搜索栏等内容,另一种是multiple标题,可以使其在表视图中的每个部分出现一个

据我所知,
tableViewHeader
视图通常是在nib文件中配置的,我不知道该表视图调用了任何允许对其进行任何配置的数据源方法,因此您必须手动进行配置。坦率地说,如果您的代码正常工作,这将是一个很好的方法。隐藏它将使表视图仍然是一个问题ct就像它在那里一样…完全移除它会使它无法收回,因为它被释放

(然而,正如您所说,您可以使用指向页眉视图的IBOutlet,只要您将其作为强引用,然后您可以稍后以某种方式将其重新插入表中……嗯,尽管如何将视图添加到表视图的滚动视图中并正确定位它的机制可能很烦人。)

我唯一的建议是将帧高度设置为零,这样你可以得到一个很好的过渡效果,比如。但是,是的,我想说你已经找到了最好的方法

编辑:

代码,你说呢?我把它当作一个挑战:)

我在标题中添加了以下内容:

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

- (IBAction)longPress:(id)sender;
不管怎样,它工作得很好。我确实发现,您肯定必须消除表视图对标题视图的引用,否则它不会消失,并且当表视图被分配回其标题属性时,它将根据标题帧的高度移动单元格的位置。此外,您必须通过IBOutlet维护对标头的强引用,否则当您取消表视图对它的引用时,它会被丢弃


干杯。

不管你如何隐藏视图,因为一旦视图被隐藏,就无法与视图交互。如果您希望将其完全删除,则可以使用removeFromSuperview方法。或者使用其他方法更改视图的索引,但如果要将其隐藏,则不需要更改帧大小以将其隐藏。是否有原因不能只说
self.tableView.tableHeaderView=nil
?如果我从superview中删除视图,视图占用的空间仍将存在。可能是因为视图位于tableview标题内。如果它是tableview标题,则需要重置标题高度以反映此更改。在桌面高度的代理中,返回0.0f或适当的高度。这将重新调整tableview.Oops。抱歉,我以为您是通过viewForheader方法声明它的。对于tableView.tableHeaderView,这没有帮助。您必须设置TabeView的框架,而不是此框架。首先设置tableView.tableHeaderView=nil,然后将tableView的框架设置为tableView.frame=framewithoutheader;在else部分,可以设置tableView.tableHeaderView=self.headerview;再次将tableview的frame设置为tableview.frame=framewithheader;非常感谢。我想你是对的,但我要把它交给ACB,因为他发布了一些代码,可以帮助其他人。
- (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;
            }

        }

    }
}
- (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;