Swift - UITableView 中的标题阻止按钮交互

Posted

技术标签:

【中文标题】Swift - UITableView 中的标题阻止按钮交互【英文标题】:Swift - Header in UITableView blocks button interaction 【发布时间】:2016-04-16 08:16:17 【问题描述】:

在我的 UITableView 中,我想要一个选项来单击具有固定位置的按钮(见附图)。但是 UITableView 的部分标题前面或后面的任何内容都被阻止交互,它不会注册按钮点击。我尝试设置更高的 zPosition,将按钮放在标题前面,但我仍然无法按下按钮。这是它的样子:

Image that shows the buttons before and after (nameOfButton).layer.zPosition = 99 is applied.

即使我的按钮在标题前面,按钮点击也没有注册...

我正在以编程方式创建按钮,我的 viewDidLoad 看起来像这样:

override func viewDidLoad() 
        super.viewDidLoad()

        // Allow ios to resize the cells automatically according to our Auto Layout constraints
        tableView.rowHeight = UITableViewAutomaticDimension

        // We will take ownership of the header view we've so nicely setup in the storyboard and then remove it from the table view.
        headerView = tableView.tableHeaderView
        tableView.tableHeaderView = nil
        tableView.addSubview(headerView)
        let addPhotoTapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.addPhoto(_:)))
        headerView.addGestureRecognizer(addPhotoTapGesture)

        // PhotoPicker
        createPhotoPickerButtons()

        let effectiveHeight = kTableHeaderHeight-kTableHeaderCutAway/2
        tableView.contentInset = UIEdgeInsets(top: effectiveHeight, left: 0, bottom: 0, right: 0)
        tableView.contentOffset = CGPoint(x: 0, y: -effectiveHeight)

        headerMaskLayer = CAShapeLayer()
        headerMaskLayer.fillColor = UIColor.blackColor().CGColor

        headerView.layer.mask = headerMaskLayer
        updateHeaderView()
     

还有我的createPhotoPickerButtons()(这里我将按钮放在视图下方,以便使用showImagePicker() 为它们的外观设置动画:

func createPhotoPickerButtons() 

        takePhotoButton = UIButton.init(type: UIButtonType.System) // .System
        photoLibraryButton = UIButton.init(type: UIButtonType.System) // .System
        cancelButton = UIButton.init(type: UIButtonType.System) // .System

        takePhotoButton.frame = CGRectMake(20, (0 + self.tableView.contentOffset.y + UIScreen.mainScreen().bounds.height), (UIScreen.mainScreen().bounds.width - 40), 40)
        photoLibraryButton.frame = CGRectMake(20, (0 + self.tableView.contentOffset.y + UIScreen.mainScreen().bounds.height), (UIScreen.mainScreen().bounds.width - 40), 40)
        cancelButton.frame = CGRectMake(20, (0 + self.tableView.contentOffset.y + UIScreen.mainScreen().bounds.height), (UIScreen.mainScreen().bounds.width - 40), 40)

        takePhotoButton.backgroundColor = UIColor(red: 0/255, green: 122/255, blue: 255/255, alpha: 1.0)
        photoLibraryButton.backgroundColor = UIColor(red: 0/255, green: 122/255, blue: 255/255, alpha: 1.0)
        cancelButton.backgroundColor = UIColor(red: 0/255, green: 122/255, blue: 255/255, alpha: 1.0)

        takePhotoButton.setTitle("Take Photo", forState: UIControlState.Normal)
        photoLibraryButton.setTitle("Photo Library", forState: UIControlState.Normal)
        cancelButton.setTitle("Cancel", forState: UIControlState.Normal)

        takePhotoButton.titleLabel?.font = UIFont.systemFontOfSize(17)
        photoLibraryButton.titleLabel?.font = UIFont.systemFontOfSize(17)
        cancelButton.titleLabel?.font = UIFont.systemFontOfSize(17)

        takePhotoButton.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)
        photoLibraryButton.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)
        cancelButton.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)

        let takePhotoButtonTapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.takePhotoButtonAction(_:)))
        takePhotoButton.addGestureRecognizer(takePhotoButtonTapGesture)
        let photoLibraryButtonTapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.photoLibraryButtonAction(_:)))
        photoLibraryButton.addGestureRecognizer(photoLibraryButtonTapGesture)
        let cancelButtonTapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.cancelButtonAction(_:)))
        cancelButton.addGestureRecognizer(cancelButtonTapGesture)

        self.tableView.addSubview(takePhotoButton)
        self.tableView.addSubview(photoLibraryButton)
        self.tableView.addSubview(cancelButton)

        takePhotoButton.layer.zPosition = 99
        photoLibraryButton.layer.zPosition = 99
        cancelButton.layer.zPosition = 99

        takePhotoButton.alpha = 0
        photoLibraryButton.alpha = 0
        cancelButton.alpha = 0

    

最后是我的showImagePicker()addPhoto()(用户点击图片时调用的操作):

func showImagePicker()

        // (0 + self.tableView.contentOffset.y + UIScreen.mainScreen().bounds.height - 50 - 10 - 50 - 10 - 50 - 10)

        UIView.animateWithDuration(0.5) 
            self.takePhotoButton.alpha = 1
            self.photoLibraryButton.alpha = 1
            self.cancelButton.alpha = 1

            self.takePhotoButton.frame.origin.y = 0 + self.tableView.contentOffset.y + UIScreen.mainScreen().bounds.height - 50 - 10 - 50 - 10 - 50 - 10
            self.photoLibraryButton.frame.origin.y = 0 + self.tableView.contentOffset.y + UIScreen.mainScreen().bounds.height - 50 - 10 - 50 - 10
            self.cancelButton.frame.origin.y = 0 + self.tableView.contentOffset.y + UIScreen.mainScreen().bounds.height - 50 - 10
        
    

我在 SO 上找不到任何关于此的内容,也不知道 tableView 中按钮的另一种解决方案。

【问题讨论】:

【参考方案1】:

我花了一段时间才找到解决方案,但我想通了:

sectionView.userInteractionEnabled = false

+

sectionView.layer.zPosition = -1

编辑:SWIFT 3 更新:

view.isUserInteractionEnabled = false

【讨论】:

这很完美!如果我在willDisplayHeaderView 方法上使用它,按钮就会起作用。【参考方案2】:

您的问题是您在函数中声明手势识别器,如果您这样做,那么它们将在函数体完成后被销毁。

在 createPhotoPickerButtons 之外声明您的识别器。所以上面的viewDidLoad:

var takePhotoButtonTapGesture: UITapGestureRecognizer!
var photoLibraryButtonTapGesture: UITapGestureRecogniser!
var cancelButtonTapGesture: UITapGestureRecogniser!

在 createPhotoPickerButtons 中:

func createPhotoPickerButtons() 

    takePhotoButtonTapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.takePhotoButtonAction(_:)))
    takePhotoButton.addGestureRecognizer(takePhotoButtonTapGesture)
    photoLibraryButtonTapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.photoLibraryButtonAction(_:)))
    photoLibraryButton.addGestureRecognizer(photoLibraryButtonTapGesture)
    cancelButtonTapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.cancelButtonAction(_:)))
    cancelButton.addGestureRecognizer(cancelButtonTapGesture)


【讨论】:

手势是 NSObject 的子类。因此,在添加它的视图被删除之前,它们不会被销毁。 您好,感谢您的建议,但不幸的是它不起作用......我已经尝试了 Varun 的建议,但这也不起作用。按钮在节标题前面时不响应。不在前面的按钮有效。这是一张图片,显示“照片库”按钮有效,但“拍照”按钮无效(因为标题在后面):Image of the problem。 (抱歉重复评论,不知道我评论别人回答时你是否收到通知) 我在 headerview 中没有遇到点击手势的问题。 Olivier 是正确的,但这是关键:使用的选择器函数必须在运行时可用(仍然存在)。当然,正如 Varun 上面所说,手势本身仍然存在,但不一定是选择器。【参考方案3】:

首先您的代码有问题。

永远不要向UIButton添加点击手势

请尝试addTarget(target: AnyObject?, action: Selector, forControlEvents controlEvents: UIControlEvents)。这用于处理点击按钮。

【讨论】:

您好,感谢您的提示,但它仍然不起作用。我也尝试过 Oliveier 的建议,但这也不起作用。按钮在节标题前面时不响应。不在前面的按钮有效。这是一张图片,显示“照片库”按钮有效,但“拍照”按钮无效(因为标题在后面):Image of the problem。 不要向tableView添加按钮,而是尝试添加到self.view

以上是关于Swift - UITableView 中的标题阻止按钮交互的主要内容,如果未能解决你的问题,请参考以下文章

如何在 swift 中增加 ScrollView 中的 UITableView 高度

UIView中的UITableView与swift

UIViewController Swift 中的 UITableViewController 与 UITableView

UITableView 和 UIButtons 中的多个部分 swift

单个 UITableview 单元格中的多种字体大小 (Swift)

iOS - UIVIewController 中的 UITableView 不显示所有行 [Swift]