2017-09-25 84 views
1

我创建了一个非常简单的测试用例来重现此问题。UITableView tableFooterView显示在UITableView的顶部 - 错误

我想以编程方式设置页脚视图到tableview。请注意,我指的是在tableview的最底部的页脚 - 而不是页脚(大多数堆栈溢出的答案让他们感到困惑)。

这里是我的代码非常简单:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    UIView *footerContainer = [[UIView alloc] initWithFrame:CGRectZero]; 
    footerContainer.backgroundColor=[UIColor greenColor]; 
    footerContainer.translatesAutoresizingMaskIntoConstraints=NO; 
    [footerContainer addConstraints:@[[NSLayoutConstraint 
             constraintWithItem:footerContainer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual 
             toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:100 
             ], 
             [NSLayoutConstraint 
             constraintWithItem:footerContainer attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual 
             toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:[UIScreen mainScreen].bounds.size.width 
             ]]]; 

    self.mytableview.tableFooterView=footerContainer; 
    [self.view setNeedsLayout]; 
    [self.view layoutIfNeeded]; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 
    return 10; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; 
    cell.textLabel.text=[NSString stringWithFormat:@"%ld",indexPath.row]; 
    return cell; 
} 

然而,结果是这样的:

enter image description here

你可能注意到了,页脚显示上的tableview的顶部。这是一个错误还是我错过了什么?

如果我将tableFooterView更改为tableHeaderView,那么它工作正常。所以我期待着同样的脚步也能工作,但事实并非如此。

+0

设置'translatesAutoresizingMaskIntoConstraints = NO'很可能会破坏tableview用于定位页脚的任何方法。 – dan

+0

您是否使用约束,因为您将(或可能)在页脚视图中具有动态内容?如果是这样,我可以给你一个解决方案...... – DonMag

+0

@DonMag是的,我一直在寻找一种解决方案,它将使用约束来设置它,而不是手动设置框架。我的实际应用具有动态大小的页脚内容。 –

回答

0

我已经尝试了与swift中的显式帧值相同的操作,并且我实现了您所要求的行为,如果您认为它很好,请尝试使用显式帧值。如果不需要,则移除布局约束。

@IBOutlet weak var tableView: UITableView! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    tableView.delegate = self 
    tableView.dataSource = self 

    let footerView = UIView(frame: CGRect.init(x: 0, y: 0, width: tableView.frame.width, height: 50)) 
    footerView.backgroundColor = UIColor.green 
    tableView.tableFooterView = footerView 
} 

extension ViewController: UITableViewDelegate, UITableViewDataSource { 

func numberOfSections(in tableView: UITableView) -> Int { 
    return 1 
} 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return 10 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") 
    cell?.textLabel?.text = "\(indexPath.row)" 
    return cell! 
} 

}

enter image description here

+0

确实对我有效。这是否意味着自动布局与页脚视图的越野车?我应该将它记录为Apple的错误吗? –

+0

@PranoyC:很高兴它解决了你的问题,并对不起,我没有使用手动自动布局代码的风格,并不能帮助你直接回答你的bug报告的想法,但我会建议,如果你要提出一个问题,尝试在视图控制器中设置简单视图的自动布局后引发。 – Bharath

0

动态尺寸UITableView页眉和页脚的观点并不总是玩自动布局很好,所以你需要给它一点帮助。

下面是一个为页脚视图创建简单UIView并添加“展开”UILabel(将行数设置为零)的示例。页脚视图是使用显式CGRect为其框架创建的,并且标签以自动布局约束固定到所有四边。

viewDidLayoutSubviews()中,我们告诉自动布局根据其内容约束来计算页脚视图的框架,然后我们更新框架值(特别是高度)。

// 
// this assumes IBOutlet has been set for "theTableView" 
// 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    // standard stuff 
    [_theTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"simpleCell"]; 
    _theTableView.delegate = self; 
    _theTableView.dataSource = self; 

    // instantiate a view for the table footer 
    // width doesn't matter (it will be stretched to fit the table by default) 
    // set height to a big number to avoid a "will attempt to break constraint" warning 
    UIView *footerContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1000)]; 

    // give it a color so we can see it 
    footerContainer.backgroundColor=[UIColor greenColor]; 

    // set the footer view 
    _theTableView.tableFooterView = footerContainer; 


    // instantiate a label to add to the footer view 
    UILabel *aLabel = [UILabel new]; 

    // auto-sizing the height, so set lines to zero 
    aLabel.numberOfLines = 0; 

    // give it a color so we can see it 
    aLabel.backgroundColor = [UIColor yellowColor]; 

    // set the text to 8 lines for demonstration purposes 
    aLabel.text = @"Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\nLine 8"; 

    // standard, for auto-sizing 
    aLabel.translatesAutoresizingMaskIntoConstraints = NO; 

    // add the label to the footer view 
    [footerContainer addSubview:aLabel]; 

    // constraint the label to 8-pts from each edge... 
    [aLabel.topAnchor constraintEqualToAnchor:footerContainer.topAnchor constant:8.0].active = YES; 
    [aLabel.leftAnchor constraintEqualToAnchor:footerContainer.leftAnchor constant:8.0].active = YES; 
    [aLabel.rightAnchor constraintEqualToAnchor:footerContainer.rightAnchor constant:-8.0].active = YES; 
    [aLabel.bottomAnchor constraintEqualToAnchor:footerContainer.bottomAnchor constant:-8.0].active = YES; 

} 

- (void)viewDidLayoutSubviews { 
    [super viewDidLayoutSubviews]; 

    // get a reference to the table's footer view 
    UIView *currentFooterView = [_theTableView tableFooterView]; 

    // if it's a valid reference (the table *does* have a footer view) 
    if (currentFooterView) { 

     // tell auto-layout to calculate the size based on the footer view's content 
     CGFloat newHeight = [currentFooterView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height; 

     // get the current frame of the footer view 
     CGRect currentFrame = currentFooterView.frame; 

     // we only want to do this when necessary (otherwise we risk infinite recursion) 
     // so... if the calculated height is not the same as the current height 
     if (newHeight != currentFrame.size.height) { 
      // use the new (calculated) height 
      currentFrame.size.height = newHeight; 
      currentFooterView.frame = currentFrame; 
     } 

    } 

} 

当尝试使自动调整表格视图标题视图正常工作时,这也会很有帮助。