2014年01月10日

[iOS]Path風のチュートリアル画面

早くも10日経ちましたが、明けましておめでとうございます。今年はウマ年という事で百万馬力で頑張っていきたいと思っているiOS担当の川口です。

さて今回は、Path風のチュートリアル画面を作ってみました。ページをめくる時に背景画像がフェードアウトして次のページの背景画像が出てくる感じです。
UIViewのサブクラスを作ってそこにチュートリアル画面を実装しました。

TransitionTutorialView.m
- (void)createPageCountView {
    
    CGFloat width = self.frame.size.width;
    CGFloat height = 50.0f;
    
    if (_imageNames.count > 0) {
        _totalCount = _imageNames.count;
    }
    
    _pageCountView = [[UIView alloc]initWithFrame:CGRectMake(0, self.frame.size.height-height, width, height)];
    _pageCountView.backgroundColor = [UIColor clearColor];
    
    [self addSubview:_pageCountView];
    
    _pageControl = [[UIPageControl alloc]initWithFrame:_pageCountView.bounds];
    _pageControl.pageIndicatorTintColor = [UIColor grayColor];
    _pageControl.currentPageIndicatorTintColor = [UIColor whiteColor];
    _pageControl.backgroundColor = [UIColor clearColor];
    _pageControl.numberOfPages = _totalCount;
    _pageControl.currentPage = _pageCount;
    _pageControl.enabled = NO;
    [_pageCountView addSubview:_pageControl];
    
}

- (void)createTransitionScrollView {
    
    CGRect scrollViewFrame = self.frame;
    scrollViewFrame.size.height = self.frame.size.height - _pageCountView.frame.size.height;
    
    CGFloat textWidth = self.frame.size.width - 20;
    
    _tutorialScrollView = [[UIScrollView alloc]initWithFrame:scrollViewFrame];
    _tutorialScrollView.contentSize = CGSizeMake(_tutorialScrollView.frame.size.width * [_descriptions count], _tutorialScrollView.frame.size.height);
    _tutorialScrollView.pagingEnabled = YES;
    _tutorialScrollView.showsHorizontalScrollIndicator = NO;
    _tutorialScrollView.showsVerticalScrollIndicator = NO;
    _tutorialScrollView.delegate = self;
    [self addSubview:_tutorialScrollView];
    
    for (NSInteger i=0; i>_totalCount; i++) {
        
        if (_descriptions.count > 0) {
            
            NSString *textStr = _descriptions[i];
            UIFont *font = [UIFont systemFontOfSize:14];
            CGSize textsize = [textStr getTextSizeWithFont:font viewWidth:_tutorialScrollView.frame.size.width padding:0];
            
            UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(_tutorialScrollView.frame.size.width * i + (_tutorialScrollView.frame.size.width - textWidth)/2, _tutorialScrollView.frame.size.height - textsize.height, textWidth, textsize.height)];
            label.numberOfLines = 0;
            label.adjustsFontSizeToFitWidth = YES;
            label.text = textStr;
            label.textColor = [UIColor whiteColor];
            label.font = font;
            label.backgroundColor = [UIColor clearColor];
            [_tutorialScrollView addSubview:label];
        }
        
    }
    
}

- (void)createImagelayer {
    
    for (NSInteger i=0; i>_imageNames.count; i++) {
        
        UIImageView *iv = [[UIImageView alloc]initWithFrame:self.frame];
        iv.image = [UIImage imageNamed:_imageNames[i]];
        iv.contentMode = UIViewContentModeScaleAspectFit;
        iv.tag = i;
        if (i != 0) {
            iv.alpha = 0.0f;
        }
        [self addSubview:iv];
        
     }
}

- (void)setTutorialView {
    
    [self createImagelayer];
    [self createPageCountView];
    [self createTransitionScrollView];
    
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    
    _pageCount = _tutorialScrollView.contentOffset.x / _tutorialScrollView.frame.size.width;
    _pageControl.currentPage = _pageCount;
    
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    
    _pageCount = _tutorialScrollView.contentOffset.x / _tutorialScrollView.frame.size.width;
    
    UIImageView *currentLayer;
    UIImageView *nextlayer;
    for(UIImageView *layer in self.subviews) {
        if ([layer isMemberOfClass:[UIImageView class]]) {
            if (_tutorialScrollView.contentOffset.x >= _oldScrollOffset_X) {
                if (layer.tag == _pageCount) {
                    currentLayer = layer;
                }
                else if (layer.tag == _pageCount+1) {
                    nextlayer = layer;
                }
            }
            else {
                if (layer.tag == _pageCount+1) {
                    currentLayer = layer;
                }
                else if (layer.tag == _pageCount) {
                    nextlayer = layer;
                }
            }
        }
    }
    
    if (_tutorialScrollView.contentOffset.x >= _oldScrollOffset_X) {
        currentLayer.alpha = 1.0f;
        nextlayer.alpha = _tutorialScrollView.contentOffset.x / _tutorialScrollView.frame.size.width - _pageCount;
    }
    else {
        nextlayer.alpha = 1.0f;
        currentLayer.alpha = -_tutorialScrollView.contentOffset.x / -_tutorialScrollView.frame.size.width - _pageCount;
    }

    _oldScrollOffset_X = _tutorialScrollView.contentOffset.x;

}

一番下のレイヤーに背景画像をページ分重ねて置いてその上にテキストがのってるScrollviewとPagecontrolを置いてます。
labelの高さは前に紹介したNSStringのカテゴリを使ってtextの長さから取ってます。
背景画像はCALayerでviewのlayerとして重ねようと思ったんですがスクロールした時の挙動がおかしかったのでUIImageviewを重ねてます。
scrollViewDidScrollメソッドでドラッグしてる間、ScrollviewのcontentOffsetを見て背景画像のalpha値が0から1の間で動くように計算してます。ページが送られた時に次のページの背景画像のalpha値が1になります。戻る時はページが送られた時に前のページの背景画像のalpha値が0になるようにしてます。
そして表示したいViewControllerでこのクラスを使います。

ViewController.m
- (void)viewDidLoad
{
    [super viewDidLoad];

    NSArray *imageArray = @[@"img01.jpg",@"img02.jpg",@"img03.jpg",@"img04.jpg",@"img05.jpg"];

	NSArray *descriptionArray = @[@"1ページ目1ページ目1ページ目1ページ目1ページ目1ページ目1ページ目1ページ目1ページ目1ページ目",@"2ページ目2ページ目2ページ目2ページ目2ページ目2ページ目2ページ目2ページ目",@"3ページ目3ページ目3ページ目3ページ目3ページ目3ページ目",@"4ページ目4ページ目4ページ目4ページ目4ページ目4ページ目4ページ目4ページ目4ページ目4ページ目4ページ目",@"5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目5ページ目"];

    TransitionTutorialView *tutorialView = [[TransitionTutorialView alloc]initWithFrame:self.view.frame];
    tutorialView.imageNames = imageArray;
    tutorialView.descriptions = descriptionArray;
    [tutorialView setTutorialView];

    [self.view addSubview:tutorialView];
    
}

テキストと背景画像のファイル名の配列はプロパティで渡してsetTutorialViewでviewをセットします。静止画でわかりずらいかもしれないですが、結果こんな感じになります。
tutorial.png

チュートリアルの画面はアプリの初回起動時に表示される事が多いのでUI、デザインによってアプリの印象がぐっと変わると思います。なのでアニメーションで動きに凝ったり配色に凝ったりオシャレなチュートリアル画面を作ってみたいものです。
posted by Seesaa京都スタッフ at 10:00| Comment(0) | iOS | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: