当前位置: 移动技术网 > IT编程>移动开发>IOS > iOS日历控件

iOS日历控件

2019年03月29日  | 移动技术网IT编程  | 我要评论

带我飞 丁磊,黑夜追风,七音阁

项目需要,前一阵子重构了下ipad工程,添加了一个滚动无缝日历。

当时没有头绪,网上找了一个源码改吧改吧就上线了(参考链接),这个功能很多而且流畅性也特别好,推荐不会写的可以参考下。

这几天,活不太忙就把日历控件裁剪了下,做个最简单的滚动无缝日历。效果如下图:

 

日历可以左右滚动,点击某个日期后会变色,并且有回调。橘色的是标记日期,蓝色的是选择日期,蓝边的是当前日期,可以根据需要自行更改。

 

这个日历控件有两个比较复杂的地方:

  • uicollectionview默认情况下,横滚cell竖排竖滚cell横排,所以我们先要修改下cell的位置,自定义flowlayout继承于uicollectionviewflowlayout,重写它的preparelayout方法。
    #import "excalendarcollectionviewflowlayout.h"
    
    @interface excalendarcollectionviewflowlayout ()
    
    @property (nonatomic, strong) nsmutablearray *allattributes;
    
    @end
    
    
    @implementation excalendarcollectionviewflowlayout
    
    - (void)preparelayout {
        [super preparelayout];
        
        self.allattributes = [nsmutablearray array];
        
        nsinteger sections = [self.collectionview numberofsections];
        for (int i = 0; i < sections; i++) {
            
            // setup one section attributes.
            nsmutablearray *tmparray = [nsmutablearray array];
            
            nsinteger count = [self.collectionview numberofitemsinsection:i];
            
            for (nsinteger j = 0; j < count; j++) {
                nsindexpath *indexpath = [nsindexpath indexpathforitem:j insection:i];
                uicollectionviewlayoutattributes *attributes = [self layoutattributesforitematindexpath:indexpath];
                [tmparray addobject:attributes];
            }
            
            [self.allattributes addobject:tmparray];
        }
    }
    
    
    - (cgsize)collectionviewcontentsize {
        return [super collectionviewcontentsize];
    }
    
    
    - (uicollectionviewlayoutattributes *)layoutattributesforitematindexpath:(nsindexpath *)indexpath {
        nsinteger item = indexpath.item;
        nsinteger x;
        nsinteger y;
        
        // 根据item的序号计算出item的行列位置
        [self targetpositionwithitem:item resultx:&x resulty:&y];
        
        // 根据已得出的item的行列位置,将item放入indexpath中对应的位置。
        nsinteger item2 =  [self orignitematx:x y:y];
        nsindexpath *thenewindexpath = [nsindexpath indexpathforitem:item2 insection:indexpath.section];
        
        uicollectionviewlayoutattributes *thenewattr = [super layoutattributesforitematindexpath:thenewindexpath];
        thenewattr.indexpath = indexpath;
        return thenewattr;
    }
    
    
    - (nsarray<uicollectionviewlayoutattributes *> *)layoutattributesforelementsinrect:(cgrect)rect {
        nsarray *attributes = [super layoutattributesforelementsinrect:rect];
        
        nsmutablearray *tmp = [nsmutablearray array];
        
        for (uicollectionviewlayoutattributes *attr in attributes) {
            for (nsmutablearray *attributes in self.allattributes)
            {
                for (uicollectionviewlayoutattributes *attr2 in attributes) {
                    if (attr.indexpath.item == attr2.indexpath.item) {
                        [tmp addobject:attr2];
                        break;
                    }
                }
                
            }
        }
        return tmp;
    }
    
    
    // 根据item计算目标item的位置。
    - (void)targetpositionwithitem:(nsinteger)item
                           resultx:(nsinteger *)x
                           resulty:(nsinteger *)y {
        //    nsinteger page = item / (self.itemcountperrow * self.rowcountperpage);
        
        nsinteger thex = item % self.itemcountperrow;
        nsinteger they = item / self.itemcountperrow;
        
        if (x != null) {
            *x = thex;
        }
        
        if (y != null) {
            *y = they;
        }
    }
    
    
    - (nsinteger)orignitematx:(nsinteger)x
                            y:(nsinteger)y {
        nsinteger item = x * self.rowcountperpage + y;
        return item;
    }
    
    
    @end
    view code

     


  • 当你在当前月份点击了一个日期,滑到其他月份,然后要对刚才选择的月份的效果进行更改时,比较麻烦。刚开始我在didselectitematindexpath委托方法中用cellforitematindexpath进行获取时,不可见的cell获取不到返回的是空,然后在如何获取不可见的cell问题上纠结了两天,最终换了个解决方案,在cellforitematindexpath中进行了判断,解决了这个问题,当然点击后直接有响应跳转的话,刚才这个功能就很鸡肋了。具体看代码吧。

 

源码地址:https://github.com/zhanghua0926/excalendar

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

  • ios uicollectionview实现横向滚动

    现在使用卡片效果的app很多,之前公司让实现一种卡片效果,就写了一篇关于实现卡片的文章。文章最后附有demo实现上我选择了使用uicollectionview ... [阅读全文]
  • iOS UICollectionView实现横向滑动

    本文实例为大家分享了ios uicollectionview实现横向滑动的具体代码,供大家参考,具体内容如下uicollectionview的横向滚动,目前我使... [阅读全文]
  • iOS13适配深色模式(Dark Mode)的实现

    iOS13适配深色模式(Dark Mode)的实现

    好像大概也许是一年前, mac os系统发布了深色模式外观, 看着挺刺激, 时至今日用着也还挺爽的终于, 随着iphone11等新手机的发售, ios 13系统... [阅读全文]
  • ios 使用xcode11 新建项目工程的步骤详解

    ios 使用xcode11 新建项目工程的步骤详解

    xcode11新建项目工程,新增了scenedelegate这个类,转而将原appdelegate负责的对ui生命周期的处理担子接了过来。故此可以理解为:ios... [阅读全文]
  • iOS实现转盘效果

    本文实例为大家分享了ios实现转盘效果的具体代码,供大家参考,具体内容如下demo下载地址: ios转盘效果功能:实现了常用的ios转盘效果,轮盘抽奖效果的实现... [阅读全文]
  • iOS开发实现转盘功能

    本文实例为大家分享了ios实现转盘功能的具体代码,供大家参考,具体内容如下今天给同学们讲解一下一个转盘选号的功能,直接上代码直接看viewcontroller#... [阅读全文]
  • iOS实现轮盘动态效果

    本文实例为大家分享了ios实现轮盘动态效果的具体代码,供大家参考,具体内容如下一个常用的绘图,主要用来打分之类的动画,效果如下。主要是ios的绘图和动画,本来想... [阅读全文]
  • iOS实现九宫格连线手势解锁

    本文实例为大家分享了ios实现九宫格连线手势解锁的具体代码,供大家参考,具体内容如下demo下载地址:效果图:核心代码://// clockview.m// 手... [阅读全文]
  • iOS实现卡片堆叠效果

    本文实例为大家分享了ios实现卡片堆叠效果的具体代码,供大家参考,具体内容如下如图,这就是最终效果。去年安卓5.0发布的时候,当我看到安卓全新的material... [阅读全文]
  • iOS利用余弦函数实现卡片浏览工具

    iOS利用余弦函数实现卡片浏览工具

    本文实例为大家分享了ios利用余弦函数实现卡片浏览工具的具体代码,供大家参考,具体内容如下一、实现效果通过拖拽屏幕实现卡片移动,左右两侧的卡片随着拖动变小,中间... [阅读全文]
验证码:
移动技术网