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的标题的典型过程是:
-
创build
UITableViewHeaderFooterView
子类,至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) } }
-
创buildNIB。 就个人而言,我给NIB的基类相同的名称,以简化我的项目中的文件的pipe理,并避免混淆。 无论如何,关键步骤包括:
-
创build视图NIB,或者如果你开始一个空的NIB,添加视图到NIB;
-
设置视图的基类是你的
UITableViewHeaderFooterView
子类(在我的例子中,CustomHeader
); -
在IB中添加您的控制和约束;
-
将
@IBOutlet
引用连接到Swift代码中的sockets; -
将button连接到
@IBAction
-
-
在视图控制器的
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") }
-
在
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 }
-
很明显,如果你打算把视图控制器指定为标题视图中button的
delegate
,你必须遵守该协议:extension ViewController: CustomHeaderDelegate { func didTapButton(in section: Int) { print("\(section)") } }
当我列出涉及的所有步骤时,这听起来很混乱,但是一旦你完成了一两次,这真的很简单。 我认为这比以编程方式构build标题视图更简单。