2

I want the image of users to popup (without action option) and then be dismissed if touched outside.

Say table view consist of 2 UI elements (a button and a text) and one picture. How would you set the pop up context menu for only the picture - immy?

public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as!  ViewControllerTableViewCell
    let immy = cell.viewWithTag(1) as! UIImageView
    let person: Userx = people[indexPath.row]
    let button = cell.viewWithTag(3) as! UIButton
    cell.lblName.text = person.Education
    cell.postID = self.people[indexPath.row].postID
    if let PhotoPosts = person.PhotoPosts {
        let url = URL(string: PhotoPosts)
        print(PhotoPosts, "sttdb")
        immy.sd_setImage(with: url)
    }
    return cell
}

extension homepage {
    func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
        let configuration = UIContextMenuConfiguration(identifier: nil, previewProvider: nil)
        return configuration
    }
}

Below is the ViewControlleTableViewCell, added after the first comment. My reply to the comment also explains how this looks in main.storyboard.

class ViewControllerTableViewCell: UITableViewCell {    

    @IBOutlet weak var button: UIButton!
    @IBOutlet weak var immy: UIImageView!
    @IBOutlet weak var lblgenre1: UILabel!    
    @IBOutlet weak var lblName: UILabel!
    @IBOutlet weak var lblName1: UILabel!
    @IBOutlet weak var likeLabel: UILabel!

    var postID: String!
    var caption1: String!
    var keyToPost: String!
    var latestLocation1: [String: Double]?
    let databaseRef = Database.database().reference()
    var refArtists: DatabaseReference!

    let profileImageView: UIImageView = {
        let imageView = UIImageView()
        
        return imageView
    } ()
    
    override func awakeFromNib() {
        super.awakeFromNib()
    }
    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }

    @IBAction func button1(_ sender: Any) {

    }
    @IBAction func button2NBTHISISTORPREVENTSEGUE(_ sender: Any) {

    }
}

In homepage:

 let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ViewControllerTableViewCell
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
uuuuuu
  • 119
  • 1
  • 7
  • 1
    What do you mean by "set the pop up context menu for only the picture"? – matt Jul 15 '20 at 00:23
  • "table view consist of 2 UI elements" you meant your cell. So you need to create a context menu for the image not for your table view elements (UITableViewCell) – Leo Dabus Jul 15 '20 at 00:31
  • Show you ViewControllerTableViewCell declaration – Leo Dabus Jul 15 '20 at 00:35
  • Note that it is Swift naming convention to name your classes starting with an uppercase letter `HomePage` – Leo Dabus Jul 15 '20 at 00:36
  • @LeoDabus Yeah. The cell/table view consists for each user of: 1) An image (2) a text, and (3) a button - horizontally next to each other - image left, text middle, and button right. Then the next user is underneath that. I need the image, once pressed, to pop up without action prompts. Then dismissed once clicked outside. – uuuuuu Jul 15 '20 at 00:40
  • @LeoDabus I added the ViewControllerTableViewCell parts of ViewControllerTableViewCell and homepage. Yeah, homepage should be capital – uuuuuu Jul 15 '20 at 00:46
  • @matt I mean if you touch the picture if pops up with context menu (that has no action option), but that doesn't happen if you click the button or the text next to the image – uuuuuu Jul 15 '20 at 00:47
  • "that doesn't happen if you click the button or the text next to the image" So in those circumstances, return `nil` instead of `configuration`. You are not looking at the `location`. Look at it. – matt Jul 15 '20 at 00:57

1 Answers1

2

What you need is to enable user interaction in your UIImageView, make your ViewControllerTableViewCell conform to UIContextMenuInteractionDelegate, create an UIContextMenuInteraction and set your cell as the delegate. Then add the iteraction to your image view. Don't forget to remove the contextMenuInteraction method from your HomePage extension.

Your ViewControllerTableViewCell contextMenuInteraction interaction implementation should look like this:

import UIKit

class ViewControllerTableViewCell: UITableViewCell, UIContextMenuInteractionDelegate {
    @IBOutlet weak var immy: UIImageView!
    override func awakeFromNib() {
        super.awakeFromNib()
        immy.isUserInteractionEnabled = true
        immy.addInteraction(UIContextMenuInteraction(delegate: self))
    }
    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
    func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
        UIContextMenuConfiguration(identifier: nil, previewProvider: nil)  { _ in
            let share = UIAction(title: "Share", image: UIImage(systemName: "square.and.arrow.up")) { _ in
               // share code
            }
            return UIMenu(title: "Profile Picture Menu", children: [share])
        }
    }
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • Thanks. I am trying it. There is one } too many at the bottom, right? – uuuuuu Jul 15 '20 at 20:20
  • Just make sure to balance the brackets. I think my code above is correct – Leo Dabus Jul 15 '20 at 20:21
  • 1
    Yeah. It was one } too many, but it works! Thanks a lot! I will mark the question as solved. Btw, is there any way to make the pop up image larger? – uuuuuu Jul 15 '20 at 20:26
  • just a last question.: immy in ViewControllerTableViewCell is linked to 3 different pages (the image displayed on all 3). For some reason the code at ViewControllerTableViewCell only makes 2 of them have the popup when long pressed. What do you guess would be the most likely difference that makes the popup not occur on the 3rd page? I know it is just a snippet, but after looking at the code for the past 2 hours, I fear it might be DispatchQueue.main.async, because it reloads. – uuuuuu Jul 17 '20 at 23:38
  • `DispatchQueue.main.async{ print(uid) let usersRef = Database.database().reference().child("people") let thisUser = usersRef.child(uid) thisUser.observeSingleEvent(of: .value, with: { snapshot in ... let p = Usery(C: C, postID: postID, A: A, photoPosts: photoPosts, B: B as? Int) self.person.insert(p, at: 0) self.table.reloadData() }) }` – uuuuuu Jul 17 '20 at 23:40
  • `DispatchQueue.main.async {` should be only using when updating the user interface. Take your firebase code out of it – Leo Dabus Jul 17 '20 at 23:55
  • Gocha, but that wasn't the cause of it not working on that page. I remove it and then played around with it, didn't work. immy and ViewControllerTableViewCell are linked to that page as well. User interaction enabled (code and storyboard), so I find it very weird why it works on the other pages and not the 3rd – uuuuuu Jul 18 '20 at 14:22