带有集合视图的 Swift 慢速自定义键盘按钮

Posted

技术标签:

【中文标题】带有集合视图的 Swift 慢速自定义键盘按钮【英文标题】:Swift slow custom keyboard buttons with collectionviews 【发布时间】:2020-10-31 10:39:29 【问题描述】:

免责声明:

在你撕下我的头并放火之前,我知道已经有人问过这样的问题,但它们都指的是单个按钮我有一个 collectionView。在仔细阅读所有其他问题并尝试将它们的解决方案结合在一起后,我提出了这个问题。

概述:

我正在创建一个带有集合视图的键盘扩展。在我的 collectionView 中,我有自定义单元格,在他们的类中我放置了一个按钮。我想为集合视图中的每个按钮添加一个目标。我知道我可以使用 selectItemAtIndexRow 函数并忽略按钮,但我需要处理 touchUpInside 和 touchDown 事件(因为当我使用 y 键盘键入时它非常慢)而且我还没有找到使用 collectionView 单元格的方法(如果存在的东西让我知道)。为了避免这个问题,我认为最好的解决方案是在我的单元格的类中添加一个按钮并添加我想要的操作,但我发现这样做有多个问题。

我在做什么:

    我有经典的keyboardViewController,你可以通过创建一个新的键盘目标来放置一个视图(这是包含collectionView的视图)。

    我有一个包含集合视图的自定义视图类

    我有一个自定义的 collectionview 单元格类

自定义视图类

在这里,我以编程方式创建了我的 collectionView。

//Closure to add action to my buttons
 var insertLowercase : ((IndexPath) -> ())?
    
 let letters = ["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"]

 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        letters.count
    
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = keyView.dequeueReusableCell(withReuseIdentifier: "collectionCellId", for: indexPath) as! KeyboardKeys
        cell.button.setTitle(letters[indexPath.row], for: .normal)
        cell.button.addTarget(self, action: #selector(lettersKeyboard.insert(indexPath:)), for: .touchUpInside)
        return cell
    
    
    @objc func insert (indexPath: IndexPath)
        insertLowercase?(indexPath)
    

这就是我添加目标的方式。但是,如果我按下按钮,键盘崩溃给我以下错误:

线程 1:“-[Keyboarddd.KeyboardButton 长度]:无法识别的选择器发送到实例 0x7f9bb2506740”

键盘视图控制器

将我的自定义视图放在这里后,在 viewDidLoad 我称之为:

 letters.insertLowercase =  indexPath in
            let text = self.letters.letters[indexPath.row]
            self.textDocumentProxy.insertText(text)
         //And more stuff to handle quick insertion but this is what you need to reproduce my problem

问题:

我怎样才能体面地将目标添加到我的按钮?或者有没有办法直接对 collectionView 单元做我想做的事情?

【问题讨论】:

【参考方案1】:

您的问题是 UIButton.addTarget 没有调用将 IndexPath 作为参数的方法。通常,您所做的是处理单元格中的按钮操作,然后在按下按钮时调用回调。

class KeyboardKeys: UICollectionViewCell 

    @IBOutlet weak var button: UIButton! 
        didSet 
            button.addTarget(self, action: #selector(buttonAction(_:)), for: .touchUpInside)
        
    

    var didPushButton: (KeyboardKeys) -> Void =  _ in 

    @objc func buttonAction(_ button: UIButton) 
        didPushButton(self)
    

在您的数据源方法中,您想为每个单元格注册一个回调:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCellId", for: indexPath) as! KeyboardKeys
    cell.button.setTitle(letters[indexPath.row], for: .normal)
    cell.didPushButton =  [weak self] cell in
        guard let indexPath = collectionView.indexPath(for: cell) else  return 
        self?.insert(indexPath: indexPath)
    
    return cell

【讨论】:

谢谢。这真的很有帮助。但是,我不清楚。在我的键盘中,取决于页面或键状态(字母页面/数字页面/大写字母),我需要附加不同的操作,因此我使用 if 语句让 didPushButton 按我的意愿行事。但是我认为我这样做不是处理问题的正确方法,您有什么建议吗?我不知道我是否清楚,如果不是,我会编辑我的问题。 如果您有兴趣回答我的问题,我将其发布。只要我有足够的代表,我就会支持这个答案。 ***.com/questions/64665630/…

以上是关于带有集合视图的 Swift 慢速自定义键盘按钮的主要内容,如果未能解决你的问题,请参考以下文章

Swift - 带有 xib 文件的自定义视图,IBOutlet 为 nil

如何在 swift 3 中的 tableview 单元格中添加带有自定义视图的 collectionView?

如何使用Swift在Xcode上创建自定义数字键盘? [关闭]

在键盘上显示带有按钮的 UIView,例如在 Skype、Viber messengers(Swift、iOS)中

当键盘中的“下一步”返回按钮时滚动带有文本字段的表格视图

Swift - 跟踪自定义键盘上使用的最流行的按钮?