之前写的一些东西都是自己放在QQ日志里,只是为了防止自己忘记,现在还是慢慢转移到CSDN来的方便,请大家多指教。
拿到一个UI界面,第一步就是对其进行分解,对于一个日历这个界面,我们可以想到的应该是:
1、这个是一个滚动视图;
2、滚动视图上面包含的是多个月视图;
3、月视图上面好办的事天视图及其他附属视图如分割线、月份标题。
在分解完UI后,我们应该就是对功能得到分配,功能分配的原则一般是面向对象的思想,自己的事情自己做,自己很难做的找代理或其他第三方做!
因此,我们得出一个初步框架:
1、滚动视图:FlowCalendarView,负责实现无限滚动,加载所需月份视图;
2、月份视图:MonthView,负责根据日期生成对应的天视图,并布局天视图及附属视图;
3、日视图:DayView,负责生成对应的点击事件、ui显示等;
对于上面这个框架,主要技术点应该在于:
1、如何实现无限循环;
2、如何根据日期布局日视图。
接下来我们就重点放在技术点上:
一、如何实现无限滚动:
我们知道ScrollView每滚动一点,就会调用layoutSubviews方法,那我们就可以在这个方法里,判断并调整自己的偏移量,这个判断条件是什么呢?我们可以认为,至少底部有一个本身视图高度以上的空间,顶部有0个视图空间,也就是说,contentSize应该至少为自身视图空间的两倍,才能实现无限滚动,这里我们可以取值充裕一点,设置为3倍以上,且判断条件可以为:
1、这个是一个滚动视图;
2、滚动视图上面包含的是多个月视图;
3、月视图上面好办的事天视图及其他附属视图如分割线、月份标题。
在分解完UI后,我们应该就是对功能得到分配,功能分配的原则一般是面向对象的思想,自己的事情自己做,自己很难做的找代理或其他第三方做!
因此,我们得出一个初步框架:
1、滚动视图:FlowCalendarView,负责实现无限滚动,加载所需月份视图;
2、月份视图:MonthView,负责根据日期生成对应的天视图,并布局天视图及附属视图;
3、日视图:DayView,负责生成对应的点击事件、ui显示等;
对于上面这个框架,主要技术点应该在于:
1、如何实现无限循环;
2、如何根据日期布局日视图。
接下来我们就重点放在技术点上:
一、如何实现无限滚动:
我们知道ScrollView每滚动一点,就会调用layoutSubviews方法,那我们就可以在这个方法里,判断并调整自己的偏移量,这个判断条件是什么呢?我们可以认为,至少底部有一个本身视图高度以上的空间,顶部有0个视图空间,也就是说,contentSize应该至少为自身视图空间的两倍,才能实现无限滚动,这里我们可以取值充裕一点,设置为3倍以上,且判断条件可以为:
//当offset大于(x-1.5)高度或小于0.5高度时候 ,这样需要保证size必须大于3倍高度
if(currentOffset.x<.5*self.frame.size.height||contentH- currentOffset.x<1.5*self.frame.size.height){
//这个时候需要重设中心
}
重设中心需要做的事情是,把偏移移动到centent得中心位置,那必然会导致一定数量的改变,假设这个值为X,那为了保证视图看起来是未移动的,那必然,要让子视图(月视图),都移动响应的X高度,因此:重设中心的代码就是:
float cha=self.contentOffset.y-centerOffsetY;
self.contentOffset = CGPointMake(currentOffset.x, centerOffsetY);//偏移移动到中心
for (UIView* view in _visibleMonthView) {