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

我可以通过如下编程方式创建简单的自定义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.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)")
        }

    }
}
基于NIB的标头的典型过程是:

>创建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", bundle: nil), 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)")
    }
}

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

相关文章
相关标签/搜索