zic10
zic10

Reputation: 2330

Setting a custom UITableView tableHeaderView

I'm working on a project and I'm trying to set the table view header to a complex View. This project does not use auto layout and all constrains are handled programatically. I have a Parent View controller that contains the table view.

Here is the code for the parent view controller (Delegate and Data Source are in parent)

@property (nonatomic, strong) NSMutableArray *array;

- (void)viewDidLoad
{
  [super viewDidLoad];

  self.array = [NSMutableArray new];

  [self.array addObject:@"One"];
  [self.array addObject:@"Two"];
  [self.array addObject:@"Three"];
  [self.array addObject:@"Four"];

  [self.view addSubview:self.detailedTableView];
}

- (void)updateViewConstraints
{

  [super updateViewConstraints];

  NSDictionary *views = @{
                          @"detailedTable": self.detailedTableView,
                          };



  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[detailedTable]-0-|" options:0 metrics:nil views:views]];
  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[detailedTable]-0-|" options:0 metrics:nil views:views]];

                                                   constant:0.f]];


}

-(UITableView *)detailedTableView
{
  if(!_detailedTableView)
  {
    _detailedTableView = [UITableView new];
    _detailedTableView.dataSource = self;
    _detailedTableView.delegate   = self;
    _detailedTableView.separatorStyle                 = UITableViewCellSeparatorStyleNone;
    _detailedTableView.showsVerticalScrollIndicator   = NO;
    _detailedTableView.separatorInset                 = UIEdgeInsetsZero;
    _detailedTableView.translatesAutoresizingMaskIntoConstraints = NO;
  }

  return _detailedTableView;
}

In the child view controller that inherits from the parent, I'm trying to set the header view to a custom view that is contained in the child view controller. Here is the relevant code:

@interface ChildViewController ()

@property (nonatomic, strong) UIView        *testView;
@end

@implementation ChildViewController

- (void)viewDidLoad
{

  [super viewDidLoad];

  self.detailedTableView.tableHeaderView = self.testView;
}

-(UIView *)testView
{
  if(!_testView)
  {
    _testView = [UIView new];
    _testView.backgroundColor = [UIColor orangeColor];
    _testView.translatesAutoresizingMaskIntoConstraints = NO;
  }

  return _testView;
}

- (void)updateViewConstraints
{

  [super updateViewConstraints];

  NSDictionary *views = @{
      @"test"         : self.testView
  };

  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[test(width)]-0-|" options:0 metrics:metrics views:views]];
  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[test(100)]" options:0 metrics:metrics views:views]];


}

I'm not setting the widths or heights through the frame property but rather through the constraints. However, this code produces the image below on iOS 8.1 and completely crashes on iOS 7.1

I can see that the dummy view is being added but it is not in the appropriate place to be the tableHeaderView as it is covering up the other array items in the UITable. Plus this doesn't work on iOS 7.1 as it throws this error message:

  *** Assertion failure in -[UITableView layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2935.137/UIView.m:8794
    2015-01-03 22:33:05.540 Saloote A[10073:607] This is where we save the application data during a exception
    2015-01-03 22:33:05.541 Saloote A[10073:607] Exception: Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.

enter image description here

Upvotes: 0

Views: 1197

Answers (1)

Suen
Suen

Reputation: 1120

This occurs because your test's view is not subview of vc.view directly.

You can only add constraints for your child view.

You can use setFrame instead of autoLayout.

Upvotes: 1

Related Questions