I am creating a app for iMessage only, searching images & populating a UICollectionView, the problem is that I cannot select the items. I need to be able to tap/select an item so it can be passed as the message layout & then send it but that part seems to be not working.
class MessagesViewController: MSMessagesAppViewController, UISearchBarDelegate {
var images_results: [Result] = []
let searchbar = UISearchBar()
private var collectionView: UICollectionView?
override func viewDidLoad() {
super.viewDidLoad()
searchbar.delegate = self
collectionView?.delegate = self
view.addSubview(searchbar)
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.minimumLineSpacing = 6
layout.minimumInteritemSpacing = 2
let itemSize = view.frame.size.width/3.5
layout.itemSize = CGSize(width: itemSize, height: itemSize)
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.register(ImageCollectionViewCell.self, forCellWithReuseIdentifier: ImageCollectionViewCell.identifier)
collectionView.allowsSelection = true
collectionView.dataSource = self
view.addSubview(collectionView)
collectionView.backgroundColor = .systemBackground
self.collectionView = collectionView
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
searchbar.frame = CGRect(x: 10, y: view.safeAreaInsets.top, width: view.frame.size.width-20, height: 50)
collectionView?.frame = CGRect(x: 7, y: view.safeAreaInsets.top+55, width: view.frame.size.width-15, height: view.frame.size.height-55)
searchbar.placeholder = "Search Images"
}
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
requestPresentationStyle(.expanded)
return true
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchbar.resignFirstResponder()
if let text = searchbar.text {
images_results = []
collectionView?.reloadData()
fetchPhotos(query: text)
}
}
func fetchPhotos(query: String) {
let urlString = "https://api.url.com"
guard let url = URL(string: urlString) else { return }
let task = URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
guard let data = data, error == nil else { return }
do {
let jsonResult = try JSONDecoder().decode(APIResponse.self, from: data)
print("GOT DATA")
DispatchQueue.main.async {
self?.images_results = jsonResult.results
self?.collectionView?.reloadData()
}
} catch {
print("WE GOT AN ERROR: \(error)")
}
}
task.resume()
}
// MARK: - Conversation Handling
override func willBecomeActive(with conversation: MSConversation) {
fetchPhotos(query: ["animals", "fruits", "cars", "memes", "houses", "ocean"].randomElement()!)
// Called when the extension is about to move from the inactive to active state.
// This will happen when the extension is about to present UI.
// Use this method to configure the extension and restore previously stored state.
}
override func didTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
if presentationStyle == .expanded {
searchbar.becomeFirstResponder()
}
// Called after the extension transitions to a new presentation style.
// Use this method to finalize any behaviors associated with the change in presentation style.
}
}
extension MessagesViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print(indexPath.item)
}
}
extension MessagesViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images_results.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let imageURLString = images_results[indexPath.row].urls.thumb
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ImageCollectionViewCell.identifier, for: indexPath) as? ImageCollectionViewCell else {
return UICollectionViewCell()
}
cell.configure(with: imageURLString)
return cell
}
}
//Custom Cell
class ImageCollectionViewCell: UICollectionViewCell {
static let identifier = "ImageCollectionViewCell"
private let imageView: UIImageView = {
let imageView = UIImageView()
imageView.clipsToBounds = true
imageView.contentMode = .scaleAspectFill
imageView.layer.cornerRadius = 4
return imageView
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(imageView)
}
required init? (coder: NSCoder) {
fatalError ()
}
override func layoutSubviews() {
super.layoutSubviews()
imageView.frame = contentView.bounds
}
override func prepareForReuse() {
super.prepareForReuse()
imageView.image = nil
}
override func awakeFromNib() {
super.awakeFromNib()
print("awakefromnib")
selectedItem()
}
func configure(with urlString: String) {
guard let url = URL(string: urlString) else {
return
}
URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
guard let data = data, error == nil else { return }
DispatchQueue.main.async {
let image = UIImage(data: data)
self?.imageView.image = image
}
}.resume()
}
func selectedItem() {
self.imageView.alpha = 0.7
}
}
This is the only part that is not working:
extension MessagesViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
...code for preparing image for message, right now I only have a print statement which is doing nothing ...
}
}
I should be able to select an image to add to message but is not working