ios 带有 IB 的 UITableViewHeaderFooterView

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19162246/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:00:26  来源:igfitidea点击:

UITableViewHeaderFooterView with IB

iosuitableviewinterface-builder

提问by hpique

After many years of avoiding Interface Builder like the plague I decided to give it a chance. It's not easy.

在像瘟疫一样避免使用 Interface Builder 多年之后,我决定给它一个机会。这是不容易的。

Take UITableViewHeaderFooterViewfor example. Like UITableViewCell, it has a contentViewproperty. Unlike UITableViewCell, it doesn't have a template in the Interface Builder object library.

UITableViewHeaderFooterView为例。比如UITableViewCell,它有一个contentView属性。与 不同UITableViewCell,它在 Interface Builder 对象库中没有模板。

How are we supposed to use Interface Builder to create a UITableViewHeaderFooterViewwith the content inside contentView? The fact that registerNib:forHeaderFooterViewReuseIdentifier:exists makes me think this should be possible somehow.

我们应该如何使用 Interface Builder 来创建一个UITableViewHeaderFooterView里面的内容contentViewregisterNib:forHeaderFooterViewReuseIdentifier:存在的事实让我认为这应该以某种方式成为可能。

回答by hpique

This is the closest I got to define a UITableViewHeaderFooterViewwith IB:

这是我最接近UITableViewHeaderFooterView用 IB定义的:

a. Create a UITableViewHeaderFooterViewsubclass (MYTableViewHeaderFooterView).

一种。创建UITableViewHeaderFooterView子类 ( MYTableViewHeaderFooterView)。

b. Create a nib file for the contentViewonly (MYTableViewHeaderFooterContentView).

湾 为contentView唯一的 ( MYTableViewHeaderFooterContentView)创建一个 nib 文件。

c. Override initWithReuseIdentifier:in MYTableViewHeaderFooterViewto load the view defined in the nib file.

C。覆盖initWithReuseIdentifier:inMYTableViewHeaderFooterView以加载在 nib 文件中定义的视图。

 - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithReuseIdentifier:reuseIdentifier];
    if (self)
    {
        NSArray* objects = [[NSBundle mainBundle] loadNibNamed:@"MYTableViewHeaderFooterView"
                                                          owner:self
                                                        options:nil];
        UIView *nibView = [objects firstObject];
        UIView *contentView = self.contentView;
        CGSize contentViewSize = contentView.frame.size;
        nibView.frame = CGRectMake(0, 0, contentViewSize.width, contentViewSize.height);
        [contentView addSubview:nibView];
    }
    return self;
}

d. Register the MYTableViewHeaderFooterViewclass instead of the nib file:

d. 注册MYTableViewHeaderFooterView类而不是 nib 文件:

[self.tableView registerClass:[MYTableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"cell"];

回答by Markus Rautopuro

I just did this with a footer and a NIB file:

我只是用一个页脚和一个 NIB 文件做到了这一点:

  1. Create an empty NIB file with name CustomFooterView.xib.
  2. Edit the NIB file in the Interface Builder and change the topmost UIView custom class to UITableViewHeaderFooterView.
  3. Disable Auto Layoutin the NIB.
  4. Set the background color of UITableViewHeaderFooterViewview to Default.
  5. Make the view freeform and correct size (for example 320 x 44).
  6. In your UITableViewController viewDidLoadregister the NIB file to be used with a reuse identifier:

    [self.tableView registerNib:[UINib nibWithNibName:@"CustomFooterView" bundle:nil] forHeaderFooterViewReuseIdentifier:@"Footer"];
    
  7. In your UITableViewController's tableView:viewForFooterInSection:use the Footer identifier to fetch and return the view:

    - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
    {
        if (section == 2)
            return [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"Footer"];
    
        return nil; 
    }
    
  1. 创建一个名为CustomFooterView.xib的空 NIB 文件。
  2. 在 Interface Builder 中编辑 NIB 文件并将最顶层的 UIView 自定义类更改为 UITableViewHeaderFooterView。
  3. 在 NIB 中禁用自动布局
  4. UITableViewHeaderFooterView视图的背景颜色设置为Default
  5. 使视图自由形式和正确的大小(例如 320 x 44)。
  6. 在您的 UITableViewController 中viewDidLoad注册要与重用标识符一起使用的 NIB 文件:

    [self.tableView registerNib:[UINib nibWithNibName:@"CustomFooterView" bundle:nil] forHeaderFooterViewReuseIdentifier:@"Footer"];
    
  7. 在您的 UITableViewController 中,tableView:viewForFooterInSection:使用页脚标识符来获取并返回视图:

    - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
    {
        if (section == 2)
            return [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"Footer"];
    
        return nil; 
    }
    

回答by Jean-Pierre

Just use the UITableViewCelltemplate in IB. Change the class to UITableViewHeaderFooterView. Here you have it... with a contentView.

只需使用IB 中的UITableViewCell模板。将类更改为UITableViewHeaderFooterView。在这里你有它......带有一个内容视图。

回答by mdziadkowiec

I found easier way.

我找到了更简单的方法。

1) Create subclass of UITableViewCell and set your xib file

1) 创建 UITableViewCell 的子类并设置您的 xib 文件

2) In your header file change superclass from UITableViewCell to UITableViewHeaderFooterView

2)在您的头文件中,将超类从 UITableViewCell 更改为 UITableViewHeaderFooterView

That's it.

就是这样。

回答by pheedsta

This solution works well, especially if you want it to work correctly in relation to Readable Content Guides (introduced in iOS 9). Instead of creating a UITableViewHeaderFooterView, it simply returns a custom UIView (from a XIB) when it is required:

此解决方案效果很好,特别是如果您希望它与可读内容指南(在 iOS 9 中引入)相关时正常工作。它没有创建 UITableViewHeaderFooterView,而是在需要时简单地返回一个自定义 UIView(来自 XIB):

  1. Create a new class that subclasses UIView ("AwesomeHeaderView") and create your outlets:

    class AwesomeHeaderView: UIView {
        @IBOutlet var myCustomLabel: UILabel!
    }
    
  2. Create a XIB file ("MyNewHeader.xib") with a UIViewas the parent view. Change the parent UIView's class type to your newly created custom class ("AwesomeHeaderView"). As required, add any additional views as it's children and link outlets etc. (NB: To ensure views comply to the new Readable Content Guides I check the boxes "Preserve Superview Margins" and "Follow Readable Width" on all objects).
  3. In your UIViewController (or UITableViewController) call the following:

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        guard let headerView = NSBundle.mainBundle().loadNibNamed("MyNewHeader", owner: nil, options: nil).first as? AwesomeHeaderView else {
            return nil
        }
    
        // configure header as normal
        headerView.backgroundColor = UIColor.redColor()
        headerView.myCustomLabel.textColor = UIColor.whiteColor()
        headerView.myCustomLabel.text = "Hello"
    
        return header
    }
    
  1. 创建一个继承 UIView 的新类(“AwesomeHeaderView”)并创建您的插座:

    class AwesomeHeaderView: UIView {
        @IBOutlet var myCustomLabel: UILabel!
    }
    
  2. 创建一个以UIView作为父视图的 XIB 文件(“MyNewHeader.xib”)。将父 UIView 的类类型更改为您新创建的自定义类(“AwesomeHeaderView”)。根据需要,添加任何其他视图,因为它是子视图和链接出口等(注意:为了确保视图符合新的可读内容指南,我选中了所有对象上的“保留超级视图边距”和“遵循可读宽度”框)。
  3. 在您的 UIViewController(或 UITableViewController)中调用以下内容:

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        guard let headerView = NSBundle.mainBundle().loadNibNamed("MyNewHeader", owner: nil, options: nil).first as? AwesomeHeaderView else {
            return nil
        }
    
        // configure header as normal
        headerView.backgroundColor = UIColor.redColor()
        headerView.myCustomLabel.textColor = UIColor.whiteColor()
        headerView.myCustomLabel.text = "Hello"
    
        return header
    }
    

回答by dklt

Following workarounds enable me to drag-assign IB items to codeas variables. UITableViewHeaderFooterView doesnt allow that out of the box.

以下变通方法使我能够将 IB 项目拖放到代码中作为变量。UITableViewHeaderFooterView 不允许开箱即用。

  1. create a (New File/CocoaTouchClass)UITableViewHeaderFooterView .h.m.xib normally

  2. temporarily rename superclassfrom UITableViewHeaderFooterView to UIView. Drag-assign your UI items to code as needed, IB will assign key-value correctly, revert back to UITableViewHeaderFooterView when done.

  3. in your tableview, use registerNib:to register instead of registerClass:. prepare the rest of tableview normally (ie:dequeue).
  1. 通常创建一个(新文件/CocoaTouchClass)UITableViewHeaderFooterView .hmxib

  2. 暂时将超类从 UITableViewHeaderFooterView重命名为 UIView。根据需要将您的 UI 项目拖放到代码中,IB 将正确分配键值,完成后恢复为 UITableViewHeaderFooterView。

  3. 在您的 tableview 中,使用registerNib:来注册而不是registerClass:。正常准备tableview的其余部分(即:出队)。

回答by xianwill

I also experienced the deprecation warning above and an inability to set background color, etc.. Eventually, I found that according to Apple's documentation,

我也遇到了上面的弃用警告和无法设置背景颜色等。 最终,我发现根据Apple的文档,

You can use [the UITableViewHeaderFooter] class as-is without subclassing in most cases. If you have custom content to display, create the subviews for your content and add them to the view in the contentView property.

在大多数情况下,您可以按原样使用 [UITableViewHeaderFooter] 类而无需子类化。如果您有自定义内容要显示,请为您的内容创建子视图并将它们添加到 contentView 属性中的视图中。

Following that suggestion, I took these steps:

根据该建议,我采取了以下步骤:

  1. I created a xib with a view that extends only UIView--not UITableViewHeaderFooter.
  2. In viewDidLoad I registered the built-in UITableViewHeaderFooter class

    tableView.registerClass(UITableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: "sectionHeader")

  3. In the viewForHeaderInSection delegate of my UITableViewController, I dequeued the header view by that identifier and checked to see if the header view already contained a subview. If not, I load my xib and add it. Then I set my text as needed.

    override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let header = self.tableView.dequeueReusableHeaderFooterViewWithIdentifier("sectionHeader")!
    
    if header.contentView.subviews.count == 0 { header.contentView.addSubview(loadMyNib()) }
    
    let myView = header.contentView.subviews[0] as! MyView
    myView.label.text = "..."
    
  1. 我创建了一个 xib,其视图只扩展了 UIView——而不是 UITableViewHeaderFooter。
  2. 在 viewDidLoad 我注册了内置的 UITableViewHeaderFooter 类

    tableView.registerClass(UITableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: "sectionHeader")

  3. 在我的 UITableViewController 的 viewForHeaderInSection 委托中,我通过该标识符将标题视图出列并检查标题视图是否已经包含子视图。如果没有,我加载我的 xib 并添加它。然后我根据需要设置我的文本。

    override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let header = self.tableView.dequeueReusableHeaderFooterViewWithIdentifier("sectionHeader")!
    
    if header.contentView.subviews.count == 0 { header.contentView.addSubview(loadMyNib()) }
    
    let myView = header.contentView.subviews[0] as! MyView
    myView.label.text = "..."
    

This seems to work, leverages reuse, and does not produce any warnings.

这似乎有效,利用了重用,并且不会产生任何警告。

https://developer.apple.com/library/prerelease/tvos/documentation/UIKit/Reference/UITableViewHeaderFooterView_class/index.html#//apple_ref/occ/instm/UITableViewHeaderFooterView/prepareForReuse

https://developer.apple.com/library/prerelease/tvos/documentation/UIKit/Reference/UITableViewHeaderFooterView_class/index.html#//apple_ref/occ/instm/UITableViewHeaderFooterView/prepareForReuse

回答by BooRanger

An awful hack I figured out is to create a IBOutlet contentView ih your headerFooter class and hook it up to the your "content view" in the xib (Have your xib laid out like a tableViewCell, View->contentView->mystuff).

我发现的一个可怕的技巧是在您的 headerFooter 类中创建一个 IBOutlet contentView 并将其连接到您在 xib 中的“内容视图”(让您的 xib 像 tableViewCell 一样布局,View->contentView->mystuff)。

You'll get warnings, ok ready for the hack...

你会收到警告,准备好接受黑客攻击......

Delete the IBOutlet and it will all work.

删除 IBOutlet,一切都会好起来的。