0

I have a UIScrollView into which I am creating and adding UILabels containing the results of a simple LINQ query.

I have set up a UISwipeGestureRecognizer within the loop that generates the labels (iOS: issues with UIGestureRecognisers vs Subviews says I need a new recogniser for each control - I'm assuming I can do with a UILabel the same as UIImageView for adding a recogniser) and then added the recogniser to the label.

When the view containing the UIScrollView is started, the scrollview works as expected, but the swipe isn't.

Caveat : only tried this on the simulator, my iPhone is acting up.

private void CreateViewHistory()
    {
        float xtext = 4f;
        float y = 4f;
        int c = 0;
        var tv = tank.Events.OrderByDescending(t => t.Date).ToList();
        tbiHistClearAll.Enabled = enableDelete;
        //tgrRemove.AddTarget(this, new Selector("screenSwipe"));
        //pgrRemove.DelaysTouchesBegan = true;
        foreach (var e in tv)
        {

            var tgrRemove = new UISwipeGestureRecognizer()
            {
                NumberOfTouchesRequired = 1,
                Direction = UISwipeGestureRecognizerDirection.Right,
            };

            tgrRemove.AddTarget(this, new Selector("screenSwipe"));

            svHistoryEvents.PanGestureRecognizer.RequireGestureRecognizerToFail(tgrRemove); 
            string info = string.Format("{0} - {1}{2} ({3})\n{4} - {5}\n{6} - {7}\n{8} - {9}", e.EventType, e.Volume, AppDelegate.Self.db.getShortVolumeUnits(), e.Date.ToShortDateString(), 
                              StringUtils.GetString("Sowcrop.Implement"), e.Implement != null ? e.Implement.ImplementType : StringUtils.GetString("Common.NonRecorded"), 
                              StringUtils.GetString("Common.User"), StringUtils.GetString("Common.NonRecorded"), 
                              StringUtils.GetString("Common.Notes"), !string.IsNullOrEmpty(e.Notes) ? e.Notes : StringUtils.GetString("Common.NonRecorded"));
            var lbl = new UILabel()
            {
                UserInteractionEnabled = true
            };

            lbl = UICreation.MakeLabelWithTag(svHistoryEvents, new RectangleF(xtext, y, 320f, 90f), info, UITextAlignment.Left, UIColor.Black, false, 4, c); 
            lbl.AddGestureRecognizer(tgrRemove); 
            svHistoryEvents.AddSubview(lbl);
            lblTemp.Add(lbl);
            c++;
            y += 94f;
        }
        UIUtils.ResizeScrollView(svHistoryEvents);
    }

    [Export("screenSwipe")]
    public void SwipeRemove(UIGestureRecognizer s)
    {
        var swipe = s as UIGestureRecognizer;
        var tv = tank.Events.OrderByDescending(t => t.Date).ToList();
        var txt = swipe.View as UILabel;
        switch (swipe.State)
        {
            case UIGestureRecognizerState.Began:
                Console.WriteLine("Swipe began");
                break;
            case UIGestureRecognizerState.Changed:
                Console.WriteLine("Swipe changed");
                tv.RemoveAt(txt.Tag);
                CreateViewHistory();
                break;
            case UIGestureRecognizerState.Ended:
                Console.WriteLine("Swipe ended");
                break;
            case UIGestureRecognizerState.Cancelled:
                Console.WriteLine("Swipe cancelled");
                break;
        }
    }

MakeLabelWithTag generates a UILabel which can then be added to the scrollview.

Am I missing something here, or do I need to do something special as the label is held within a scrollview?

I've also tried what has been suggested at UISwipeGestureRecogniser in a UIScrollView, but still without success.

Community
  • 1
  • 1
Nodoid
  • 1,449
  • 3
  • 24
  • 42

1 Answers1

0

Found the problem and it's probably the dumbest thing I've encountered in a long time!

To get the swipe gesture to work within a scrollview, you have to first encompass whatever it is you want to add within a UIView and then add that to the scrollview.

To therefore get a swipe within a scrollview to work, you need to do the following

 private void CreateViewHistory()
    {
        foreach (var i in svHistoryEvents.Subviews)
            if (i is UIView)
                i.RemoveFromSuperview();
        float xtext = 4f;
        float y = 4f;
        int c = 0;
        tbiHistClearAll.Enabled = enableDelete;
        foreach (var e in tv)
        {

            var tgrRemove = new UISwipeGestureRecognizer()
            {
                NumberOfTouchesRequired = 1,
                Direction = UISwipeGestureRecognizerDirection.Right,
            };

            tgrRemove.AddTarget(this, new Selector("screenSwipe"));
            var view = new UIView(new RectangleF(xtext, y, 320f, 90f));
            svHistoryEvents.PanGestureRecognizer.RequireGestureRecognizerToFail(tgrRemove); 
            string info = string.Format("{0} - {1}{2} ({3})\n{4} - {5}\n{6} - {7}\n{8} - {9}", e.EventType, e.Volume, AppDelegate.Self.db.getShortVolumeUnits(), e.Date.ToShortDateString(), 
                              StringUtils.GetString("Sowcrop.Implement"), e.Implement != null ? e.Implement.ImplementType : StringUtils.GetString("Common.NonRecorded"), 
                              StringUtils.GetString("Common.User"), StringUtils.GetString("Common.NonRecorded"), 
                              StringUtils.GetString("Common.Notes"), !string.IsNullOrEmpty(e.Notes) ? e.Notes : StringUtils.GetString("Common.NonRecorded"));
            var lbl = new UILabel()
            {
                UserInteractionEnabled = true
            };

            lbl = UICreation.MakeLabelWithTag(svHistoryEvents, new RectangleF(0, 0, 320f, 90f), info, UITextAlignment.Left, UIColor.Black, false, 4, c); 
            view.AddGestureRecognizer(tgrRemove); 
            view.AddSubview(lbl);
            svHistoryEvents.AddSubview(view);
            lblTemp.Add(lbl);
            c++;
            y += 94f;
        }
        UIUtils.ResizeScrollView(svHistoryEvents);
    }

    [Export("screenSwipe")]
    public void SwipeRemove(UIGestureRecognizer s)
    {
        var swipe = s as UIGestureRecognizer;
        var txt = swipe.View.Subviews[0] as UILabel;
        switch (swipe.State)
        {
            case UIGestureRecognizerState.Began:
                Console.WriteLine("Swipe began");
                break;
            case UIGestureRecognizerState.Changed:
                Console.WriteLine("Swipe changed");
                break;
            case UIGestureRecognizerState.Ended:
                Console.WriteLine("Swipe ended");
                tv.RemoveAt(txt.Tag);
                CreateViewHistory();
                break;
            case UIGestureRecognizerState.Cancelled:
                Console.WriteLine("Swipe cancelled");
                break;
        }
    }

It is not possible to add just a UILabel and have the swipe act on that, it has to be on a UIView with the label as a subview to it.

Nodoid
  • 1,449
  • 3
  • 24
  • 42