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,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.issue: Button @IBAction doesn’t connect with my ViewController. (Fixed)
解决与文件的所有者,ViewController基类(点击左侧轮廓菜单.)
2.issue: Header height problem (Fixed)
解决在viewForHeaderInSection:方法中添加headerView.clipsToBounds = true.
对于约束警告this answer solved my problems:
当在ViewController中使用此方法添加ImageView时,甚至使用相同的高度约束,它将流过tableView行look like picture.
func tableView(tableView: UITableView,heightForHeaderInSection section: Int) -> CGFloat { return 120 }
如果我使用,在viewDidLoad中自动调整ScrollViewInsets,在这种情况下,图像在导航栏下流动. -固定-
self.automaticallyAdjustsScrollViewInsets = false
3.issue: If button under View (Fixed)
@IBAction func didTapButton(sender: AnyObject) { print("tapped") if let upView = sender.superview { if let headerView = upView?.superview as? CustomHeader { print("in section \(headerView.sectionNumber)") } } }
解决方法
>创建UITableViewHeaderFooterView子类,至少有一个标签的插座.您可能还想给它一些标识符,您可以通过该标识符反向工程到该标题对应的部分.同样,您可能需要指定一个协议,通过该协议,头可以通知视图控制器的事件(例如敲击按钮).因此,在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) } }
>创建NIB.就个人而言,我给NIB与基类名称相同,以简化我的项目文件的管理,避免混淆.无论如何,关键步骤包括:
>创建视图NIB,或者如果您启动了一个空的NIB,则将视图添加到NIB;
>将视图的基类设置为您的UITableViewHeaderFooterView子类(在我的示例中为CustomHeader);
>在IB中添加您的控制和限制;
钩住@IBOutlet引用Swift代码的插座;
>将按钮连接到@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",forHeaderFooterViewReuseIdentifier: "CustomHeader") }
>在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 }
或者,在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 }
>显然,如果要将视图控制器指定为标题视图中按钮的代理,则必须符合该协议:
extension ViewController: CustomHeaderDelegate { func didTapButton(in section: Int) { print("\(section)") } }
当我列出所有涉及的步骤时,这听起来很混乱,但一旦你完成了一两次,这真的很简单.我认为这比通过编程方式构建标题更简单.