iOS10 - ContentView 阻止了 UITableView 中 UIButton 的触摸 Header

iOS10 - ContentView Blocking Touches of UIButton in UITableView Header

我正在使用 Swift 2.3 和 Xcode 8 Beta 1 将我的应用程序更新到 iOS10,我发现有一个 UITableViewHeaderFooterContentView阻止触摸我的 UITableViewHeaderFooterView 子类上的 UIButton。

在 Xcode 8 Beta 1 模拟器上,UIButton 在 iOS9.3 上有效,但在 iOS10.

上无效

1) 有这方面的文档吗?

2) 如何确保我的 UI 元素位于 iOS10 中新内容视图的顶部? (或允许通过 UITableHeaderFooterContentView 进行触摸)

谢谢!

Table Header

import UIKit

class TableHeader: UITableViewHeaderFooterView {

    @IBOutlet weak var dayLabel: UILabel!

    @IBOutlet weak var dateLabel: UILabel!

    @IBOutlet weak var addNewEventButton: UIButton!

}

视图控制器中的代码 dateCell.addNewEventButton 是在 iOS10

中不再接收触摸的 UI 按钮
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {


    let tintColor = TintManager().getTintColour()

    let dateCell:TableHeader = tableView.dequeueReusableHeaderFooterViewWithIdentifier("TableHeader") as! TableHeader

    //dateCell.bringSubviewToFront(dateCell.addNewEventButton)

    dateCell.dayLabel.text = Dates.day.uppercaseString

    dateCell.dateLabel.text = Dates.date

        dateCell.backgroundView = UIView(frame: dateCell.frame)
        dateCell.backgroundView!.backgroundColor = tintColor
        dateCell.dayLabel.textColor = UIColor.whiteColor()
        dateCell.dateLabel.textColor = UIColor.whiteColor()
        dateCell.addNewEventButton.backgroundColor = tintColor



    dateCell.addNewEventButton.tag = section
    dateCell.addNewEventButton.layer.cornerRadius = 20.0

    if (savedEventView.superview === self.view) {
        dateCell.addNewEventButton.removeTarget(nil, action: nil, forControlEvents: .AllEvents)
        dateCell.addNewEventButton.addTarget(self, action: #selector(ViewController.userPressedAddButtonToInsertSavedEvent(_:)), forControlEvents:.TouchUpInside)
    } else {
        dateCell.addNewEventButton.removeTarget(nil, action: nil, forControlEvents: .AllEvents)
        dateCell.addNewEventButton.addTarget(self, action: #selector(ViewController.userPressedAddNewEventOnTableViewHeader(_:)), forControlEvents:.TouchUpInside)
    }

    return dateCell
}

冒犯的观点实际上是 UITableViewHeaderFooterViewcontentView(参见 Apple Docs)。所以你应该可以使用 sendSubview(toBack:) 来阻止它干扰触摸。

但是,在 iOS9 下,如果视图是从 NIB 加载的,UITableViewHeaderFooterView 似乎无法正确初始化 contentView。尽管 contentView 属性 不是可选的,但实际上它是 nil,如果您尝试访问它,您会收到 BAD ACCESS 错误。您也不能为 contentView 设置值(在代码中或作为 IB 中的出口),因为它是只读的 属性 (*)。所以我能想到的唯一解决方案是使用 #available 有条件地包含代码以将 contentView 移到后面,如果你是 运行 在 iOS 10 或更新版本上。我会把相关代码放到你的子类中:

override func awakeFromNib() {
    if #available(iOS 10, *) {
        self.sendSubview(toBack: contentView)
    }
}

(*) 胡思乱想,我的猜测是 Apple 的 UITableViewHeaderFooterView 代码很大程度上基于 UITableViewCell。由于 IB 在其对象库中有 UITableViewCells(注意这些包括单元格的 contentView),它可以确保单元格的 contentView 被正确实例化。但是由于对象库中没有 UITableViewHeaderFooterView,所以无法正确加载 contentView。看起来他们通过实例化一个空 contentView 在 iOS10 中修复了它。可惜他们没有将 UITableViewHeaderFooterView 添加到图书馆。