【问题标题】:UITableView's tableHeaderView height property is changed to strange values during load and rotationUITableView 的 tableHeaderView 高度属性在加载和旋转期间更改为奇怪的值
【发布时间】:2012-03-04 03:06:21
【问题描述】:

我有一个自定义 UIView,我在 loadView 期间将其设置为 UITableView 的 tableHeaderView 属性:

headerView = [[MYViewClass alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 120)];
[headerView sizeToFit];

self.tableView.tableHeaderView = headerView;

视图绘制不正确,部分视图被剪裁,表格上方有空白。旋转设备时,视图几乎消失。向后旋转时,视图现在比标题的空间更大,并遮住了表格中的一些单元格。

为了解决问题,我在自定义视图类中覆盖了 setFrame 方法:

- (void) setFrame:(CGRect)frame {
    [super setFrame:frame];
    NSLog(@"%@ - %@", NSStringFromSelector(_cmd), NSStringFromCGRect(frame));
}

我还在 NSLog 语句上设置了一个断点,这样我就可以看到所谓的 setFrame 了,我得到了一些我无法解释的奇怪结果,希望有人能阐明正在发生的事情和原因。

加载视图期间

1. initWithFrame calls: setFrame: - {{0, 0}, {320, 120}}
2. sizeToFit calls: setFrame: - {{0, 0}, {320, 109}}
3. setTableHeaderView calls:  setFrame: - {{0, 0}, {320, 109}}
4. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 109}}
5. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {320, 65}}
6. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 65}}
7. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 65}}

向左旋转设备

1. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {480, 0}}
2. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {480, 0}}
3. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {480, 12}}
4. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {480, 12}}

向右旋转设备

1. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {320, 172}}
2. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 172}}
3. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {320, 160}}
4. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 160}}

这解释了为什么我的视图最初看起来被截断,然后几乎消失并最终与单元格重叠。看来_resizeWithOldSuperviewSize 是罪魁祸首,我不明白为什么要调用它以及它从哪里得到这些奇怪的值。

我通过在viewDidAppear:didRotateFromInterfaceOrientation: 中调用[self.tableView.tableHeaderView sizeToFit] 来解决一个非常垃圾的工作,这会将框架恢复到正确的大小,但是重绘很糟糕,因为两者都发生在视图可见或旋转动画之后.尝试在视图可见之前的任何时间设置此设置会导致 _resizeWithOldSuperViewSize 将框架设置回这些奇怪的大小。

【问题讨论】:

    标签: iphone ios uitableview frame autorotate


    【解决方案1】:

    创建一个新的 xib 文件,然后在 xib 文件中自定义您喜欢的大小。说xib叫做customHeader (.xib) 声明:

      IBOutlet UIView *customView;
    

    将 customView 分配给您的 xib 中的该视图。

      -(UIView *)viewOfCategory;
    

    在.m:

       -(UIView *)viewOfCategory {
    
    if (!customView) {
    
            [[NSBundle mainBundle] loadNibNamed:@"customHeader" owner:self options:nil];
    }
    
    return customView;
       }
    

    然后调用这个 UITableView 方法:

      -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:        (NSInteger)section {
    
    return [self customView];
    
    }
    

    那么最后也是最重要的就是回答您的问题了!实现这个其他 UITableView 方法:

       -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    
    // You can just return default size of your xib: return [[self viewOfCategory]          bounds].size.height;
    
    
           // Or you can return custom size using  CGRect or whatever. 
         }
    

    【讨论】:

    • 很抱歉,但我不认为是这样。我不是为节标题设置视图,而是为整个表格设置标题。
    【解决方案2】:

    它将通过UIViewautoresizingMask 属性帮助您read up 了解Apple 的视图大小调整方案。可能的值是:

    enum {
        UIViewAutoresizingNone                 = 0,
        UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
        UIViewAutoresizingFlexibleWidth        = 1 << 1,
        UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
        UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
        UIViewAutoresizingFlexibleHeight       = 1 << 4,
        UIViewAutoresizingFlexibleBottomMargin = 1 << 5
    };
    typedef NSUInteger UIViewAutoresizing;
    

    毫无疑问,经过一些实验后,您会找到合适的调整大小蒙版组合来解决您的问题。

    另外,请注意sizeToFit,根据同一文档来源“调整并移动接收器视图,使其仅包含其子视图。”在创建视图之后并将其放入表头之前调用它似乎不合适。

    【讨论】:

    • 嗨 Mundi,感谢您为我指明了正确的方向。我已经熟悉自动调整掩码并将我的 headerView 的自动调整掩码设置为 None 确实解决了这个问题。我仍然对我拥有的自动调整大小蒙版(flexibleRightMargin 和 flexibleBottomMargin)为什么会导致这种行为感到困惑。为什么表格要在设置 headerView 后直接尝试调整框架高度?还有为什么当将自动调整掩码设置为无时,标题在旋转后正确显示(其框架已更改以适合表格的宽度)。有什么想法吗?
    • 实际上,擦洗它。将其设置为 None 似乎可以修复它,但事实并非如此。它停止了这些对_resizeWithOldSuperViewSize 的额外调用,并且正确指定了视图的宽度,但不再调整高度大小。我需要做一些进一步的测试。
    【解决方案3】:

    当我想在底部使用带有 SearchBar 和一些自定义 UI 的表头视图时遇到了完全相同的问题。有趣的是,如果你只保留 SearchBar,它就可以完美运行。

    所以我决定应用一个非常肮脏的技巧,将自定义 UIView 的覆盖 Frame 设置器中的 Frame 高度(您正在记录帧大小)重置为您需要的东西(在您的情况下为 120)。

    - (void) setFrame:(CGRect)frame {
        frame.Height = 120;
        [super setFrame:frame];
    }
    

    之后,旋转时没有奇怪的标题视图和表格重叠。希望对您有所帮助。

    附:顺便说一句,我在自定义 UIView 中使用自动布局。

    【讨论】:

    • 该死的,我差点把剩下的头发都掉光了。我通常不写“谢谢”cmets,但这是当之无愧的。
    【解决方案4】:

    您需要正确设置固有大小和 autoresizingMask。一旦你这样做了,UITableView 将停止搞砸你的 tableHeaderView。

    例如,如果您希望标题具有取决于其内容的固定高度,但您希望标题使用整个表格宽度,您会这样做:

    1.使用以下自动调整掩码配置创建您的视图(因此表格不会尝试增加标题视图高度):


    2. 使用 AutoLayout 添加您的子视图,使顶部/底部锚点与您的视图相匹配(这是您的子视图定义标题视图的高度)
    3. 像这样添加你的标题视图:

    let headerView : CustomView? = CustomView.fromNib()
    headerView?.sizeToFit()
    
    tableView.tableHeaderView = headerView
    

    【讨论】:

    • Wau 这么愚蠢的错误...而且我已经通过 viewWillTransitionToSize 黑客来修复它...只需关闭自动调整高度就足够了。
    猜你喜欢
    • 2015-11-14
    • 1970-01-01
    • 2011-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-02
    • 1970-01-01
    • 2013-12-12
    相关资源
    最近更新 更多