Ok, I have looked at similar posts like Select items programmatically in UICollectionView and tried my own methods, but I cannot select an item in my programmatically created UICollectionView with Swift.
I am building an iMessage extension and I made the UICollectionview to store custom MSStickerViews instead of the MSStickerBrowser. I create my MSStickerViews like this, which have a custom class on the MSStickerView to detect when they are peeled or tapped:
var url: URL?
var i = 1
while i < 5 { //while true
url = Bundle.main.url(forResource: "test5", withExtension: "png") //would be "test\(i)"
print("URL IS THIS: \(url)")
guard let url = url else { break }
//make it a sticker
let sticker = try! MSSticker(contentsOfFileURL: url, localizedDescription: "test\(i)")
//let stickerView = InstrumentedStickerView(frame: CGRect(x: 0, y: 0, width: view.bounds.width*0.4, height: view.bounds.width*0.4))
let stickerView = InstrumentedStickerView(frame: CGRect(origin: CGPoint(x: 0,y :0), size: stickerSize))
stickerView.sticker = sticker
stickerView.delegate = self
starterPack.append(stickerView)
i += 1
Then in my custom class which I adopted from another post:
protocol InstrumentedStickerViewDelegate: class {
func stickerViewDidSelect(stickerView: MSStickerView)
func stickerViewDidPeel(stickerView: MSStickerView)
}
class InstrumentedStickerView: MSStickerView {
weak var delegate: InstrumentedStickerViewDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
for gestureRecognizer in gestureRecognizers ?? [] {
if let tapGestureRecognizer = gestureRecognizer as? UITapGestureRecognizer {
tapGestureRecognizer.addTarget(self, action: #selector(didTap))
} else if let longPressGestureRecognizer = gestureRecognizer as? UILongPressGestureRecognizer {
longPressGestureRecognizer.addTarget(self, action: #selector(didLongPress))
}
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func didTap(tapGestureRecognizer: UITapGestureRecognizer) {
if tapGestureRecognizer.state == .recognized {
delegate?.stickerViewDidSelect(stickerView: self)
}
}
func didLongPress(longPressGestureRecognizer: UILongPressGestureRecognizer) {
if longPressGestureRecognizer.state == .began {
delegate?.stickerViewDidPeel(stickerView: self)
}
}
}
My issue is I need to be able to PROGRAMMATICALLY (like with a button) select one of my sticker views at its place in my collection view. Meaning simulating the user tapping the sticker and making it appear in the iMessage text entry field.
I did not know how to go about just putting the sticker in the entry field directly, this is why I am going with the simulate tapping approach.
My collection view has a header, and I have tried using the following to select the item in the collection view, but despite trying to navigate the different rows/sections when I put in 0,0 nothing happens (suspect it was selecting the header) and anything else either does nothing or does Uncaught exception error:
collectionView.selectItem(at: IndexPath(row: 0, section: 1), animated: false, scrollPosition: UICollectionViewScrollPosition.left)
I have called the didTap and custom funcs from the class directly, but this did not select the sticker just called the function:
stickerViewDidSelect(stickers[1])
I need to find a way to trigger a tap event on the MSStickerView/MSSticker to put it in the entry field. How can I do this?