Collection 自定义键盘无法正常查看
Collection View as Custom Keyboard not working
我正在构建您具有自定义键盘的应用程序。
里面是 class 我已经创建了 collection 视图,这里是代码:
class KeyboardViewController: UIInputViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate {
let stickerImages = [
UIImage(named: "Image-1"),
UIImage(named: "Image-2"),
UIImage(named: "Image-3"),
UIImage(named: "Image-4"),
UIImage(named: "Image-5")
]
@IBOutlet var nextKeyboardButton: UIButton!
@IBOutlet var collectionView: UICollectionView!
override func updateViewConstraints() {
super.updateViewConstraints()
}
override func viewDidLoad() {
super.viewDidLoad()
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.scrollDirection = UICollectionView.ScrollDirection.vertical
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
layout.itemSize = CGSize(width: 50, height: 50)
collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(StickersCell.self, forCellWithReuseIdentifier: StickersCell.reuseIdentifier)
collectionView.backgroundColor = UIColor.white
collectionView.showsHorizontalScrollIndicator = false
collectionView.backgroundColor = UIColor.red
collectionView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(collectionView)
self.nextKeyboardButton = UIButton(type: .system)
self.nextKeyboardButton.setTitle(NSLocalizedString("Next Keyboard", comment: "Title for 'Next Keyboard' button"), for: [])
self.nextKeyboardButton.sizeToFit()
self.nextKeyboardButton.translatesAutoresizingMaskIntoConstraints = false
self.nextKeyboardButton.backgroundColor = UIColor.white
self.nextKeyboardButton.addTarget(self, action: #selector(handleInputModeList(from:with:)), for: .allTouchEvents)
self.view.addSubview(self.nextKeyboardButton)
self.nextKeyboardButton.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
self.nextKeyboardButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
self.collectionView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
self.collectionView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
self.collectionView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
self.collectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
}
override func textWillChange(_ textInput: UITextInput?) {
// The app is about to change the document's contents. Perform any preparation here.
}
override func textDidChange(_ textInput: UITextInput?) {
// The app has just changed the document's contents, the document context has been updated.
var textColor: UIColor
let proxy = self.textDocumentProxy
if proxy.keyboardAppearance == UIKeyboardAppearance.dark {
textColor = UIColor.white
} else {
textColor = UIColor.black
}
self.nextKeyboardButton.setTitleColor(textColor, for: [])
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return stickerImages.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: StickersCell.reuseIdentifier, for: indexPath) as! StickersCell
cell.setImage(stickerImages[indexPath.item]!)
return cell
}}
这是我的 Collection 查看单元格 class:
class StickersCell: UICollectionViewCell {
static let reuseIdentifier: String = "StickersCell"
lazy var imageView: UIImageView = {
let imageView = UIImageView(frame: .zero)
imageView.contentMode = .scaleAspectFit
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.clipsToBounds = true
contentView.addSubview(imageView)
imageView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
imageView.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
imageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setImage(_ image: UIImage) {
imageView.image = image
}}
将 collection 视图添加到任何 UIView
或 UIViewController
时,此代码工作正常,但当尝试将其添加到键盘时,它会抛出此类错误:
据我所知我放置了错误的约束,但我不明白到底哪里出了问题,尤其是当它在简单视图或视图控制器中工作正常时。
我用 google 搜索了 allot,但找不到任何解决方案...
此外,这个 SO 问题也没有帮助:
- First question
- Second question
- Third question
我也尝试过将创建 collection 视图的代码移动到 viewDidAppear
和 viewWillAppear
方法中,但同样没有成功。
还有一件奇怪的事:
如果我向键盘添加具有相同约束的简单 UIView
- 一切正常。问题似乎专门针对 collection 视图。
那么,我错过了什么?将不胜感激任何帮助,因为我已经与这个问题斗争了一个多星期了...
更新:
阅读 Apple 开发者论坛后,我想到了一个想法:
我之前创建了与 UICollectionView
相同的 UITableView
并且奇怪的是它有效。那么有下一个问题:
你能用 UICollectionView
作为自定义键盘吗?
与这个问题斗争了 2 周后终于找到了解决方法:
由于某些原因,您不能在 UICollectionViewCell
中使用 UIImageView
或 MSStickerView
,就像在 iMessage Extension 中一样,所以我只是添加了透明的 UIButton
和 UIImage
在此按钮内并且有效!
仍然不知道为什么你不能使用图像或视图,也找不到任何关于它的具体信息,但我的解决方案有效,我希望这对以后的人有所帮助。
我正在构建您具有自定义键盘的应用程序。
里面是 class 我已经创建了 collection 视图,这里是代码:
class KeyboardViewController: UIInputViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate {
let stickerImages = [
UIImage(named: "Image-1"),
UIImage(named: "Image-2"),
UIImage(named: "Image-3"),
UIImage(named: "Image-4"),
UIImage(named: "Image-5")
]
@IBOutlet var nextKeyboardButton: UIButton!
@IBOutlet var collectionView: UICollectionView!
override func updateViewConstraints() {
super.updateViewConstraints()
}
override func viewDidLoad() {
super.viewDidLoad()
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.scrollDirection = UICollectionView.ScrollDirection.vertical
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
layout.itemSize = CGSize(width: 50, height: 50)
collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(StickersCell.self, forCellWithReuseIdentifier: StickersCell.reuseIdentifier)
collectionView.backgroundColor = UIColor.white
collectionView.showsHorizontalScrollIndicator = false
collectionView.backgroundColor = UIColor.red
collectionView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(collectionView)
self.nextKeyboardButton = UIButton(type: .system)
self.nextKeyboardButton.setTitle(NSLocalizedString("Next Keyboard", comment: "Title for 'Next Keyboard' button"), for: [])
self.nextKeyboardButton.sizeToFit()
self.nextKeyboardButton.translatesAutoresizingMaskIntoConstraints = false
self.nextKeyboardButton.backgroundColor = UIColor.white
self.nextKeyboardButton.addTarget(self, action: #selector(handleInputModeList(from:with:)), for: .allTouchEvents)
self.view.addSubview(self.nextKeyboardButton)
self.nextKeyboardButton.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
self.nextKeyboardButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
self.collectionView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
self.collectionView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
self.collectionView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
self.collectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
}
override func textWillChange(_ textInput: UITextInput?) {
// The app is about to change the document's contents. Perform any preparation here.
}
override func textDidChange(_ textInput: UITextInput?) {
// The app has just changed the document's contents, the document context has been updated.
var textColor: UIColor
let proxy = self.textDocumentProxy
if proxy.keyboardAppearance == UIKeyboardAppearance.dark {
textColor = UIColor.white
} else {
textColor = UIColor.black
}
self.nextKeyboardButton.setTitleColor(textColor, for: [])
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return stickerImages.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: StickersCell.reuseIdentifier, for: indexPath) as! StickersCell
cell.setImage(stickerImages[indexPath.item]!)
return cell
}}
这是我的 Collection 查看单元格 class:
class StickersCell: UICollectionViewCell {
static let reuseIdentifier: String = "StickersCell"
lazy var imageView: UIImageView = {
let imageView = UIImageView(frame: .zero)
imageView.contentMode = .scaleAspectFit
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.clipsToBounds = true
contentView.addSubview(imageView)
imageView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
imageView.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
imageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setImage(_ image: UIImage) {
imageView.image = image
}}
将 collection 视图添加到任何 UIView
或 UIViewController
时,此代码工作正常,但当尝试将其添加到键盘时,它会抛出此类错误:
据我所知我放置了错误的约束,但我不明白到底哪里出了问题,尤其是当它在简单视图或视图控制器中工作正常时。
我用 google 搜索了 allot,但找不到任何解决方案... 此外,这个 SO 问题也没有帮助:
- First question
- Second question
- Third question
我也尝试过将创建 collection 视图的代码移动到 viewDidAppear
和 viewWillAppear
方法中,但同样没有成功。
还有一件奇怪的事:
如果我向键盘添加具有相同约束的简单 UIView
- 一切正常。问题似乎专门针对 collection 视图。
那么,我错过了什么?将不胜感激任何帮助,因为我已经与这个问题斗争了一个多星期了...
更新:
阅读 Apple 开发者论坛后,我想到了一个想法:
我之前创建了与 UICollectionView
相同的 UITableView
并且奇怪的是它有效。那么有下一个问题:
你能用 UICollectionView
作为自定义键盘吗?
与这个问题斗争了 2 周后终于找到了解决方法:
由于某些原因,您不能在 UICollectionViewCell
中使用 UIImageView
或 MSStickerView
,就像在 iMessage Extension 中一样,所以我只是添加了透明的 UIButton
和 UIImage
在此按钮内并且有效!
仍然不知道为什么你不能使用图像或视图,也找不到任何关于它的具体信息,但我的解决方案有效,我希望这对以后的人有所帮助。