Alright, I have looked at How to trigger tap gesture recognizer of UIView programmatically and similar questions but cant find what I am looking for. I am building an iMessage app extension, and need too programmatically trigger a tap event on an MSSticker.
I have made custom MSStickerViews with the following class that detects when it has been pressed and/or tapped, then triggers another function, however I do not know how to actually SIMULATE these taps so that the sticker will be put in the entry field:
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)
}
}
}
The reason why just calling one of the tap functions above won't work is I don't need to trigger any certain function with the tap - I just need to create a fake tap on the MSSticker within the MSStickerView so it will be put in the entry field. I have no idea how to do this.
I create my MSStickerViews like this and put them in a collection view, but programmatically tapping the collection view cell does nothing (Ive tried):
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
I have a feeling maybe something like (pseudo code)
starterPack[1].sendActionForEvent(UIEvent.Tap)
is correct, but the MSStickerView doesn't have .sendActionForEvent
I am desperate. How can I create a fake tap?
You have to create a
MSMessage
, which you than caninsert
to your currentMSConversation
.See Apples sample code.