UICollectionView 做的App首次启动引导页

376 阅读3分钟

迁移自简书

背景:项目已经迭代了了两个版本,在下一个版本中要加入引导页的功能

引导图的显示放在什么地方比较好

  1. 放在 appDelegate 中创建 tabBer 的方法中进行判断,如果为第一启动就跳到引导页 GuideViewController ,但是个人不太喜欢在 appDelegate 中做过多的操作因此放弃
    appDelegate.png
  2. 放在 TabBarController-viewDidLoad 方法中,判断为第一次启动后,显示 GuideViewController

GuideViewController 如何展示更加优雅

纯属个人愚见 个人十分推崇使用 UIWindow 来展示 GuideViewController 代码如下

- (void)showGuideView {
    if (!self.guideWindow) {
        self.guideWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        GuideCollectionViewController *guideVC = [[GuideCollectionViewController alloc] initWithNibName:@"GuideCollectionViewController" bundle:[NSBundle mainBundle]];
        guideVC.imageArray = @[[UIImage imageNamed:@"p1"],[UIImage imageNamed:@"p2"],[UIImage imageNamed:@"p3"],[UIImage imageNamed:@"p4"],[UIImage imageNamed:@"p5"]];
        __weak typeof(self)weakSelf = self;
        guideVC.dismissAction = ^{
        	//这里展示完成后 的操作,如 1.更改本地保存的数据为非第一次启动 2.继续走以前没有引导页时的逻辑 等 
            [weakSelf finishShowGuideView];
        };
        [self.guideWindow setRootViewController:guideVC];
    }
    [self.guideWindow makeKeyAndVisible];
}

- (void)finishShowGuideView {
    [UIView animateWithDuration:0.5 animations:^{
        self.guideWindow.alpha = 0.0;
    } completion:^(BOOL finished) {
        self.guideWindow.hidden = YES;
        //必须置为 `nil`
        self.guideWindow.rootViewController = nil;
        //非必须操作 但是实际上这个`window`只是用一次因此释放掉最好
        self.guideWindow = nil;
    }];
    //更改保存数据为非第一次启动 具体代码略

    //走原本没有引导页时的逻辑,和判断为非第一启动同样的操作 代码略

}

备注:iOS 7.0之后必须引用UIWindow对象后,UIWindow对象调用-makeKeyAndVisible方法才能使 window正常显示


上面的废话终于说完了,来讨论下使用UICollectionView来做引导页时的坑 😱

先上第一个版本的 GuideViewController的展示效果

第一版本的 GuideView.gif

怎么没有PageControl?🤔 ,这也是一个坑,我用的是UICollectionViewController并且是xib文件创建视图结果悲剧了,UICollectionViewController默认view就是UiCollectionView不能通过直接拖拽加约束的方式添加UIPageControl因此后面我改用了UIViewController上布局UICollectionView的做法

背景不是我们项目的启动图,好吧加上背景为启动图的代码

static NSString * const reuseIdentifier = @"GuideCollectionViewCellID";

- (void)viewDidLoad {
    [super viewDidLoad];
    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = NO;
    [self.collectionView registerNib:[UINib nibWithNibName:@"GuideCollectionViewCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:reuseIdentifier];
    [self showLaunchImageView];
}

- (void)showLaunchImageView {
    UIImage *lanuchImage = nil;
    if (iphone5x_4_0) {
        lanuchImage = [UIImage imageNamed:@"LaunchImage-700-568h"];
    }else if (iphone6_4_7) {
        lanuchImage = [UIImage imageNamed:@"LaunchImage-800-667h"];
    }else if (iphone6Plus_5_5) {
        lanuchImage = [UIImage imageNamed:@"LaunchImage-800-Portrait-736h"];
    }else {
        lanuchImage = [UIImage imageNamed:@"LaunchImage-700"];
    }
    UIImageView *lanuchImageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
   // lanuchImageView.image = lanuchImage;
    lanuchImageView.image = [UIImage imageNamed:@"bg"];
    [self.collectionView setBackgroundView:lanuchImageView];
}

来让我们再来看一下,运行的效果

带背景视图并有BUG的版本.gif

😦😵😫😖😱

是不是完全蒙了,别怕赶紧点进- setBackgroundView:看看官方的说明

@property (nonatomic, strong, nullable) UIView *backgroundView; // will be automatically resized to track the size of the collection view and placed behind all cells and supplementary views.

然而,😳似乎也看不出什么!🙃好吧,还好我们还有一招(以前的文章中说过的),看图说话时间到

步骤1

调试1.png

步骤2

调试2.png

步骤3

调试3.png

ok~🙂找到 BUG 产生的原因,由于对 cell 做了 CATransform3D 变换,因此造成的 cellbackgroundView 分割造成的,现在解决它

- (void)showLaunchImageView {
    UIImage *lanuchImage = nil;
    if (iphone5x_4_0) {
        lanuchImage = [UIImage imageNamed:@"LaunchImage-700-568h"];
    }else if (iphone6_4_7) {
        lanuchImage = [UIImage imageNamed:@"LaunchImage-800-667h"];
    }else if (iphone6Plus_5_5) {
        lanuchImage = [UIImage imageNamed:@"LaunchImage-800-Portrait-736h"];
    }else {
        lanuchImage = [UIImage imageNamed:@"LaunchImage-700"];
    }
    UIImageView *lanuchImageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
   // lanuchImageView.image = lanuchImage;
    CATransform3D t = CATransform3DIdentity;
    //注意`z`值可以根据你对`cell`做`3D`变化的偏转角度和`cell`的`size`来计算出来的,也可以给一个(绝对值)足够大的值,这个 demo 中给 '-212' 是最合适的
    t = CATransform3DTranslate(t, 0, 0, -150);
    lanuchImageView.layer.transform = t;
    lanuchImageView.image = [UIImage imageNamed:@"bg"];
    [self.collectionView setBackgroundView:lanuchImageView];
}

来再看一下效果

正常版本.gif

最后改UICollectionViewController为用UIViewcontroller布局UICollectionView来实现就可以添加UIPagecontrol

参考

iOS-Core-Animation-Advanced-Techniques -- 关于 CATransform3D请详细阅读 iOS-Core-Animation-Advanced-Techniques/5-变换/变换.md