2015-01-21 9 views
5

Diciamo che ho un ViewController con un UICollectionView seduto su di esso. Come posso far passare Touches attraverso lo UICollectionView e nelle funzioni /TouchesMoved/TouchesEnded del ViewController? Ho fatto questo più volte con UIScrollViews semplicemente impostando ExclusiveTouch = false e il tocco sarebbe quindi consentito di passare attraverso il UIScrollView alla sua superview. Ma lo stesso approccio non funziona con UICollectionViews. Qualche idea?Consenti ai tocchi di passare attraverso un UICollectionView al suo Superview

Set di fino 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); 
     } 

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

    } 

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

} 

Consente di impostare UIViewController che detiene il CollectionView. Voglio ottenere tocchi in TouchesBegan/Moved/Ended qui!

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"); 
    } 

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

} 

Questo è il mio UICollectionView classe. Non ho potuto ottenere tocchi in modo UIViewController Li ho provati arrivare qui, ma non ci sono riuscito ....

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"); 
    } 
} 
+0

Vuoi che il tocco venga riconosciuto sia dalla vista raccolta che dalla vista sottostante o solo dalla vista sottostante? – rdelmar

+0

Voglio che la collectionview funzioni, ma quando tocchi semplicemente, o premi-tieni premuto-trascina per avere la vista sottostante per catturare TouchesBegan/Moved/Ended. Quindi probabilmente entrambi. UIScrollViews può fare entrambe le cose, quindi sto cercando di capire perché UICollectionViews non può. O se possono come possono? – LampShade

risposta

2

Non so se questo è il modo corretto, ma ignorando touchesBegan, ecc la sottoclasse della vista raccolta e la chiamata su super come su nextResponder sembra funzionare. In Objective-C, ho fatto questo,

@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]; 
} 

Poi, nella vista sottostante, ho anche implementato questi tre metodi, e gestito i tocchi.

+0

Giusto, questo ha senso. L'ho fatto prima con successo con altre collezioni in Xamarin. Ma per qualche ragione le mie funzioni Touches non vengono nemmeno chiamate con UICollectionView o ViewController. Questo è molto strano È quasi come se il CollectionView stia catturando i tocchi e non lasciandoli andare da nessun'altra parte. Da qui la mia sperimentazione con ExclusingTouch = false – LampShade

+0

@LampShade: può essere che la tua cellula della raccolta delle immagini ottenga quegli eventi – Gokul

+0

Questa soluzione è pulita. Lo sto facendo per l'app nativa e la tua idea è utile. –