UICollectionViewController的基本属性和功能实现

  • 在项目的作用:引导页的使用
  • 怎么来插入引导页
    • 当第一次进入程序时,为了给用户一个良好的体验,所以需要进行介绍,让用户更好的了解程序的功能。
    • 如果是用户第二次后者说是以后再次点开程序时,则不需要再进行介绍,直接跳转到主程序即可。
    • 还有,当程序版本进行更新的时候,启动程序的时候,再次进入引导页,当然此时的引导页应该显示新的内容。
    • 所以,进行构想。 记录版本号,当前版本号与旧版本号进行比较,如果相同则直接进入程序,如果不一样则进入引导页。
    • 代码实现如下
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // 1.创建窗口
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];


    // 判断下当前有没有最新的版本

    // 最新的版本保存到info.plist文件
    NSString *curVersion = [NSBundle mainBundle].infoDictionary[@"CFBundleShortVersionString"];

    // 获取上一次保存的最新版本号
    NSString *lastVersion = [[NSUserDefaults standardUserDefaults] objectForKey:@"vision"];
    NSLog(@"%@",[NSUserDefaults standardUserDefaults]);


    UIViewController *rootVc;

    if ([curVersion isEqualToString:lastVersion]) { // 相等
        // 没新版本,进入主框架界面
        // 创建tabBarVc
        rootVc  = [[LXLTabBarController alloc] init];



    }else{ // 表示有最新的版本号,进入新特性界面

        // 如果有,进入新特性界面
        rootVc = [[UIViewController alloc] init];
        rootVc.view.backgroundColor = [UIColor greenColor];

        // 保存当前的最新的版本号
        [[NSUserDefaults standardUserDefaults] setObject:curVersion forKey:@"vision"];


    }

    // 2.设置窗口的根控制器
    self.window.rootViewController = rootVc;


    // 3.让窗口显示
    [self.window makeKeyAndVisible];


    return YES;
}

  • 关于新特性界面的选择
    • 新特性界面是有几张图片组成的
    • 如果有多张的话,节约内存,希望能进行循环使用最好。
  • 实现方案
    • 在UIViewController上加入UIScrollView,并让UIScrollView的尺寸同屏幕尺寸一样大小,在其上面加载图片,并加入分页功能。
    • 可以加入UITableViewController它内部是UITableView,因为它的cell是可以显示图片,也能显示内容。所以设想,如果能把其横过来放置,然后cell的尺寸为屏幕尺寸的话,这样的话,也是可以显示的。并且对于UITableViewController的cell是能循环利用的,这样的话,也就节约了内容。使用效果很好。
    • 学习一个新的控制器UICollectionViewController 内部是 UICollectionView,个人觉得它是有scrollview的分页功能,又可以在里面放尺寸随意的控件。
    • 对于特定控制器,它的内部的view则为它的特定view,不要调用self.view需要调用它的特定的view,因为有时候两个view真的不一样。 需要注意,(真的不好理解,后面有一点代码进行说明)。
  • 循环思想的说明
    • 缓存池思想,出现新的控件或者说要显示新的内容,不直接进行创建,应该现从缓存池中读取,如果缓存池中没有则进行创建。
    • 所以根据上面的思想,要进行无限循环的话,只需要两个页面就可以了,内容尺寸为3个页面的宽度,并且中间位置始终指示当前图片。 怎么说呢,无论进行左移还是右移,如果出现要出现新的图片,则把缓存池中的页面取出来放在要移的方向上,如果图片全部移至到新的页面的话,则就页面放入缓存池,并且把新页面和移动的位置到再次放置到中心。
Snip20150726_19.png
Snip20150726_21.png
Snip20150726_22.png
  • 对于新控件UICollectionView的学习

    • 必须要先进行布局的设置。
    • 在布局设置中可以进行,其cell(它和tableView和相似)的尺寸,边距,以及组距等设置。还可以对其滚动方向进行设
    • 为了方便管理,再次创建自定义控制器进行管理
    • 代码实现
  • 对与初始化,因为要设置布局,那么就将布局设置在其初始化方法的内部,并且调用- init方法时,同时调用- initWithCollectionViewLayout:方法,来设置布局

- (instancetype)init
{
    // 创建一个流水布局
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];

    // 设置cell的尺寸
    layout.itemSize = [UIScreen mainScreen].bounds.size;

    // 设置滚动的方向
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;

    // 行间距
    layout.minimumLineSpacing = 0;

    // 设置cell之间的间距
    layout.minimumInteritemSpacing = 0;
//
//    // 组间距
//    layout.sectionInset = UIEdgeInsetsMake(100, 20, 0, 30);

    return [super initWithCollectionViewLayout:layout];
}


  • 和tableView相似的是:collection的cell也需要注册,但是只能注册,因为它创建的时候没有方法绑定标识。所以需要注册才能完成重用。注册在- viewDidLoad方法中实现
- (void)viewDidLoad {

    [super viewDidLoad];

    // 初始化
    [self setUp];

    // 在UICollectionViewController中self.view != self.collectionView
    // [self.view registerClass:[XMGNewFeatureCell class] forCellWithReuseIdentifier:ID];

    // 注册cell
    [self.collectionView registerClass:[XMGNewFeatureCell class] forCellWithReuseIdentifier:ID];

    // 搭建布局
    [self setUpChildViewLayout];
}

  • 对于初始化其特性的设置(建议另起方法为之,为了封装)(继承于scrollView )
    • 是否有弹簧作用
    • 是否展示水平或者垂直标识符
    • 是否具有分页功能
    • 代理等
    • 代码如下
- (void)setUp
{
    self.collectionView.bounces = NO;

    self.collectionView.showsHorizontalScrollIndicator = NO;

    self.collectionView.pagingEnabled = YES;

    self.collectionView.delegate = self;
}

  • 对于其子控件的设置,cell展示的内容等等
    • 类似于tableView的做法,自定义cell ,定义模型等等,但是观察实现的功能,发现cell中只需要有一个图片即可。所以模型属性就是一张图片。
    • 自定义cell,用来接受图片,并将图片添加到它的contentView种。
    • cell内部不能直接添加view,只能通过contentView添加 ,提供接口用来接受图片
    • 有图片来才进行赋值,所以用懒加载。
    • 代码如下
- (void)setImage:(UIImage *)image
{
    _image = image;

    self.imageView.image = image;
}

- (UIImageView *)imageView
{
    if (_imageView == nil) {
        UIImageView *imageV = [[UIImageView alloc] initWithFrame:self.bounds];

        [self.contentView addSubview:imageV];

        _imageView = imageV;
    }
    return _imageView;
}

  • 所以对于其数据源方法实现如下
// Items对应cell
// Items在某种程度上就是模型
// 返回有多少个cell

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 20;
}

// 返回每一个cell长什么样
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{

    // 从缓存池里取
    // UICollectionViewCell 没有UIImageView
    LXLCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];

    // 取出每行的item,对应的背景名
    NSString *imageName = [NSString stringWithFormat:@"guide%ldBackground",indexPath.item + 1];
    // cell赋值
    cell.image = [UIImage imageNamed:imageName];



    return cell;
}
  • 根据实现的效果图,来思考
    • 出现的动画视图,并非是加载到cell上,如果加载到cell上则不会跳来跳去。
    • 认为其加载的地方应该是在collectionView的最顶层
// 添加子控件
- (void)setUpChildViewLayout
{
    // guide
    UIImageView *guide = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"guide1"]];
    _guide = guide;
    guide.x += 50;
    [self.collectionView addSubview:guide];


    // largerText
    UIImageView *largerText = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"guideLargeText1"]];
    largerText.center = CGPointMake(self.view.width * 0.5, self.view.height * 0.7);
    [self.collectionView addSubview:largerText];

    // smallText
    UIImageView *smallText = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"guideSmallText1"]];
    smallText.center = CGPointMake(self.view.width * 0.5, self.view.height * 0.8);
    [self.collectionView addSubview:smallText];

    // guideLine
    UIImageView *guideLine = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"guideLine"]];
    guideLine.x -= 150;
    [self.collectionView addSubview:guideLine];
}

  • 我们的实现效果中,有一个是滑动结束后,从滑动的反方向推出视图的效果。
    • 思考
    • 什么时候推出
      • 滑动结束后推出(说明需要调用滑动代理方法减速完成)
    • 怎么才能从滑动反方向推出。
      • 可以先将图片移到位置上,然后再推出来。所以滑动是有距离的(当前偏移量和上一次偏移量的差值),滑动了一个页面,图片若偏移两个界面,然后再推回一个界面就应该能够完成这么一个效果了。
    • 需要展示哪张图片呢
      • 对于图片的选择,可以根据滑动偏移量,偏移一个界面,就展示第一个界面的,偏移两个界面,就展示第二个界面的。
    • 如何得到上一次的偏移量
      • 这一次的偏移量 ,就是下一次的上一次的偏移量。

// 减速完成的时候调用
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

    // 移动子控件的位置,并且做动画
    NSLog(@"%f",scrollView.contentOffset.x);

    // 获取scrollView滚动的X
    CGFloat offsetX = scrollView.contentOffset.x;

    // 计算偏移量的差值
    CGFloat delta = offsetX - _lastOffsetX;

    // 平移子控件
    _guide.x += 2 * delta;

    [UIView animateWithDuration:0.25 animations:^{
        _guide.x -= delta;
    }];
    // 计算页数
    int page = offsetX / scrollView.width + 1;
    // 切换子控件的显示
    NSString *imageName = [NSString stringWithFormat:@"guide%d",page];
    _guide.image = [UIImage imageNamed:imageName];


    _lastOffsetX = offsetX;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,271评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,725评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,252评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,634评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,549评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,985评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,471评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,128评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,257评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,233评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,235评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,940评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,528评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,623评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,858评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,245评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,790评论 2 339

推荐阅读更多精彩内容