2009-06-08 4 views
1

警告:これは私の最初のiPhoneアプリケーションであるため、ここではたくさんのカーゴカルトプログラミングが行われています。複数のPageScrollViews(UIScrollViews)が一度に画面に表示される(ネストされていない)

私はグーグル、スタックオーバーフローを検索し、書籍を読んで、これを修正しようとして何度も何度もコードを変更しましたが、できません。私はJonathan Zdziarskiの "iPhone SDK Application Development"にあるPageScrollViewクラスを使用しています。これは、5つの画像(またはそれ以上)のビューを提供し、一度に3つをメモリにロードするクラスです。これらのPageScrollViewsの3つを画面上に重ねて重ねることをお勧めします。水平方向にスクロールする画像の一番上の行、画像を横にスクロールするための中央の行、画像の一番下の行は、電話機がポートレートの位置に保持されている間に水平にスクロールするモードです。 。

私が変更したように、コメントアウトされたものは、この作業を行うために1つの点でコメントを外していました。ここで

#import "PageScrollView.h" 

@implementation PageScrollView 

-(id)initWithFrame:(CGRect)frame { 
    self = [ super initWithFrame: frame ]; 
    if (self != nil) { 
     _pages = nil; 
     _zeroPage = 0; 
     _pageRegion = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); 
     //_controlRegion = CGRectMake(frame.origin.x,frame.size.height/2, frame.size.width, 0); 

     self.delegate = nil; 

     scrollView = [ [ UIScrollView alloc ] initWithFrame: _pageRegion ]; 
     scrollView.pagingEnabled = YES; 
     scrollView.delegate = self; 
     [ scrollView setContentOffset: CGPointMake(frame.origin.x, frame.origin.y) ]; 
     [ scrollView setContentSize: CGSizeMake(_pageRegion.size.width,_pageRegion.size.height) ]; 
     [ scrollView setContentInset : UIEdgeInsetsMake(0.0,80.0,0,0) ]; 
     [ self addSubview: scrollView ]; 

     //pageControl = [ [ UIPageControl alloc ] initWithFrame: _controlRegion ]; 
     //[ pageControl addTarget: self action: @selector(pageControlDidChange:) forControlEvents: UIControlEventValueChanged ]; 
     //[ self addSubview: pageControl ]; 
    } 
    return self; 
} 

-(void)setPages:(NSMutableArray *)pages { 
    if (pages != nil) { 
     for(int i=0;i<[_pages count];i++) { 
      [ [ _pages objectAtIndex: i ] removeFromSuperview ]; 
     } 
    } 
    _pages = pages; 
    //scrollView.contentOffset = CGPointMake(0.0, 0.0); 
    scrollView.contentOffset = CGPointMake(0.0, _pageRegion.origin.y); 
    if ([ _pages count] < 3) { 
     scrollView.contentSize = CGSizeMake(_pageRegion.size.width * [ _pages count ], _pageRegion.size.height); 
    } else { 
     scrollView.contentSize = CGSizeMake(_pageRegion.size.width * 3, _pageRegion.size.height); 
     scrollView.showsHorizontalScrollIndicator = NO; 
    } 
    pageControl.numberOfPages = [ _pages count ]; 
    pageControl.currentPage = 0; 
    [ self layoutViews ]; 
} 

- (void)layoutViews { 
    if ([ _pages count ] <= 3) { 
     for(int i=0;i<[ _pages count];i++) { 
      UIView *page = [ _pages objectAtIndex: i ]; 
      //CGRect bounds = page.bounds; 
      //CGRect frame = CGRectMake(_pageRegion.size.width * i, 0.0, _pageRegion.size.width, _pageRegion.size.height); 
      //CGRect frame = CGRectMake(_pageRegion.size.width * i, _pageRegion.origin.y+_pageRegion.size.height , _pageRegion.size.width, _pageRegion.size.height); 
      //page.frame = frame; 
      //page.bounds = bounds; 
      [ scrollView addSubview: page ]; 
     } 
     return; 
    } 

    /* For more than 3 views, add them all hidden, layout according to page */ 
    for(int i=0;i<[ _pages count];i++) { 
     UIView *page = [ _pages objectAtIndex: i ]; 
     //CGRect bounds = page.bounds; 
     //CGRect frame = CGRectMake(0.0, 0.0, _pageRegion.size.width, _pageRegion.size.height); 
     //CGRect frame = CGRectMake(0.0, _pageRegion.origin.y+_pageRegion.size.height, _pageRegion.size.width, _pageRegion.size.height); 
     //page.frame = frame; 
     //page.bounds = bounds; 
     page.hidden = YES; 
     [ scrollView addSubview: page ]; 
    } 
    [ self layoutScroller ]; 
} 

- (void)layoutScroller { 
    UIView *page; 
    CGRect bounds, frame; 
    int pageNum = [ self getCurrentPage ]; 

    if ([ _pages count ] <= 3) 
     return; 

    NSLog(@"Laying out scroller for page %d\n", pageNum); 

    /* Left boundary */ 
    if (pageNum == 0) { 
     for(int i=0;i<3;i++) { 
      page = [ _pages objectAtIndex: i ]; 
      bounds = page.bounds; 
      //frame = CGRectMake(_pageRegion.size.width * i, 0.0, _pageRegion.size.width, _pageRegion.size.height); 
      frame = CGRectMake(_pageRegion.size.width * i, 0.0, _pageRegion.size.width, _pageRegion.size.height); 
      NSLog(@"\tOffset for Page %d = %f\n", i, frame.origin.x); 
      page.frame = frame; 
      page.bounds = bounds; 
      page.hidden = NO; 
     } 
     page = [ _pages objectAtIndex: 3 ]; 
     page.hidden = YES; 
     _zeroPage = 0; 
    } 

    /* Right boundary */ 
    else if (pageNum == [ _pages count ] -1) { 
     for(int i=pageNum-2;i<=pageNum;i++) { 
      page = [ _pages objectAtIndex: i ]; 
      bounds = page.bounds; 
      frame = CGRectMake(_pageRegion.size.width * (2-(pageNum-i)), 0.0, _pageRegion.size.width, _pageRegion.size.height); 
      NSLog(@"\tOffset for Page %d = %f\n", i, frame.origin.x); 
      page.frame = frame; 
      page.bounds = bounds; 
      page.hidden = NO; 
     } 
     page = [ _pages objectAtIndex: [ _pages count ]-3 ]; 
     page.hidden = YES; 
     _zeroPage = pageNum - 2; 
    } 

    /* All middle pages */ 
    else { 
     for(int i=pageNum-1; i<=pageNum+1; i++) { 
      page = [ _pages objectAtIndex: i ]; 
      bounds = page.bounds; 
      frame = CGRectMake(_pageRegion.size.width * (i-(pageNum-1)), 0.0, _pageRegion.size.width, _pageRegion.size.height); 
      NSLog(@"\tOffset for Page %d = %f\n", i, frame.origin.x); 
      page.frame = frame; 
      page.bounds = bounds; 
      page.hidden = NO; 
     } 
     for(int i=0; i< [ _pages count ]; i++) { 
      if (i < pageNum-1 || i > pageNum + 1) { 
       page = [ _pages objectAtIndex: i ]; 
       page.hidden = YES; 
      } 
     } 
     //scrollView.contentOffset = CGPointMake(_pageRegion.size.width, 0.0); 
     scrollView.contentOffset = CGPointMake(_pageRegion.size.width, 0.0); 
     _zeroPage = pageNum-1; 
    } 
} 

-(id)getDelegate { 
    return _delegate; 
} 

- (void)setDelegate:(id)delegate { 
    _delegate = delegate; 
} 

-(BOOL)getShowsPageControl { 
    return _showsPageControl; 
} 

-(void)setShowsPageControl:(BOOL)showsPageControl { 
    _showsPageControl = showsPageControl; 
    if (_showsPageControl == NO) { 
     //_pageRegion = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height); 
     pageControl.hidden = YES; 
     scrollView.frame = _pageRegion; 
    } else { 
     //_pageRegion = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height - 60.0); 
     //_pageRegion = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height); 
     pageControl.hidden = NO; 
     scrollView.frame = _pageRegion; 
    } 
} 

-(NSMutableArray *)getPages { 
    return _pages; 
} 

-(void)setCurrentPage:(int)page { 
// [ scrollView setContentOffset: CGPointMake(0.0, 0.0) ]; 
    [ scrollView setContentOffset: CGPointMake(0.0,_pageRegion.origin.y) ]; 
    _zeroPage = page; 
    [ self layoutScroller ]; 
    pageControl.currentPage = page; 
} 

-(int)getCurrentPage { 
    return (int) (scrollView.contentOffset.x/_pageRegion.size.width) + _zeroPage; 
} 

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    pageControl.currentPage = self.currentPage; 
    [ self layoutScroller ]; 
    [ self notifyPageChange ]; 
} 

-(void) pageControlDidChange: (id)sender 
{ 
    UIPageControl *control = (UIPageControl *) sender; 
    if (control == pageControl) { 
     //[ scrollView setContentOffset: CGPointMake(_pageRegion.size.width * (control.currentPage - _zeroPage), 0.0) animated: YES ]; 
     [ scrollView setContentOffset: CGPointMake(_pageRegion.size.width * (control.currentPage - _zeroPage), 0.0) animated: YES ]; 

    } 
} 

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { 
     [ self layoutScroller ]; 
     [ self notifyPageChange ]; 
} 

-(void) notifyPageChange { 
    if (self.delegate != nil) { 
//  if ([ _delegate conformsToProtocol:@protocol(PageScrollViewDelegate) ]) { 
      if ([ _delegate respondsToSelector:@selector(pageScrollViewDidChangeCurrentPage:currentPage:) ]) { 
       [ self.delegate pageScrollViewDidChangeCurrentPage: (PageScrollView *)self currentPage: self.currentPage ]; 
      } 
//  } 
    } 
} 

@end 

が私のViewControllerクラスから私のloadViewメソッドである:私は、問題を特定するために私ができる限り多くをコメントアウトしてみました

- (void)loadView { 
    [ super loadView ]; 

    /* Load demo images for pages */ 
    topPages = [ [ NSMutableArray alloc ] init ]; 
    for(int i = 0; i < 5; i++) { 
     UIImage *image = [ [ UIImage alloc ] initWithData: [ NSData dataWithContentsOfURL: [ NSURL URLWithString: [ NSString stringWithFormat: @"http://www.zdziarski.com/demo/%d.png", i+1 ] ] ] ]; 
     UIImageView *page = [ [ UIImageView alloc ] initWithFrame: CGRectMake(0,0,320,160) ] ; 
     page.image = image; 
     //page.bounds = CGRectMake(0.0, 0.0, 320, 160); 
     [ topPages addObject: page ];  
    } 

    CGRect viewBounds = [ [ UIScreen mainScreen ] applicationFrame ]; 
    viewBounds.origin.y = 0.0; 

    portraitTopView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,0,320,160) ]; 
    portraitTopView.pages = topPages; 
    portraitTopView.delegate = self; 
    //portraitTopView.showsPageControl = NO; 

    middlePages = [ [ NSMutableArray alloc ] init ]; 
    for(int i = 0; i < 5; i++) { 
     UIImage *image = [ [ UIImage alloc ] initWithData: [ NSData dataWithContentsOfURL: [ NSURL URLWithString: [ NSString stringWithFormat: @"http://www.zdziarski.com/demo/%d.png", i+1 ] ] ] ]; 
     UIImageView *page = [ [ UIImageView alloc ] initWithFrame: CGRectMake(0,0,320,160) ] ; 
     page.image = image; 
     //page.bounds = CGRectMake(0.0, 0.0, 320, 160); 
     [ middlePages addObject: page ]; 
    } 

    portraitMiddleView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,80,320,160) ]; 
    portraitMiddleView.pages = middlePages; 
    portraitMiddleView.delegate = self; 
    //portraitMiddleView.showsPageControl = NO; 

    bottomPages = [ [ NSMutableArray alloc ] init ]; 
    for(int i = 0; i < 5; i++) { 
     UIImage *image = [ [ UIImage alloc ] initWithData: [ NSData dataWithContentsOfURL: [ NSURL URLWithString: [ NSString stringWithFormat: @"http://www.zdziarski.com/demo/%d.png", i+1 ] ] ] ]; 
     UIImageView *page = [ [ UIImageView alloc ] initWithFrame: CGRectMake(0,0,320,160) ] ; 
     page.image = image; 
     //page.bounds = CGRectMake(0.0, 0.0, 320, 160); 
     [ bottomPages addObject: page ];   
    } 

    portraitBottomView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,160,320,160) ]; 
    portraitBottomView.pages = bottomPages; 
    portraitBottomView.delegate = self; 
    //portraitBottomView.showsPageControl = NO; 


    portraitView = [ [ UIView alloc ] initWithFrame: viewBounds ]; 
    [ portraitView addSubview: portraitTopView ]; 
    [ portraitView addSubview: portraitMiddleView ]; 
    [ portraitView addSubview: portraitBottomView ]; 

    landscapeTextView = [ [ UITextView alloc ] initWithFrame: viewBounds ]; 
    landscapeTextView.text = woahDizzy; 

    self.view = portraitView; 
} 

私の問題は、スクロール領域(の一部私が触れる画面)は画像と一致していないようです。画像を正しく表示するために取得するには、私が使用している:

portraitTopView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,0,320,160) ]; 
portraitMiddleView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,80,320,160) ]; 
portraitBottomView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,160,320,160) ]; 

をしかし、これらの数字は私に権利いないようです。私は、160ピクセルの高さと(3x160 = 480)の3つのイメージを持っているので、y値はそれぞれ0,160,320でなければならないと感じていますが、y値を0,160,320に設定すると、画面の中央の画像は、下の画像があるべき場所であり、下の画像は、画面から離れたところにあります。しかし、yの値を0,80、および160に設定すると、画像は正しく表示されますが、スクロール領域が機能します(スクロール領域やタッチ領域がイメージの上に設定されていると感じています)。

誰にもアイデアはありますか?

答えて

1

手作業でレイアウトを作っていないと、物事がもっと簡単になると思います。これを見ている:

あなたのUIScrollViewのを作成します(viewBaseはUIScrollViewののインスタンスである)

int imgWidth = 160; 
int numImages = 3; 
int scrollWidth = imgWidth * numImages; 

int imgHeight = 160; 
int numRows = 3; 
int scrollHeight = imgHeight * numRows; 

viewBase.contentSize = CGSizeMake(scrollWidth, scrollHeight); 
// Set anything else you need on viewbase 

あなたはUIScrollViewのにあなたの要素を追加するときに、同様の計算を行います。

// Add this View to the far left of the scroller. 
webViewOne = [[UIWebView alloc] initWithFrame: CGRectMake(viewBase.frame.origin.x, viewBase.frame.origin.y, viewBase.frame.size.width, viewBase.frame.size.height)]; 
[viewBase addSubview:webViewOne]; 
[webViewOne release]; 

// Add this View tot he right of webViewOne (Note the offset on the X coordinate) 
webViewTwo = [[UIWebView alloc] initWithFrame: CGRectMake((viewBase.frame.size.width * 1), viewBase.frame.origin.y, viewBase.frame.size.width, viewBase.frame.size.height)]; 
[viewBase addSubview:webViewTwo]; 
[webViewTwo release]; 

これにより、すべてのサイジングとレイアウトが、ピクセル単位で制御するのではなく、基礎となるUIScrollViewを基準にすることができます。

+0

これは、3つの独立したスクロールイメージの行を許可しますか?一番上の行のイメージ1、中行のイメージ3、一番下の行のイメージ2、または他の組み合わせを見ることができるようにしたい。また、私は何百もの画像を持っているので、PageScrollViewを使用しようとしていました。 –

+0

はい、UIScrollViewは単なる大きな「キャンバス」です。計算とピクセルを使用して項目を設定します。上記のコードは、デバイスの画面の幅の2倍のUIScrollViewを作成し、2つ目のViewのX軸にプロットをオフセットすることによって2つのUIWebViewを並べて設定します。あなたが作成している仮想の "グリッド"上のスポットを追跡できるようにする必要があるだけです。幅と高さなどの変数を作成した理由は...レイアウトを追跡するのが簡単です – MystikSpiral

+0

私はそれを得る。あなたは、3つの動くキャンバスを持つ私の1つの静的フレームの代わりに、3つの独立した水平に動くフレームを持つ1つの大きなキャンバスを提案していますか?私はこのアイデアが気に入っていますが、一度に何百枚もの画像をロードするというメモリ問題をどのように乗り越えているのか本当に分かりません。 –

関連する問題