ios开发——简单引导页的实现

每当第一次打开某个应用时,总会出现一个引导页,引导用户怎么使用这一程序。这个功能是非常实用的。当然根据要求不同,该功能可以做得非常简单直白或者炫酷好看。今天试着自己封装了一下这个功能。


一、目前实现的功能:

今天早上还雄心勃勃想写将这个功能得比较完善,不过由于课程略多(今天上日语默写五十音图跪了抓狂)、时间较少(主要还是懒- -|)等因素,目前只实现了部分功能。主要有以下几点:

1、只要用户提供三个数组(背景图片、图片、文字介绍)就能将该引导页展示出来。

2、提供四种动画选项显示该引导页,包括无动画、淡入、从下到上弹出,以及一个3d的混合动画。

3、用户可以随时Skip该引导页。

4、拖到最后一页继续拖的时候将导航页隐藏,展示正文

未实现或不完整的功能:

1、切换时动画,即用户用手拖动界面时的动画。目前只是生硬的改变每个引导页的透明度,效果欠佳。至于复杂的动画更是木有实现。。

2、错误处理、接口设置并不好,由于并未自习测试,可能会有bug,而且类封装得并不完美,例如:用户提供的三个数组必须有相同的count,否则无法正常显示该引导页。

留到以后再改改好了,但愿以后还能捡起来- -


二、效果图


放出渣渣效果,意思意思就好了,至少功能有了偷笑




三、思路与接口设计


引导页主要是通过ScrollView来实现的,将每个引导页封装成一个Item类,将每个Item依次放到该ScrollView上并设置scrollview的相关属性即可。而拖动过程中的一系列操作,例如动画等则是通过scrollView的协议方法来实现的。


先来看看IntroductionItem

@class IntroductionItem;

@protocol IntrodectionItemDelegate <NSObject>

- (void)skipButtonTappedInItem:(IntroductionItem *)item;

@end

@interface IntroductionItem : UIView

@property (weak, nonatomic) id<IntrodectionItemDelegate> delegate;

@property (strong, nonatomic) UIImage *bgImage;
@property (strong, nonatomic) UIImage *mainImage;
@property (strong, nonatomic) NSString *textToShow;

@property (strong, nonatomic) UIImageView *bgImageView;
@property (strong, nonatomic) UIImageView *mainImageView;
@property (strong, nonatomic) UILabel *textLabel;

- (id)initWithBGImage:(UIImage *)aBGImage mainImage:(UIImage *)aMianImage contentText:(NSString *)aText;

既然要封装,就要将留给用户的信息,也就是用户可以设置的信息暴露出来。这里其实下面三个View并非直接面向用户的,而是面向接下来的IntroductionView的。用户提供的是上面三个,即背景图片、介绍用图片以及介绍用文字。同时为了在每个Item下发加上SKIP按钮来跳过引导页,为其定义协议,准备让其委托来实现。

接着是IntroductionView类,也是最主要的类

typedef enum : NSUInteger {
    CYZAnimationTypeNone,
    CYZAnimationType3D,
    CYZAnimationTypeDownToUp,
    CYZAnimationTypeOpaque
} CYZAnimationType;

@interface IntroductionView : UIView

@property (strong, nonatomic) NSArray *allBGImages;
@property (strong, nonatomic) NSArray *allMainImages;
@property (strong, nonatomic) NSArray *allTitles;

- (id)initWithFrame:(CGRect)frame
   allBGImagesArray:(NSArray *)bgImages
  allMainImageArray:(NSArray *)mainImages
      allTitleArray:(NSArray *)titles;

- (void)showIntroductionItemsWithAnimationType:(CYZAnimationType)animationType;
- (void)setIntroductionAlpha:(CGFloat)alpha;
- (void)hideIntroductionView;

这里主要有三个public方法,一个是展示该引导页,参数为展示的动画类型,对应的一个为隐藏该引导页。另外,还有一个设置透明度的方法,单拿出来的目的是能保证在动画中不会改变用户设置的透明度,其实这是设计问题,待改进。


四、关键代码


其实这两个类的实现都比较容易,Item类只需要将三个View初始化并设置好相关属性即可。View类里主要说下展示动画的方法

- (void)showIntroductionItemsWithAnimationType:(CYZAnimationType)animationType
{
    if (animationType == CYZAnimationTypeNone) {
        self.alpha = _settingAlpha;
    } else if (animationType == CYZAnimationTypeDownToUp) {
        self.layer.transform = CATransform3DMakeTranslation(0, self.frame.size.height, 1.0);
        [UIView animateWithDuration:kAnimationDuration1x animations:^{
            self.alpha = _settingAlpha;
            self.layer.transform = CATransform3DIdentity;
        }];
    } else if (animationType == CYZAnimationTypeOpaque) {
        [UIView animateWithDuration:kAnimationDuration1x animations:^{
            self.alpha = _settingAlpha;
        }];
    } else {
        CATransform3D transform = self.layer.transform;
        transform.m34 = 2.0 / 500.0;
        //self.layer.transform = CATransform3DMakeTranslation(-self.frame.size.width, 0, 1.0f);
        self.center = CGPointMake(0, self.frame.size.height / 2);
        
        [UIView animateWithDuration:kAnimationDuration3x animations:^{
            
            self.center = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2);
            self.alpha = _settingAlpha;
            self.layer.transform = CATransform3DMakeScale(0.7f, 0.7f, 1.0f);
            self.layer.transform = CATransform3DRotate(self.layer.transform, M_PI / 4, 1.0f, 0.0f, 0.0f);
            //self.layer.transform = CATransform3DMakeTranslation(0, 0, 1.0f);
            
        } completion:^(BOOL finished) {
            if (finished) {
                [UIView animateWithDuration:kAnimationDuration3x animations:^{
                    self.layer.transform = CATransform3DIdentity;
                }];
            }
        }];
    }
}

在最后一个case,也就是3d动画中,我们先取得layer的transform属性,设置其m34为一合理值即可在接下来的变换中产生一定的3d效果(刚看别人代码学得,至于为什么,同求解= =)。然后对其进行变换(移动、缩放、旋转)即可。最后不要忘记在完成的时候在让其恢复成Identity。

隐藏引导页则只需将该View的透明度设为0并从父视图中移除,这里添加了动画效果,即让其在消失的同时适度放大。

- (void)hideIntroductionView
{
    [UIView animateWithDuration:kAnimationDuration2x animations:^{
        self.layer.transform = CATransform3DMakeScale(1.2f, 1.2f, 1.0f);
        self.alpha = 0.0f;
    } completion:^(BOOL finished) {
        [self removeFromSuperview];
    }];
}

对于那个生硬的Item间透明度变换效果就是在scrollView的协议方法 scrollViewDidScroll:中根据contentOffset来实现的,我相信那些好看的效果也是通过这个思路来实现的(虽然我没能成功)

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (_hasFinished) {
        return;
    }
    
    //当引导页处于第一页时,阻止用户右划
    if (scrollView.contentOffset.x < 0) {
        scrollView.scrollEnabled = NO;
    } else {
        scrollView.scrollEnabled = YES;
    }
    
    NSInteger allPages = self.allTitles.count;
    
    NSInteger i_newPage = (NSInteger)scrollView.contentOffset.x / scrollView.frame.size.width;
    CGFloat f_newPage = scrollView.contentOffset.x / scrollView.frame.size.width;
    CGFloat settingAlpha = f_newPage - i_newPage;
    
    if (f_newPage > allPages - 1) {
        [self hideIntroductionView];
        _hasFinished = YES;
        return;
    }
    
    IntroductionItem *currentItem = (IntroductionItem *)[self.itemArray objectAtIndex:_currentPage];
    IntroductionItem *newItem;

    if (_currentPage > i_newPage) {                 //往右划,展示上一个界面
        newItem = (IntroductionItem *)[self.itemArray objectAtIndex:i_newPage];
        currentItem.alpha = settingAlpha;
        newItem.alpha = 1.0 - settingAlpha;
        
    } else if (_currentPage == i_newPage) {         //往左划,展示下一个界面
        newItem = (IntroductionItem *)[self.itemArray objectAtIndex:i_newPage + 1];
        newItem.alpha = settingAlpha;
        currentItem.alpha = 1.0 - settingAlpha;
    }
    
}

这样就能简单地实现一个引导功能了,在上面添加上合适的图片也能产生很好看的画面的。更好的实现可以搜索源码学习一下,通过这个简单的效果可以熟悉scrollview和animation相关知识。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值