Swift – 如何创build自定义viewForHeaderInSection,使用XIB文件?

我可以创build简单的自定义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创build自定义tableView标题视图? 我遇到过老的Obj-C主题,但是我是新的Swift语言。 如果有人详细解释,这将是伟大的。

1.issue: Button @IBAction不能与我的ViewController连接。 (固定)

解决与文件的所有者,ViewController基类(点击左轮廓菜单。)

2.issue:标题高度问题(固定)

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

对于约束性警告, 这个答案解决了我的问题 :

当我在viewController中用这个方法添加ImageView甚至相同的高度约束时,它在tableView行上看起来像图片 。

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

如果我使用,在viewDidLoad中自动调用ScrollViewInsets,在这种情况下,图像stream在navigationBar下。 -固定-

 self.automaticallyAdjustsScrollViewInsets = false 

3.issue:如果查看(固定)

 @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. 创buildUITableViewHeaderFooterView子类,至less为你的标签提供一个sockets。 你也可以给它一些标识符,通过这个标识符你可以反向devise这个头对应的部分。 同样,你可能想指定一个协议,通过这个协议头可以通知视图控制器的事件(比如点击button)。 因此,在Swift 3:

     // if you want your header to be able to inform view controller of key events, create protocol protocol CustomHeaderDelegate: class { func didTapButton(in section: Int) } // define CustomHeader class with necessary `delegate`, `@IBOutlet` and `@IBAction`: class CustomHeader: UITableViewHeaderFooterView { 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 @IBAction func didTapButton(_ sender: AnyObject) { delegate?.didTapButton(in: sectionNumber) } } 
  2. 创buildNIB。 就个人而言,我给NIB的基类相同的名称,以简化我的项目中的文件的pipe理,并避免混淆。 无论如何,关键步骤包括:

    • 创build视图NIB,或者如果你开始一个空的NIB,添加视图到NIB;

    • 设置视图的基类是你的UITableViewHeaderFooterView子类(在我的例子中, CustomHeader );

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

    • @IBOutlet引用连接到Swift代码中的sockets;

    • 将button连接到@IBAction

  3. 在视图控制器的viewDidLoad中,注册NIB。 在Swift 3:

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

    或者在Swift 2中:

     override func viewDidLoad() { super.viewDidLoad() tableView.registerNib(UINib(nibName: "CustomHeader", bundle: nil), forHeaderFooterViewReuseIdentifier: "CustomHeader") } 
  4. viewForHeaderInSection ,使用您在上一步中指定的相同标识符使可重用视图出列。 完成之后,你现在可以使用你的sockets了,你不需要用程序创build的约束等来做任何事情。唯一需要做的事情就是指定它的委托。 例如,在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 } 

    或者,在Swift 2:

     override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { let headerView = tableView.dequeueReusableHeaderFooterViewWithIdentifier("CustomHeader") as! CustomHeader headerView.customLabel.text = content[section].name headerView.sectionNumber = section headerView.delegate = self return headerView } override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return 44 // or whatever } 
  5. 很明显,如果你打算把视图控制器指定为标题视图中button的delegate ,你必须遵守该协议:

     extension ViewController: CustomHeaderDelegate { func didTapButton(in section: Int) { print("\(section)") } } 

当我列出涉及的所有步骤时,这听起来很混乱,但是一旦你完成了一两次,这真的很简单。 我认为这比以编程方式构build标题视图更简单。