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");
}
}
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.
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!
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With