如何制作可扩展的UITableView标头? [英] How do I make an expandable UITableView header?

查看:70
本文介绍了如何制作可扩展的UITableView标头?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想首先显示标题的一半。当用户点击标题内的其中一个按钮时,标题的其余部分向下滑动并显示自己。当用户再次点击按钮时,标题会滑回原来的大小(1/2大小)。

I want to display half of the header at first. When the user taps on one of the buttons inside the header, the rest of the header slides down and reveals itself. When the user taps on the button again, the header slides back up to its original size (1/2 size).

然而,当我试图扩展标题的高度时,它覆盖了tableView单元格,而不是将它们向下推。

However, when I tried to expand my header's height, it covers the tableView cells instead of pushing them down.

func prepareHeader(){
    let headerHeight = CGFloat(51.0)
    headerView = UIView(frame: CGRect(x: 0, y: 0, width: screenWidth, height: headerHeight))
    headerView.backgroundColor = UIColor.whiteColor()
    headerView.layer.addSublayer(bottomBorder)
    headerView.layer.masksToBounds = true


    let toggler = UIButton(type: .Custom)
    toggler.frame = CGRectMake(0, 0, 40, 40)
    toggler.backgroundColor = FlatGreen()
    toggler.addTarget(self, action: "toggleHeader:", forControlEvents: UIControlEvents.TouchUpInside)
    headerView.addSubview(toggler)

    self.tableView.tableHeaderView = headerView

}

func toggleHeader(sender: UIButton){
    print("Pushed")
    var newFrame = self.headerView.frame
    newFrame.size.height = CGFloat(100)
    self.headerView.frame = newFrame
}


推荐答案

我们想要什么

可以动态打开和关闭的表格视图标题。

A table view header that can be dynamically opened and closed.

解决方案1:没有界面建设者

class ViewController: UIViewController {

    var headerView = UIView()
    var tableView  = UITableView()
    var isHeaderOpen = false
    let HEADER_CLOSED_HEIGHT: CGFloat = 100
    let HEADER_OPEN_HEIGHT: CGFloat = 200

    var headerClosedHeightConstraint: NSLayoutConstraint!
    var headerOpenHeightConstraint: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Add the table view to the screen.
        view.addSubview(tableView)

        // Make the table view fill the screen.
        tableView.translatesAutoresizingMaskIntoConstraints = false
        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[tableView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["tableView": tableView]))
        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[tableView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["tableView": tableView]))

        // Add the header view to the table view.
        tableView.tableHeaderView = headerView
        headerView.backgroundColor = UIColor.redColor()
        headerView.translatesAutoresizingMaskIntoConstraints = false

        // Add a button to the header.
        let button = UIButton(type: .Custom)
        button.setTitle("Toggle", forState: .Normal)
        headerView.addSubview(button)
        button.translatesAutoresizingMaskIntoConstraints = false
        headerView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[button]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["button": button]))
        headerView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[button]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["button": button]))
        button.addTarget(self, action: "toggleHeaderAction:", forControlEvents: .TouchUpInside)

        // Make the header full width.
        view.addConstraint(NSLayoutConstraint(item: headerView, attribute: .Width, relatedBy: .Equal, toItem: view, attribute: .Width, multiplier: 1, constant: 0))

        // Create the constraints for the two different header heights.
        headerClosedHeightConstraint = NSLayoutConstraint(item: headerView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 0, constant: HEADER_CLOSED_HEIGHT)

        // Create the height constraint for the header's other height for later use.
        headerOpenHeightConstraint = NSLayoutConstraint(item: headerView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: HEADER_OPEN_HEIGHT)

        closeHeader()   // Close header by default.
    }

    func openHeader() {
        headerView.removeConstraint(headerClosedHeightConstraint)
        headerView.addConstraint(headerOpenHeightConstraint)
        updateHeaderSize()
        isHeaderOpen = true
    }

    func closeHeader() {
        headerView.removeConstraint(headerOpenHeightConstraint)
        headerView.addConstraint(headerClosedHeightConstraint)
        updateHeaderSize()
        isHeaderOpen = false
    }

    func updateHeaderSize() {
        // Calculate the header's new size based on its new constraints and set its frame accordingly.
        let size = headerView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
        var frame = headerView.frame
        frame.size.height = size.height
        headerView.frame = frame
        tableView.tableHeaderView = headerView
        self.headerView.layoutIfNeeded()
    }

    func toggleHeader() {
        if isHeaderOpen {
            closeHeader()
        } else {
            openHeader()
        }
    }

    func toggleHeaderAction(sender: AnyObject) {
        toggleHeader()
    }
}

解决方案2:使用界面构建器

要动态 UITableView 标题更改高度,请尝试以下操作。

To make a UITableView header change height dynamically, try the following.

在故事板中,首先向视图控制器添加 UITableView 。然后添加 UIView 作为 UITableView 的第一个子项(Interface Builder自动将其解释为 UITableView 的标题视图。

In your storyboard, first add a UITableView to your view controller. Then add a UIView as the first child of the UITableView (Interface Builder automatically interprets this as the UITableView's header view).

将一个插座连接到表格和标题,以便我们稍后可以在代码中访问它们。

Wire up an outlet to the table and header so we can access them later in code.

@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var headerView: UIView!

接下来,在代码中我们创建了两个约束(打开和关闭),稍后我们将添加/删除切换标题的高度。

Next, in code we create two constraints (opened and closed) which we'll later add/remove to toggle the header's height.

var headerOpenHeightConstraint: NSLayoutConstraint!
var headerClosedHeightConstraint: NSLayoutConstraint!

让我们创建一个标志来跟踪标题的打开/关闭状态。另外,我们指定开放标题高度。

Let's also create a flag to keep track of the open/closed state of the header. Also, we specify the open header height.

var isHeaderOpen = false
let HEADER_OPEN_HEIGHT: CGFloat = 200

Interface Builder会自动将我们创建的标题的尺寸转换为自动布局约束。由于我们要自己更改标题的高度,我们需要添加自己的替换约束并删除这些自动约束( NSAutoresizingMaskLayoutConstraints )。
viewDidLoad()中,添加以下内容(将默认标题高度作为关闭高度, HEADER_OPEN_HEIGHT 作为开放标题高度。。

Interface Builder automatically converts the dimensions of the header we created into Auto Layout constraints. Since we're going to change the header's height ourselves, we need to add replacement constraints of our own and remove these automatic constraints (NSAutoresizingMaskLayoutConstraints). In viewDidLoad(), add the following (takes the default header height as the closed height and HEADER_OPEN_HEIGHT as the open header height).

override func viewDidLoad() {
    super.viewDidLoad()

    // The header needs a new width constraint since it will no longer have the automatically generated width.
    view.addConstraint(NSLayoutConstraint(item: headerView, attribute: .Width, relatedBy: .Equal, toItem: view, attribute: .Width, multiplier: 1, constant: 0))

    // Add the height constraint for the default state (closed header).
    headerClosedHeightConstraint = NSLayoutConstraint(item: headerView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: headerView.bounds.height)
    headerView.addConstraint(headerClosedHeightConstraint)

    // Make the constraint we'll use later to open the header.
    headerOpenHeightConstraint = NSLayoutConstraint(item: headerView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: HEADER_OPEN_HEIGHT)

    // Finally we disable this so that we don't get Interface Builder's automatically generated constraints
    // messing with our constraints.
    headerView.translatesAutoresizingMaskIntoConstraints = false
}

最后,在Interface Builder中,添加一个按钮并将其连接到视图控制器中的操作。

Finally, in Interface Builder, add a button and wire it up to an action in your view controller.

@IBAction func toggleHeaderAction(sender: AnyObject) {

    // Add/remove the appropriate constraints to toggle the header.
    if isHeaderOpen {
        headerView.removeConstraint(headerOpenHeightConstraint)
        headerView.addConstraint(headerClosedHeightConstraint)
    } else {
        headerView.removeConstraint(headerClosedHeightConstraint)
        headerView.addConstraint(headerOpenHeightConstraint)
    }

    // Calculate the header's new size based on its new constraints.
    let size = headerView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

    // Give the header its new height.
    var frame = headerView.frame
    frame.size.height = size.height
    headerView.frame = frame
    headerView.setNeedsLayout()
    headerView.layoutIfNeeded()
    tableView.tableHeaderView = headerView

    isHeaderOpen = !isHeaderOpen
}

这篇关于如何制作可扩展的UITableView标头?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆