Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow touches to pass through a UICollectionView to it's Superview

Let's say I have a ViewController with a UICollectionView sitting on it. How can I get Touches to pass through the UICollectionView and into the ViewController's TouchesBegan/TouchesMoved/TouchesEnded functions? I've done this many times with UIScrollViews simply by setting ExclusiveTouch = false and the touch would then be allowed to pass through the UIScrollView to it's superview. But that same approach doesn't work with UICollectionViews. Any ideas?

Set's up UICollectionView:

partial class CyanViewController : BaseViewControllerWithCollection
{

    /*--------------------------------------------------------------------------------*/
    // Constructors
    /*--------------------------------------------------------------------------------*/

    public CyanViewController (IntPtr handle) : base (handle)
    {
    }

    /*--------------------------------------------------------------------------------*/

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

        // Setup collection view
        this.SetupCollectionView();
    }

    /*--------------------------------------------------------------------------------*/

    public override void TouchesBegan (NSSet touches, UIEvent evt)
    {
        base.TouchesBegan (touches, evt);

        Console.WriteLine ("TouchesBegan");
    }

    /*--------------------------------------------------------------------------------*/
    // Private Methods
    /*--------------------------------------------------------------------------------*/

    private void SetupCollectionView ()
    {
        Console.WriteLine ("SetupCollectionView");
        try
        {
            // Instantiate collection view
            this.CollectionView = new UICollectionView(
                this.View.Bounds,
                new UICollectionViewFlowLayout() { 
                    ScrollDirection = UICollectionViewScrollDirection.Vertical,
                    ItemSize = new CGSize(75, 115),
                    SectionInset = new UIEdgeInsets(20, 20, 20, 20)
                }
            );

            // Setup delegate and data source
            this.CollectionView.Delegate = new ProductTypeCollectionViewDelegate(this);
            this.CollectionView.DataSource = new ProductTypeCollectionViewDataSource(this);
            this.CollectionView.RegisterClassForCell(typeof(BaseCollectionViewCell), BaseCollectionViewCell.s_millaCellId);
        }
        catch (Exception ex)
        {
            Console.WriteLine ("Exception : " + ex.Message);
            Console.WriteLine ("Exception : " + ex.StackTrace);
        }

        // Add collection view to view
        this.View.AddSubview(this.CollectionView);
    }

    /*--------------------------------------------------------------------------------*/
    // Class: SeedsCollectionViewDataSource
    /*--------------------------------------------------------------------------------*/

    public class ProductTypeCollectionViewDataSource : UICollectionViewDataSource
    {

        /*--------------------------------------------------------------------------------*/
        // Properties
        /*--------------------------------------------------------------------------------*/

        private CyanViewController _parentController;

        /*--------------------------------------------------------------------------------*/
        // Constructors
        /*--------------------------------------------------------------------------------*/

        public ProductTypeCollectionViewDataSource (
            CyanViewController a_parentController
        )
        {
            this._parentController = a_parentController;
        }

        /*--------------------------------------------------------------------------------*/

        private ProductTypeCollectionViewDataSource ()
        {
            throw new NotImplementedException ();
        }

        /*--------------------------------------------------------------------------------*/
        // UICollectionViewDataSource Implementation
        /*--------------------------------------------------------------------------------*/

        public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath)
        {
            var cell = (BaseCollectionViewCell)collectionView.DequeueReusableCell (BaseCollectionViewCell.s_millaCellId, indexPath);

            cell.Label.Text = "Woot";

            return cell;
        }

        /*--------------------------------------------------------------------------------*/

        public override nint GetItemsCount (UICollectionView collectionView, nint section)
        {
            return 10;
        }

        /*--------------------------------------------------------------------------------*/

    }

    /*--------------------------------------------------------------------------------*/
    // Class: SeedsCollectionViewDelegate
    /*--------------------------------------------------------------------------------*/

    public class ProductTypeCollectionViewDelegate : UICollectionViewDelegate
    {

        /*--------------------------------------------------------------------------------*/
        // Properties
        /*--------------------------------------------------------------------------------*/

        private CyanViewController _parentController;

        /*--------------------------------------------------------------------------------*/
        // Constructors
        /*--------------------------------------------------------------------------------*/

        public ProductTypeCollectionViewDelegate (
            CyanViewController a_parentController
        )
        {
            this._parentController = a_parentController;
        }

        /*--------------------------------------------------------------------------------*/

        private ProductTypeCollectionViewDelegate ()
        {
            throw new NotImplementedException ();
        }

        /*--------------------------------------------------------------------------------*/
        // UICollectionViewDelegate Implementation
        /*--------------------------------------------------------------------------------*/

        public async override void ItemSelected (UICollectionView collectionView, NSIndexPath indexPath)
        {
            Console.WriteLine ("ItemSelected indexPath.Row = " + indexPath.Row);
        }

        /*--------------------------------------------------------------------------------*/

    }

    /*--------------------------------------------------------------------------------*/

}

Sets up UIViewController that holds the CollectionView. I want to get touches in TouchesBegan/Moved/Ended here!

partial class BaseViewControllerWithCollection : UIViewController
{

    /*--------------------------------------------------------------------------------*/
    // Properties
    /*--------------------------------------------------------------------------------*/

    public UICollectionView CollectionView { get; set; }

    /*--------------------------------------------------------------------------------*/
    // Constructors
    /*--------------------------------------------------------------------------------*/

    public BaseViewControllerWithCollection (IntPtr handle) : base (handle)
    {
        this.View.ExclusiveTouch = false;
        this.View.UserInteractionEnabled = true;
    }

    public override void TouchesBegan (NSSet touches, UIEvent evt)
    {
        base.TouchesBegan (touches, evt);

        Console.WriteLine ("TouchesBegan");
    }

    public override void TouchesMoved (NSSet touches, UIEvent evt)
    {
        base.TouchesMoved (touches, evt);

        Console.WriteLine ("TOuchesMoved");
    }

    public override void TouchesEnded (NSSet touches, UIEvent evt)
    {
        base.TouchesEnded (touches, evt);

        Console.WriteLine ("TouchesSended");
    }

    /*--------------------------------------------------------------------------------*/

}

This is my UICollectionView Class. I couldn't get touches in the UIViewController so I tried getting them here, but couldn't....

public class MyCollectionView : UICollectionView
{
    public MyCollectionView ( CGRect frame, UICollectionViewLayout layout ) : base (frame, layout)
    {
        this.ExclusiveTouch = false;
        this.UserInteractionEnabled = true;

        this.BackgroundView.UserInteractionEnabled = true;
        this.BackgroundView.ExclusiveTouch = false;
    }

    public override void TouchesBegan (NSSet touches, UIEvent evt)
    {
        base.TouchesBegan (touches, evt);

        Console.WriteLine ("MyCollectionVIew TouchesBegan");
    }

    public override void TouchesMoved (NSSet touches, UIEvent evt)
    {
        base.TouchesMoved (touches, evt);

        Console.WriteLine ("MyCollectionVIew TouchesMoved");
    }

    public override void TouchesEnded (NSSet touches, UIEvent evt)
    {
        base.TouchesEnded (touches, evt);

        Console.WriteLine ("MyCollectionVIew TouchesEnded");
    }
}
like image 343
LampShade Avatar asked Jan 21 '15 23:01

LampShade


People also ask

What is uicollectionview in UIScrollView?

UICollectionView: The main view where the content is displayed, similar to a UITableView. Like a table view, a collection view is a UIScrollView subclass. UICollectionViewCell: This is similar to a UITableViewCell in a table view. These cells make up the view’s content and are subviews to the collection view.

How to implement full scale uicollectionview?

First step in implementing full scale UICollectionView is to create an instance of it, add it on the view and set up desired constraints - in this case pinning to all sides of its superview. A blank UICollectionView with white background - Unfortunately nothing is visible yet!

How to implement uicollectionview in Swift iOS app?

We're going step by step starting from scratch to see how to add and implement simple collectionView with cells to the Swift iOS application. First step in implementing full scale UICollectionView is to create an instance of it, add it on the view and set up desired constraints - in this case pinning to all sides of its superview.

What is uicollectionview in Salesforce?

UICollectionView contains several key components, as you can see below: UICollectionView: The main view where the content is displayed, similar to a UITableView. Like a table view, a collection view is a UIScrollView subclass. UICollectionViewCell: This is similar to a UITableViewCell in a table view.


1 Answers

I don't know if this is the correct way, but overriding touchesBegan, etc. in the collection view subclass, and calling it on super as well as on the nextResponder seems to work. In Objective-C, I did this,

@implementation RDCollectionView

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    [self.nextResponder touchesBegan:touches withEvent:event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.nextResponder touchesMoved:touches withEvent:event];
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    [self.nextResponder touchesEnded:touches withEvent:event];
}

Then, in the underlying view, I also implemented these three methods, and handled the touches.

like image 68
rdelmar Avatar answered Oct 21 '22 17:10

rdelmar