【问题标题】:Swift: tvOS IBAction for UIControl in Collection View cell never gets calledSwift:集合视图单元中 UIControl 的 tvOS IBAction 永远不会被调用
【发布时间】:2019-11-16 15:52:40
【问题描述】:

我知道这个问题已经被问过很多次了,但我还在学习,我已经在 S.O. 中尝试了所有可能的解决方案。而且我一次也没有运气。所以这就是问题所在:

  • 我使用的是 Xcode 11 beta 3(希望这不是问题!)
  • 我在视图控制器中有一个简单的集合视图
  • 在单元格内我放置了一个 tvOS'TVPosterView - 它继承自 UIControl 并自行测试它的行为就像一个按钮(IBAction 被调用)。
  • 在收藏视图上有我推海报时的动画
  • 海报视图有一个默认图像,我只是更改了标题
  • 我将 IBAction 从海报视图拖到 IB 中的单元格类中
  • IBAction 分开,集合视图显示和滚动很好,改变了海报的标题
  • 如果我将集合视图委托给视图控制器,collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 会被调用。

代码如下:

视图控制器

import UIKit
import TVUIKit

class SecondViewController: UIViewController {

    @IBOutlet weak var myView: UIView!
    @IBOutlet weak var myCollection: MyCollection!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
}

extension SecondViewController: UICollectionViewDataSource {

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) as! MyCell

        cell.myPoster.title! = "Header " + String(indexPath.row + 1)

        cell.myPoster.tag = indexPath.row + 1
        cell.posterTapAction = { cell in
            print("Header is: \(cell.myPoster.title!)")
        }

        return cell
    }
}

extension SecondViewController: UICollectionViewDelegate {

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// This one works - but that's not what I am looking for
        print("From didSelectItemAt indexPath: \(indexPath.item + 1)")
    }
}

收藏视图

import UIKit

class MyCollection: UICollectionView {

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
    }
}

单元格

import UIKit
import TVUIKit

class MyCell: UICollectionViewCell {

    var posterTapAction: ((MyCell) -> Void)?

    @IBOutlet weak var myPoster: TVPosterView!
    @IBAction func myAction(_ sender: TVPosterView) {
        posterTapAction?(self)
        print("Poster pressed \(sender.tag)")
    }
}

知道我缺少什么吗?我很乐意在按下海报后设法打印一个虚拟字符串。

我也尝试了选择器和委托的解决方案,但都没有奏效。所以,请让我们专注于closures 这个特殊的解决方案。谢谢!

【问题讨论】:

    标签: swift uicollectionview uibutton uicollectionviewcell tvos


    【解决方案1】:

    我终于找到了。像往常一样,这是由于 tvOS 的焦点。基本上,单元格必须不可聚焦,以便单元格内的 UIControl 元素(在我的情况下为 TVPosterView,但它可以是任何 UIControl)将成为焦点。这是骗人的,因为从图形上看,它确实看起来好像海报有焦点(可以将海报旋转一点)。

    解决方法是将collectionView(_:canFocusItemAt:)添加到UICollectionViewDelegate

    extension SecondViewController: UICollectionViewDelegate {
    
        func collectionView(_ collectionView: UICollectionView,
                                 canFocusItemAt indexPath: IndexPath) -> Bool {
            return false
        }
    
        func collectionView(_ collectionView: UICollectionView, 
                                 didSelectItemAt indexPath: IndexPath) {
            // Now, thanks to the function above, this is disabled
            print("From didSelectItemAt indexPath: \(indexPath.item + 1)")
        }
    }
    

    我已经在这个问题的代码中对其进行了测试,并将其也添加到了我的项目中,终于可以使用了!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-13
      • 2018-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多