当前位置: 首页 > 面试题库 >

Swift-如何使用XIB文件创建自定义viewForHeaderInSection?

燕星鹏
2023-03-14
问题内容

我可以像下面这样以编程方式创建简单的自定义viewForHeaderInSection。但是我想做更多复杂的事情,例如与不同的类连接,并像tableView单元格一样达到其属性。简而言之,我想看看我在做什么。

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    if(section == 0) {

        let view = UIView() // The width will be the same as the cell, and the height should be set in tableView:heightForRowAtIndexPath:
        let label = UILabel()
        let button   = UIButton(type: UIButtonType.System)

        label.text="My Details"
        button.setTitle("Test Title", forState: .Normal)
        // button.addTarget(self, action: Selector("visibleRow:"), forControlEvents:.TouchUpInside)

        view.addSubview(label)
        view.addSubview(button)

        label.translatesAutoresizingMaskIntoConstraints = false
        button.translatesAutoresizingMaskIntoConstraints = false

        let views = ["label": label, "button": button, "view": view]

        let horizontallayoutContraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[label]-60-[button]-10-|", options: .AlignAllCenterY, metrics: nil, views: views)
        view.addConstraints(horizontallayoutContraints)

        let verticalLayoutContraint = NSLayoutConstraint(item: label, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1, constant: 0)
        view.addConstraint(verticalLayoutContraint)

        return view
    }

    return nil
}


func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 50
}

有没有人可以解释如何使用xib创建自定义tableView标头视图?我遇到过旧的Obj-C主题,但是我是Swift语言的新手。如果有人详细解释,那太好了。

1.问题: 按钮@IBAction不与我的ViewController连接。 (固定)

通过File的所有者ViewController基类解决(单击左侧轮廓菜单。)

2. 问题 页眉高度问题 (已修复)

解决了在 viewForHeaderInSection :方法中添加 headerView.clipsToBounds = true
问题

当我在viewController中使用此方法添加ImageView甚至具有相同的高度限制时,它流过tableView的行看起来就像picture。

 func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 120
}

如果我使用viewDidLoad中的automaticAdjustsScrollViewInsets,在这种情况下,图像流在navigationBar下。-固定-

self.automaticallyAdjustsScrollViewInsets = false

3.问题: 如果“查看”下的按钮 (固定)

@IBAction func didTapButton(sender: AnyObject) {
    print("tapped")

    if let upView = sender.superview {
        if let headerView = upView?.superview as? CustomHeader {
            print("in section \(headerView.sectionNumber)")
        }

    }
}

问题答案:

基于NIB的标头的典型过程为:

  1. UITableViewHeaderFooterView至少创建一个带有标签出口的子类。您可能还想给它一些标识符,通过它可以反向工程此头对应的部分。同样,您可能希望指定一个协议,标题可以通过该协议将事件通知给视图控制器(例如单击按钮)。因此,在Swift 3及更高版本中:

    // if you want your header to be able to inform view controller of key events, create protocol
    

    protocol CustomHeaderDelegate: class {
    func customHeader(_ customHeader: CustomHeader, didTapButtonInSection section: Int)
    }

    // define CustomHeader class with necessary delegate, @IBOutlet and @IBAction:

    class CustomHeader: UITableViewHeaderFooterView {
    static let reuseIdentifier = “CustomHeader”

    weak var delegate: CustomHeaderDelegate?
    
    @IBOutlet weak var customLabel: UILabel!
    
    var sectionNumber: Int!  // you don't have to do this, but it can be useful to have reference back to the section number so that when you tap on a button, you know which section you came from; obviously this is problematic if you insert/delete sections after the table is loaded; always reload in that case
    
    @IBAction func didTapButton(_ sender: AnyObject) {
        delegate?.customHeader(self, didTapButtonInSection: section)
    }
    

    }

  2. 创建NIB。就个人而言,我为NIB提供与基类相同的名称,以简化项目中文件的管理并避免混淆。无论如何,关键步骤包括:

    • 创建视图NIB,或者如果您以空的NIB开始,则将视图添加到NIB;

    • 将视图的基类设置为您的UITableViewHeaderFooterView子类(在我的示例中为CustomHeader);

    • 在IB中添加您的控件和约束;

    • 胡克@IBOutlet在您的银行代码网点引用;

    • 将按钮连接到@IBAction; 和

    • 对于NIB中的根视图,请确保将背景色设置为“默认”,否则您将收到有关更改背景色的烦人警告。

  3. viewDidLoad视图控制器中,注册NIB。在Swift 3及更高版本中:

    override func viewDidLoad() {
    super.viewDidLoad()
    
    tableView.register(UINib(nibName: "CustomHeader", bundle: nil), forHeaderFooterViewReuseIdentifier: CustomHeader.reuseIdentifier)
    

    }

  4. 在中viewForHeaderInSection,使用您在上一步中指定的相同标识符出队可重用视图。完成此操作后,您现在就可以使用插座了,您无需对以编程方式创建的约束进行任何操作,等等。唯一需要考虑的事情(为了使按钮的协议起作用)就是指定其委托。例如,在Swift 3中:

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "CustomHeader") as! CustomHeader
    
    headerView.customLabel.text = content[section].name  // set this however is appropriate for your app's model
    headerView.sectionNumber = section
    headerView.delegate = self
    
    return headerView
    

    }

    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 44 // or whatever
    }

  5. 显然,如果要将视图控制器指定delegate为标题视图中按钮的,则必须遵循该协议:

    extension ViewController: CustomHeaderDelegate {
    func customHeader(_ customHeader: CustomHeader, didTapButtonInSection section: Int) {
        print("did tap button", section)
    }
    

    }

当我列出所有涉及的步骤时,这一切听起来都令人困惑,但是一旦完成一两次,它真的很简单。我认为这比以编程方式构建标题视图更简单。

在马特的回答,他抗议:

问题很简单,就是您不能仅仅通过在身份检查器中声明将UIView笔尖神奇地变成笔尖UITableViewHeaderFooterView

这根本是不正确的。如果使用上述基于NIB的方法,则为此头视图的根视图实例化的类
UITableViewHeaderFooterView子类,而不是UIView。它实例化为NIB根视图的基类指定的任何类。

但是,正确的是,contentView在这种基于NIB的方法中未使用此类的某些属性(尤其是)。它确实应该是可选属性,就像textLabeldetailTextLabel一样(或者更好的是,它们应该UITableViewHeaderFooterView在IB中添加适当的支持)。我同意这对Apple来说设计不佳,但它给我留下了草率,特质的细节,但鉴于表视图中的所有问题,这都是一个小问题。例如,非常不寻常的是,这些年来,我们仍然无法在情节提要中完全制作原型页眉/页脚视图,而完全必须依靠这些NIB和类注册技术。

但是,不能断定一个人不能使用register(_:forHeaderFooterViewReuseIdentifier:),这是一种自iOS
6起就一直在使用的API方法,这是不正确的。我们不要将婴儿带洗澡水扔掉。



 类似资料:
  • 问题内容: 我有一个称为的子类,我想用一个文件初始化。我不确定如何使用名为xib的文件初始化此类 问题答案: 我测试了这段代码,它很好用: 初始化视图并按如下方式使用它: 要么 更新Swift > = 3.x和Swift> = 4.x

  • 问题内容: 在Objective-C中,自定义通知只是一个普通的NSString,但是在Swift 3的WWDC版本中并不明显。 问题答案: 您也可以为此使用协议 然后将您的通知名称定义为所需的任何位置。例如: 并像这样使用 这样,通知名称将与基金会分离。而且您只需要修改协议,以防更改实现。

  • 我试图使用OpenNLPJavaAPI从文档中提取名称、技能等实体。但它没有提取正确的名称。我使用opennlp源锻造链接上可用的模型 下面是一段java代码- 我想做的是: 我正在使用ApacheTika将PDF文档转换为纯文本文档 但它正在提取姓名和其他单词。它不是提取专有名称。如何创建自定义模型,从文档中提取游泳、编程等技能? 给我一些想法! 任何帮助都将不胜感激!?

  • 问题内容: 我正在http://www.cafeaulait.org/javafaq.html上阅读#6.10项,然后我开始怀疑大型企业如何创建自己的JVM实现。一个人会尝试(或可行)实验性的东西吗? 问题答案: 从技术上讲,创建该新JVM所需的所有信息都是该语言和目标平台的公共规范。即使字节码解释在很大程度上相同,JVM还是需要根据其是要在台式机还是手机上运行而有所不同。 一些开始寻找信息的地方

  • 问题内容: 我正在用Gradle创建一个构建过程,我想提供一个使用Java代码的插件。Gradle 插件文档 说 这是可能的: 您可以使用任何喜欢的语言来实现自定义插件,前提是该实现最终会编译为字节码。对于此处的示例,我们将使用Groovy作为实现语言。如果需要,可以改用Java或Scala。 但是,经过数小时的谷歌搜索和阅读之后,我还没有找到有关如何使用Java创建Gradle自定义插件的任何说

  • Swift 5.x Set 定义、创建 1. 创建Set 1.1 使用初始化器语法来创建一个确定类型的空Set let letters = Set<Character>() 1.2 使用数组字面量创建Set var letters: Set<String> = ["Math", "English", "History"] 注: 如果不指定类型为Set, 默认初始化的是数组 2. Set 类型的