Handling touch events within a child UIScrollView

前端 未结 4 676
青春惊慌失措
青春惊慌失措 2021-02-01 11:27

I\'m displaying a series of images in a UIScrollView. I pretty much want to replicate the Photos application.

My current architecture is:

  • A parent UIScrollView with
  • 4条回答
    •  太阳男子
      2021-02-01 11:39

      This is the Andrey's code with c# translation for monotouch developers... First you need to edit your xib file.. Insert 3 view controllers and make outlets like _page1, _page2, _mainpage.. and link these outlets with views. note you must referance to view controller's view outlet with _mainpage view. (sorry for my english)

          public partial class Test_Details_Controller : UIViewController
      {
          private UIPageControl _pageCont;
      
          private UIScrollView _scView;
          private Object[] _pageViews;
          private int _currentPageIndex;        
          private bool _rotationInProgress;
      
      
          void InitializeAfterLoad ()
          { 
      
              this.Title = "Test";
      
              this._pageCont = CreatePageControll();
      
          }
      
          private UIPageControl CreatePageControll()
          {
              UIPageControl pageControll = new UIPageControl( new RectangleF( 146,348, 38, 20 ) );
              pageControll.BackgroundColor = UIColor.Red;
              pageControll.Alpha = 0.7f;
      
              return pageControll;
          }
      
          private void UpdatePageControll(UIPageControl cont, int current, int pages, UIView showed)
          {
              cont.CurrentPage = current;
              cont.Pages = pages;
              cont.UpdateCurrentPageDisplay();
      
              UIPageControl.AnimationsEnabled = true;
              UIPageControl.BeginAnimations(string.Empty, this.Handle);
              cont.Frame = new RectangleF(showed.Frame.Location.X 
                                              , cont.Frame.Location.Y , pageSize().Width, cont.Frame.Height);         
              UIPageControl.CommitAnimations();
      
          }
      
          private UIView loadViewForPage(int pageIndex){
              UIView _view = null;
              switch ( pageIndex ) {
              case 1:
                  _view = this._page1;
              break;
              case 2:
                  _view = this._page2;
              break;
              default:
                  _view = this._page1;
              break;
              }
              return _view;
          }
      
          private int numberOfPages(){
              return (int)this._pageViews.Count();
          }
      
          private UIView viewForPage( int pageIndex ){
              UIView pageView;
              if(this._pageViews.ElementAt( pageIndex ) == null)
              {
                  pageView = loadViewForPage( pageIndex );
                  _pageViews[ pageIndex ] = pageView;
              }
              else{
                  pageView = (UIView)_pageViews[ pageIndex ];
              }
      
              _scView.AddSubview( pageView );
      
              return pageView;                
          }
      
          private SizeF pageSize(){
              return this._scView.Frame.Size;
          }
      
          private bool isPageLoaded( int pageIndex ){
              return this._pageViews.ElementAt( pageIndex ) != null;
          }
      
          private void layoutPage( int pageIndex ){
      
              SizeF pageSize = this.pageSize();
              ((UIView)this._pageViews[pageIndex]).Frame = new RectangleF( pageIndex * pageSize.Width,0, pageSize.Width, pageSize.Height );
              this.viewForPage( pageIndex );  
      
          }
      
          private void loadView(){
              this._scView = new UIScrollView();
              this._scView.Delegate = new ScViewDelegate( this );
              this._scView.PagingEnabled = true;
              this._scView.ShowsHorizontalScrollIndicator = false;
              this._scView.ShowsVerticalScrollIndicator = false;
              this._scView.Layer.BorderWidth = 2;
              this._scView.AddSubview( _pageCont );
              this.View = this._scView;
      
          }
      
          public override void ViewDidLoad ()
          {
              base.ViewDidLoad ();
              InitializeAfterLoad ();
              this._pageViews = new Object[]{ _page1, _page2 };
              this.loadView();    
          }           
      
          private void currentPageIndexDidChange(){
              this.layoutPage( _currentPageIndex );
      
              if(_currentPageIndex+1 < this.numberOfPages()){
                  this.layoutPage( _currentPageIndex + 1 );
              }
              if(_currentPageIndex >0){
                  this.layoutPage( _currentPageIndex - 1 );
              }
      
              this.UpdatePageControll( _pageCont, _currentPageIndex, this.numberOfPages(), ((UIView)this._pageViews[_currentPageIndex]) );
              this._scView.BringSubviewToFront( _pageCont );
      
      
              this.NavigationController.Title = string.Format( "{0} of {1}", _currentPageIndex + 1, this.numberOfPages() );
          }
      
          private void layoutPages(){
              SizeF pageSize = this.pageSize();
              this._scView.ContentSize = new SizeF( this.numberOfPages() * pageSize.Width, pageSize.Height );
              // move all visible pages to their places, because otherwise they may overlap
              for (int pageIndex = 0; pageIndex < this.numberOfPages(); pageIndex++) {
                  if(this.isPageLoaded( pageIndex ))
                      this.layoutPage( pageIndex );
              }
          }
      
          public override void ViewWillAppear (bool animated)
          {
              this.layoutPages();
              this.currentPageIndexDidChange();
              this._scView.ContentOffset = new PointF( _currentPageIndex * this.pageSize().Width, 0 );
          }
      
          class ScViewDelegate : UIScrollViewDelegate
          {
              Test_Details_Controller id;
              public ScViewDelegate ( Test_Details_Controller id )
              {
                  this.id = id;
              }
              public override void Scrolled (UIScrollView scrollView)
              {
      
                  if(id._rotationInProgress)
                      return;// UIScrollView layoutSubviews code adjusts contentOffset, breaking our logic
      
                  SizeF pageSize = id.pageSize();
                  int newPageIndex = ((int)id._scView.ContentOffset.X + (int)pageSize.Width / 2) / (int)pageSize.Width;
                  if( newPageIndex == id._currentPageIndex )
                      return;
      
                  id._currentPageIndex = newPageIndex;
                  id.currentPageIndexDidChange();
              }
          }
      
          public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
          {
              return toInterfaceOrientation != UIInterfaceOrientation.PortraitUpsideDown;
          }
      
          public override void WillRotate (UIInterfaceOrientation toInterfaceOrientation, double duration)
          {           
              _rotationInProgress = true;
              // hide other page views because they may overlap the current page during animation
              for (int pageIndex = 0; pageIndex < this.numberOfPages(); pageIndex++) {
                  if(this.isPageLoaded( pageIndex ))
                      this.viewForPage( pageIndex ).Hidden = ( pageIndex != _currentPageIndex );
              }
          }
          public override void WillAnimateRotation (UIInterfaceOrientation toInterfaceOrientation, double duration)
          {
          // resize and reposition the page view, but use the current contentOffset as page origin
          // (note that the scrollview has already been resized by the time this method is called)
              SizeF pageSize = this.pageSize();
              UIView pageView = this.viewForPage( _currentPageIndex );
              this.viewForPage( _currentPageIndex ).Frame = new RectangleF( this._scView.ContentOffset.X, 0, pageSize.Width, pageSize.Height );           
          }
          public override void DidRotate (UIInterfaceOrientation fromInterfaceOrientation)
          {
              base.DidRotate (fromInterfaceOrientation);
      
              // adjust frames according to the new page size - this does not cause any visible changes
              this.layoutPages();
              this._scView.ContentOffset = new PointF( _currentPageIndex * this.pageSize().Width, 0 );
      
              //unhide
              for (int pageIndex = 0; pageIndex < this.numberOfPages(); pageIndex++) {
                  if( this.isPageLoaded( pageIndex ) )
                      this.viewForPage( pageIndex ).Hidden = false;
              }
      
              _rotationInProgress = false;
          }               
      
          public override void DidReceiveMemoryWarning ()
          {
              //SuperHandle = DidReceiveMemoryWarning();
              if(this._pageViews != null)
              {
                  // unload non-visible pages in case the memory is scarse
                  for (int pageIndex = 0; pageIndex < this.numberOfPages(); pageIndex++) {
                      if( pageIndex < _currentPageIndex - 1 || pageIndex > _currentPageIndex + 1 )
                          if( this.isPageLoaded(pageIndex) ){
                              UIView pageview = (UIView)this._pageViews[ pageIndex ];
                              this._pageViews[ pageIndex ] = null;
                              pageview.RemoveFromSuperview();
                          }
                  }
              }
          }
          public override void ViewDidUnload ()
          {
              this._pageViews = null;
              this._scView = null;
          }       
      }
      

    提交回复
    热议问题