Несколько PageScrollViews (UIScrollViews) на экране одновременно (не вложенные) - PullRequest
1 голос
/ 08 июня 2009

Предупреждение: это мое первое приложение для iPhone, поэтому здесь происходит множество программ культового груза.

Я гуглил, искал переполнение стека, читал книги и менял код снова и снова, пытаясь это исправить, а я не могу. Я использую класс PageScrollView, который Джонатан Здзярски написал в «Разработка приложений для iPhone SDK». Это класс, который обеспечивает просмотр 5 (или более) изображений, загружая 3 в память одновременно. Я хочу, чтобы 3 из этих PageScrollViews на экране одновременно накладывались друг на друга. Верхний ряд из 5 изображений для горизонтальной прокрутки, средний ряд изображений для горизонтальной прокрутки и нижний ряд изображений для горизонтальной прокрутки, когда телефон находится в портретном положении, я полностью переключаю виды в альбомном режиме .

PageScrollView, как я модифицировал, все, что было закомментировано, в какой-то момент было прокомментировано в попытке сделать эту работу. Я пытался закомментировать как можно больше, чтобы выделить проблему:

    #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

Вот мой метод loadview из моего класса ViewController:

- (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) ];

Однако эти цифры мне не кажутся правильными. Я чувствую, что значения y должны быть 0,160 и 320 соответственно, потому что у меня есть 3 изображения, каждое из которых имеет высоту 160 пикселей и (3x160 = 480), но когда я устанавливаю значения y на 0,160 и 320, верхнее изображение находится вверху на экране среднее изображение находится там, где должно быть нижнее изображение, а нижнее изображение далеко от экрана. Но когда у меня установлены значения y, равные 0,80 и 160, изображения отображаются правильно, но области прокрутки работают (у меня есть ощущение, что области прокрутки или области касания, как бы они ни назывались, устанавливаются над изображениями).

У кого-нибудь есть идеи?

1 Ответ

1 голос
/ 08 июня 2009

Я думаю, что было бы намного проще, если бы вы не пытались создать макет вручную. Посмотрите на это:

Создайте свой 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, а не пытаться управлять вещами попиксельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...