本文介绍了Swift - 如何使用XIB文件创建自定义viewForHeaderInSection?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以通过编程方式创建简单的自定义viewForHeaderInSection,如下所示。但我想做更复杂的事情,可能是与不同​​的类连接,并像tableView单元格一样到达它们的属性。简单地说,我想看看我做了什么。

I can create simple custom viewForHeaderInSection in programmatically like below. But I want to do much more complex things maybe connection with a different class and reach their properties like a tableView cell. Simply, I want to see what I do.

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语言的新手。如果有人解释详细,那就太棒了。

Is there anyone to explain how can I create a custom tableView header view using xib? I have encountered with old Obj-C topics but I'm new with Swift language. If someone explain as detailed, It would be great.

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

Solved with File's Owner, ViewController base class (clicked left outline menu.)

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

Solved adding headerView.clipsToBounds = true in viewForHeaderInSection: method.

对于约束警告

当我在viewController中使用此方法添加ImageView甚至相同的高度约束时,它流过tableView行。

When I added ImageView even same height constraint with this method in viewController, it flow over tableView rows look like picture.

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

如果我使用,请在viewDidLoad中自动调整ScrollViewInsets,在这种情况下,图像流在navigationBar下。 -fixed -

If I use, automaticallyAdjustsScrollViewInsets in viewDidLoad, In this case image flows under navigationBar. -fixed-

self.automaticallyAdjustsScrollViewInsets = false





@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的标头的典型过程是:

The typical process for NIB based headers would be:


  1. 创建 UITableViewHeaderFooterView 子类,至少包含标签的插座。您可能还想给它一些标识符,通过该标识符可以对此标题对应的部分进行反向工程。同样,您可能希望指定一个协议,通过该协议,标头可以向视图控制器通知事件(例如点击按钮)。因此,在Swift 3中:

  1. Create UITableViewHeaderFooterView subclass with, at the least, an outlet for your label. You might want to also give it some identifier by which you can reverse engineer to which section this header corresponds. Likewise, you may want to specify a protocol by which the header can inform the view controller of events (like the tapping of the button). Thus, in 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提供了与基类相同的名称,以简化我项目中文件的管理,避免混淆。无论如何,关键步骤包括:

  • Create NIB. Personally, I give the NIB the same name as the base class to simplify management of my files in my project and avoid confusion. Anyway, the key steps include:


    • 创建视图NIB,或者如果以空NIB开始,则向NIB添加视图;

    • Create view NIB, or if you started with an empty NIB, add view to the NIB;

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

    Set the base class of the view to be whatever your UITableViewHeaderFooterView subclass was (in my example, CustomHeader);

    在IB中添加控件和约束;

    Add your controls and constraints in IB;

    在Swift代码中连接 @IBOutlet 对商店的引用;

    Hook up @IBOutlet references to outlets in your Swift code;

    将按钮连接到 @IBAction

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

    In the viewDidLoad in the view controller, register the NIB. In Swift 3:

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

    或者在Swift 2中:

    Or in Swift 2:

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


  • viewForHeaderInSection 中,使用您在上一步中指定的相同标识符对可重复使用的视图出列队列。完成后,您现在可以使用您的插座,您不必对编程创建的约束等做任何事情。您需要做的唯一事情(对于按钮工作的协议)是指定其委托。例如,在Swift 3中:

  • In viewForHeaderInSection, dequeue a reusable view using the same identifier you specified in the prior step. Having done that, you can now use your outlet, you don't have to do anything with programmatically created constraints, etc. The only think you need to do (for the protocol for the button to work) is to specify its delegate. For example, in 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:

    Or, in 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
    }
    


  • 显然,如果您要在标题视图中为按钮指定视图控制器作为委托,则必须符合该协议:

  • Obviously, if you're going to specify the view controller as the delegate for the button in the header view, you have to conform to that protocol:

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


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

    This all sounds confusing when I list all the steps involved, but it's really quite simple once you've done it once or twice. I think it's simpler than building the header view programmatically.

    这篇关于Swift - 如何使用XIB文件创建自定义viewForHeaderInSection?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    07-18 11:13
    查看更多