Tableheader视图自动布局问题

Sid*_*kan 5 objective-c uitableview uiview ios autolayout

我正在加载一个自定义UIView的XIB文件作为视图控制器内的uitableview的标题视图.

xib文件的文件所有者是viewcontroller.我在uiviewcontroller中声明了viewcontroller和uiview的接口.

ViewController.h

      @class ZeroStateView;

      @interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>

      @property (nonatomic, weak) IBOutlet CustomUITableView *tableView;
      @property (nonatomic,strong) NSMutableArray *dataArray;
      @property (weak, nonatomic) IBOutlet ZeroStateView *zeroStateView;


      @end


     @interface ZeroStateView : UIView
     @property (weak, nonatomic) IBOutlet AutoLayoutLabel *titleLabel;
     @property (weak, nonatomic) IBOutlet UIImageView *titleIcon;

     - (void)updateView;

     @end
Run Code Online (Sandbox Code Playgroud)

ViewController.m

    - (void)prepareHeaderViewForZeroState{
            ZeroStateView *sizingView = [ZeroStateView new];
            [[[NSBundle mainBundle] loadNibNamed:@"ZeroStateView" owner:self options:nil] objectAtIndex:0];
            sizingView = self.zeroStateView;
           [sizingView updateView];

           self.tableView.tableHeaderView = sizingView;

           UIView *headerView = self.tableView.tableHeaderView;



           CGFloat height = [headerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

         CGRect headerFrame = headerView.frame;
         headerFrame.size.height = height;
         headerView.frame = headerFrame;


         self.tableView.tableHeaderView = headerView;
     }

    @end

    @implementation ZeroStateView

    -(void)updateView{
      self.titleIcon.alpha = 0.5;

      UIFontDescriptor *titleFontDescriptor = [UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleSubheadline];

      self.titleLabel.text =  @"This is a long text message and its really long. This is a long text message and its really long. This is a long text message and its really long. This is a long text message and its really long. This is a long text message and its really long. This is a long text message and its really long. This is a long text message and its really long. This is a long text message and its really long. ";

     }
Run Code Online (Sandbox Code Playgroud)

AutolayoutLabel类重写了以下方法:

   - (void)setBounds:(CGRect)bounds {
      [super setBounds:bounds];

      // For multiline label, preferredMaxLayoutWidth always matches the frame width
      if (self.numberOfLines == 0 && bounds.size.width != self.preferredMaxLayoutWidth) {
          self.preferredMaxLayoutWidth = self.bounds.size.width;
          [self setNeedsUpdateConstraints];
      }
   }
Run Code Online (Sandbox Code Playgroud)

systemLayoutSizeFittingSize计算的高度:UILayoutFittingCompressedSize返回0.结果我得到以下视图作为表头视图: 标题视图,高度为0

当我添加如下的实际高度时,uilabel溢出.随着标签高度的增长,我期待uiview的成长.

 headerFrame.size.height = self.sizingView.frame.size.height;
Run Code Online (Sandbox Code Playgroud)

TableHeaderView没有正确调整大小

以下是UIViews约束的屏幕截图:

具有约束的ZeroState视图XIB文件

我在这里想念什么?有人能指出我吗?

更新 我为你们创建了一个示例项目,以确定问题是什么.

kei*_*ter 2

我以不同的方式重新实现了您到目前为止所拥有的内容。首先,我删除了嵌入UIViewZeroStateView.xibUIImageViewUILabelxib 的基础已经是 a UIView,因此无需向UIView其中添加另一个。

接下来我改变了周围的约束。我不记得我到底改变了哪些约束,所以我只是在这里列出它们:

  1. 约束条件UIImageView
    • 将中心 X 与超级视图对齐
    • 宽度 = 60
    • 高度 = 56
    • 超级视图的顶部空间 = 37
    • 底部空间UILabel= 31
  2. 约束条件UILabel
    • 超级视图的剩余空间 = 15
    • 超级视图的正确空间 = 15
    • 底部空间到超级视图 = 45
    • 顶部空间UIImageView= 31

上代码。在 中ViewController.hIBOutlet据我所知, 没有做任何事情,所以我将该属性更改为 read@property (strong, nonatomic) ZeroStateView *zeroStateView;

现在重要的变化是:ViewController.m。有两种UITableViewDelegate方法可以替代prepareHeaderViewForZeroState. 在 中viewDidLoad,初始化zeroStateView并将表视图的委托设置为self

- (void)viewDidLoad
{
    //...

    // Load the view
    self.zeroStateView = [[[NSBundle mainBundle] loadNibNamed:@"ZeroStateView" owner:self options:nil] firstObject];
    [self.zeroStateView updateView];
    self.zeroStateView.backgroundColor = [UIColor darkGrayColor];

    // Set self for table view delegate for -heightForHeaderInSection: and viewForHeaderInSection:
    self.dataTable.delegate = self;
}
Run Code Online (Sandbox Code Playgroud)

现在我们是表视图的委托,我们得到两个方法调用,这将允许我们自定义标题视图并适当地设置其高度。

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    // This will set the header view to the zero state view we made in viewDidLoad
    return self.zeroStateView;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    // sizeToFit describes the size that the label can fit itself into.
    // So we are saying that the label can use the width of the view and infinite height.
    CGSize sizeToFit = CGSizeMake(self.view.frame.size.width, MAXFLOAT);

    // Then we ask the label to tell us how it can fit in that size.
    // The label will respond with the width of the view and however much height it needs
    // to display its text. This is the magic of how it grows vertically.
    CGSize size = [self.zeroStateView.titleLabel sizeThatFits:sizeToFit];

    // Add the height the label needs to the overall zero state view. This should be changed
    // to the height of the UIImage + the height we just got + the whitespace above and below
    // each of these views. You can handle that part.
    return self.zeroStateView.frame.size.height + size.height;
}
Run Code Online (Sandbox Code Playgroud)

我在此处将更改上传到 Dropbox 。