Hello,
I am building application where you have custom keyboard. I used Collection View to display set of stickers, but for some reason it's not working, and throws errors related to constraints when switching to that keyboard.
After that, I've use same coding approach and created Table View and it's working just fine.
Question: Are you able to use Collection View inside Custom Keyboard?
Here's my code in Keyboard class:
It's working fine, if I use it in UIView, or in UIViewController.
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
}
}
And that's how I create Collection View Cell
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
}
}