Swift 带有集合视图的慢速自定义键盘按钮
Swift slow custom keyboard buttons with collectionviews
免责声明:
在你把我的脑袋砍下来放火之前,我知道已经有人问过这样的问题,但它们都指的是单个按钮。 我有一个 collectionView。在仔细阅读所有其他问题并尝试将他们的解决方案结合在一起之后,我才问这个问题。
概览:
我正在创建一个带有集合视图的键盘扩展。在我的 collectionView 中,我有自定义单元格,在它们的 class 中,我放置了一个按钮。我想为集合视图中的每个按钮添加一个目标。我知道我可以使用 selectItemAtIndexRow 函数并忽略按钮,但我需要处理 touchUpInside 和 touchDown 事件(因为当我使用 y 键盘键入时它非常慢)并且我还没有找到使用 collectionView 单元格的方法(如果有些东西存在让我知道)。为了避免这个问题,我认为最好的解决方案是在我的单元格 class 中添加一个按钮并添加我想要的操作,但我发现这样做有多个问题。
我在做什么:
我有 classic 键盘ViewController 你可以通过创建一个新的键盘目标来获得,我在其中放置了一个视图(这是包含 collectionView 的视图)。
我有一个包含集合视图的自定义视图class
我有一个自定义的 collectionview 单元格 class
自定义视图Class
这里我以编程方式创建了我的 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)
}
这就是我添加目标的方式。但是,如果我按下按钮,键盘会崩溃并出现以下错误:
Thread 1: "-[Keyboarddd.KeyboardButton length]: unrecognized selector sent to instance 0x7f9bb2506740"
键盘ViewController
将我的自定义视图放在这里后,在 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 单元格执行我想执行的操作?
您的问题是 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
}
免责声明:
在你把我的脑袋砍下来放火之前,我知道已经有人问过这样的问题,但它们都指的是单个按钮。 我有一个 collectionView。在仔细阅读所有其他问题并尝试将他们的解决方案结合在一起之后,我才问这个问题。
概览:
我正在创建一个带有集合视图的键盘扩展。在我的 collectionView 中,我有自定义单元格,在它们的 class 中,我放置了一个按钮。我想为集合视图中的每个按钮添加一个目标。我知道我可以使用 selectItemAtIndexRow 函数并忽略按钮,但我需要处理 touchUpInside 和 touchDown 事件(因为当我使用 y 键盘键入时它非常慢)并且我还没有找到使用 collectionView 单元格的方法(如果有些东西存在让我知道)。为了避免这个问题,我认为最好的解决方案是在我的单元格 class 中添加一个按钮并添加我想要的操作,但我发现这样做有多个问题。
我在做什么:
我有 classic 键盘ViewController 你可以通过创建一个新的键盘目标来获得,我在其中放置了一个视图(这是包含 collectionView 的视图)。
我有一个包含集合视图的自定义视图class
我有一个自定义的 collectionview 单元格 class
自定义视图Class
这里我以编程方式创建了我的 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)
}
这就是我添加目标的方式。但是,如果我按下按钮,键盘会崩溃并出现以下错误:
Thread 1: "-[Keyboarddd.KeyboardButton length]: unrecognized selector sent to instance 0x7f9bb2506740"
键盘ViewController
将我的自定义视图放在这里后,在 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 单元格执行我想执行的操作?
您的问题是 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
}