Reputation: 2775
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");
}
}
Upvotes: 8
Views: 3684
Reputation: 104082
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.
Upvotes: 3