1

I have created a view like this in my xamarin iOS mobile project. Job Images View

User will be able to click on the capture images button to take a picture and set the image property of the image view. I would like to know how can i allow the user longpress a image (after it has been captured) and popup a message box to delete the image.

I have tried what Sameer has suggested in his comment like so in my ViewDidLoad

    var gestureRecognizer = new UILongPressGestureRecognizer();
    gestureRecognizer.AddTarget(() => ButtonLongPressed(gestureRecognizer));
    img1.AddGestureRecognizer(gestureRecognizer);
    img2.AddGestureRecognizer(gestureRecognizer);

When i click and hold on the image nothing happens. I have added these image views via the designer.

After a little more research and using the comment from @Junior Jiang - MSFT. I have made a bit progress but i would like to know which UIImage view has been clicked.

Heres my current code:

 public JobImagesViewController(Job passedInCurrentJob) : base("JobImagesViewController", null)
        {
            currentJob = passedInCurrentJob;
            uIImageViews = new List<UIImageView>();           
        }

    public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            uIImageViews.Add(img1);
            uIImageViews.Add(img2);
            uIImageViews.Add(img3);
            uIImageViews.Add(img4);
            uIImageViews.Add(img5);
            uIImageViews.Add(img6);
            uIImageViews.Add(img7);
            uIImageViews.Add(img8);
            uIImageViews.Add(img9);
            uIImageViews.Add(img10);

            InitialiseImageGrid();

            // Add a Save button to the navigation bar
            this.NavigationItem.SetRightBarButtonItem(
                new UIBarButtonItem("Save", UIBarButtonItemStyle.Done, (sender, args) =>
                {
                    //TODO if else block with all logic to check if there are images etc.
                    //TODO prompt user and ask if they would like to save images.
                    UIAlertView alert = new UIAlertView("Save Images?", "Save images against the Job?", null, "Yes", new string[] { "No" });
                    alert.Clicked += (s, e) =>
                    {
                        if (e.ButtonIndex == 0) // Yes clicked
                        {
                            SaveJobImages();
                        }
                    };
                    alert.Show();

                }), true);

        }


   [Export("ImageLongPressed:")]
        public void ImageLongPressed(UILongPressGestureRecognizer gestureRecognizer)
        {
            if (gestureRecognizer.State != UIGestureRecognizerState.Began)
            {
                return;
                // Needed because selector is executed twice, because Long-press gestures are continuous
            }
            // Perform action of opening the dialog to select/take a picture, replacing the ? image with the new image
            UIAlertView alert = new UIAlertView("Delete this image ?" , "Are you sure you want to delete this image?", null, "Yes", new string[] { "No" });
            alert.Clicked += (s, e) =>
            {
                if (e.ButtonIndex == 0) // 'Accept' clicked
                {
                    // TODO how to get the image which has been clicked??
                }
            };
            alert.Show();

        }


        private void InitialiseImageGrid()
        {
            _imageList = DataAccess.GetImages(currentJob.jobAddressID);
            var imageBytes = _imageList.Select(x => x.ImageBytes).ToList();

            var gestureRecognizer = new UILongPressGestureRecognizer(this, new ObjCRuntime.Selector("ImageLongPressed:"));
            gestureRecognizer.AddTarget(() => ImageLongPressed(gestureRecognizer));

            // Populate the image views.
            // TODO need to find a way to assign it to every imageview on the view without looping maybe linq???
            int i = 0;
            foreach (var item in imageBytes)
            {
                var imagedata = NSData.FromArray(item);
                var img = UIImage.LoadFromData(imagedata);

                if (uIImageViews != null && uIImageViews.Count > i)
                {
                    uIImageViews[i].UserInteractionEnabled = true;
                    uIImageViews[i].AddGestureRecognizer(gestureRecognizer);
                    uIImageViews[i].AddGestureRecognizer(gestureRecognizer);
                    uIImageViews[i].Image = img;
                }
                i++;

        }
Abe
  • 1,879
  • 2
  • 24
  • 39

2 Answers2

1

It depends on how you are creating your view, are you using a XIB with all the images on there as buttons with images, and IBActions connected to those buttons. just make the sender a UILongPressGestureRecognizer.

If you are doing it through code, then in your ViewDidLoad you want to set your buttons to have an initial ? (or Image Needed) background image and then you add the UILongPress GestureRecognizer to each on of them. So if you had one button, you would do this:

public override void ViewDidLoad ()
{
    // Perform any additional setup after loading the view

    UIButton button = new UIButton (new System.Drawing.RectangleF(100, 100, 100, 30));
    button.SetBackgroundImage ("imageNeeded", UIControlState.Normal);
    var gestureRecognizer = new UILongPressGestureRecognizer ();
    gestureRecognizer.AddTarget(() => this.ButtonLongPressed(gestureRecognizer));
    button.AddGestureRecognizer(gestureRecognizer);
    this.View.Add (button);
}

public void ButtonLongPressed(UILongPressGestureRecognizer gestureRecognizer)
{
    if (gestureRecognizer.State != UIGestureRecognizerState.Began) 
    {
          return;
          // Needed because selector is executed twice, because Long-press gestures are continuous
    }
    // Perform action of opening the dialog to select/take a picture, replacing the ? image with the new image
}
Marwen Doukh
  • 1,946
  • 17
  • 26
Saamer
  • 4,687
  • 1
  • 13
  • 55
  • @Sameer - I am planning on having buttons on the screen with a sample image. Users can click the button to open up the camera and set the image. Can i have a single click event for all buttons rather than 10 events for 10 buttons. I will certainly try your code when user would like to delete a picture. – Abe Jun 26 '19 at 16:00
  • Since the work you want to do is different for each one, and since its not exactly an event, you would have to create individual GestureRecognizers – Saamer Jun 26 '19 at 16:03
  • @Sameer - I slightly changed the plan, I added a single button 'capture images' and 10 UIImageviews. When user clicks the capture button i go through each image view and see which one is free and set the image accordingly. However I am unable to setup the long press gesture as you suggested in your code. I have added the image views via designer by the way. – Abe Jun 27 '19 at 10:01
  • @Sameer - I have updated my question now. Thank you. – Abe Jun 27 '19 at 10:07
0

If want to use UILongPressGestureRecognizer in UIImage, should set ImageView's UserInteractionEnabled be true.

As follow:

List<UIImageView> imageViews = new List<UIImageView>();

UIImage image = UIImage.FromFile("off.png");
ImageViewOne.Image = image;
ImageViewOne.Tag = 1;
ImageViewTwo.Image = image;
ImageViewTwo.Tag = 2;

imageViews.Add(ImageViewOne);
imageViews.Add(ImageViewTwo);

foreach (var imageview in imageViews)
{
    imageview.UserInteractionEnabled = true;
    UILongPressGestureRecognizer uITapGestureRecognizer = new UILongPressGestureRecognizer();
    uITapGestureRecognizer.AddTarget(() => { Console.WriteLine("You choose View " + imageview.Tag); });
    imageview.AddGestureRecognizer(uITapGestureRecognizer);
}

Here is official document from Apple.

Junior Jiang
  • 12,430
  • 1
  • 10
  • 30
  • Thanks for your comment, I have set the UserInteractionenabled = true; in code and also in the controls properties. The code from your comment is present in my ViewDidLoad() method. And ButtonLongPressed never gets fired. What am i missing?? – Abe Jun 28 '19 at 13:05
  • @Abe Okey , you can show full code about this part in question ,or sharing a sample, I will check that. – Junior Jiang Jul 01 '19 at 01:47
  • Thanks for your comment. I have made a bit of progress, i am able to catch the long press gesture however i am unable to find out which UIImageview has been pressed. – Abe Jul 01 '19 at 13:58
  • @Abe You can set `Tag` for each `ImageView`, I will update answer .If be helpful , thanks for marking in advance. – Junior Jiang Jul 02 '19 at 01:31