iOS日历控件

释放双眼,带上耳机,听听看~!

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

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

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

iOS日历控件

 

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

 

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

  • UICollectionView默认情况下,横滚cell竖排竖滚cell横排,所以我们先要修改下cell的位置,自定义FlowLayout继承于UICollectionViewFlowLayout,重写它的prepareLayout方法。 iOS日历控件 iOS日历控件
    #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

 

给TA打赏
共{{data.count}}人
人已打赏
随笔日记

Linux - 挂载磁盘 + 通过LVM动态实现磁盘的动态扩容

2020-11-9 4:04:04

随笔日记

新手向:从不同的角度来详细分析Redis

2020-11-9 4:04:06

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索