├── Preview
├── preview-2@2x.jpg
├── preview-3@2x.jpg
├── preview-4@2x.jpg
└── preview-5@2x.jpg
├── Class
├── Other
│ ├── CalendarRow.png
│ ├── CalendarRow@2x.png
│ ├── CalendarRowBottom.png
│ ├── CalendarDisableDate.png
│ ├── CalendarNormalDate.png
│ ├── CalendarTodaysDate.png
│ ├── CalendarPreviousMonth.png
│ ├── CalendarRowBottom@2x.png
│ ├── CalendarSelectedDate.png
│ ├── CalendarTodaysDate@2x.png
│ ├── CalendarPreviousMonth@2x.png
│ └── CalendarSelectedDate@2x.png
├── Model
│ ├── TicketModel.m
│ ├── TicketModel.h
│ ├── RMCalendarModel.m
│ └── RMCalendarModel.h
├── View
│ ├── RMCalendarCollectionViewLayout.h
│ ├── RMCalendarMonthHeaderView.h
│ ├── RMCollectionCell.h
│ ├── RMCalendarMonthHeaderView.m
│ ├── RMCalendarCollectionViewLayout.m
│ └── RMCollectionCell.m
├── Category
│ ├── UIView+CustomFrame.h
│ ├── NSDate+RMCalendarLogic.h
│ ├── UIView+CustomFrame.m
│ └── NSDate+RMCalendarLogic.m
├── Logic
│ ├── RMCalendarLogic.h
│ └── RMCalendarLogic.m
└── Controller
│ ├── RMCalendarController.h
│ └── RMCalendarController.m
├── RMCalendar
├── Default-568h@2x.png
├── ViewController.h
├── MJExtension
│ ├── MJFoundation.h
│ ├── MJExtension.h
│ ├── NSString+MJExtension.h
│ ├── MJConst.m
│ ├── MJType.h
│ ├── NSObject+MJCoding.h
│ ├── MJFoundation.m
│ ├── MJProperty.h
│ ├── NSObject+MJCoding.m
│ ├── MJType.m
│ ├── MJConst.h
│ ├── NSString+MJExtension.m
│ ├── MJProperty.m
│ ├── NSObject+MJProperty.h
│ ├── NSObject+MJKeyValue.h
│ ├── NSObject+MJProperty.m
│ └── NSObject+MJKeyValue.m
├── AppDelegate.h
├── main.m
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Info.plist
├── AppDelegate.m
├── ViewController.m
└── Base.lproj
│ ├── LaunchScreen.xib
│ └── Main.storyboard
├── RMCalendar.xcodeproj
├── xcuserdata
│ ├── chd.xcuserdatad
│ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── RMCalendar.xcscheme
│ └── chihaodong.xcuserdatad
│ │ ├── xcschemes
│ │ └── xcschememanagement.plist
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ ├── chd.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ └── chihaodong.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ └── RMCalendar.xccheckout
└── project.pbxproj
├── RMCalendarTests
├── Info.plist
└── RMCalendarTests.m
└── README.md
/Preview/preview-2@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Preview/preview-2@2x.jpg
--------------------------------------------------------------------------------
/Preview/preview-3@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Preview/preview-3@2x.jpg
--------------------------------------------------------------------------------
/Preview/preview-4@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Preview/preview-4@2x.jpg
--------------------------------------------------------------------------------
/Preview/preview-5@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Preview/preview-5@2x.jpg
--------------------------------------------------------------------------------
/Class/Other/CalendarRow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Class/Other/CalendarRow.png
--------------------------------------------------------------------------------
/Class/Other/CalendarRow@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Class/Other/CalendarRow@2x.png
--------------------------------------------------------------------------------
/RMCalendar/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/RMCalendar/Default-568h@2x.png
--------------------------------------------------------------------------------
/Class/Other/CalendarRowBottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Class/Other/CalendarRowBottom.png
--------------------------------------------------------------------------------
/Class/Other/CalendarDisableDate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Class/Other/CalendarDisableDate.png
--------------------------------------------------------------------------------
/Class/Other/CalendarNormalDate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Class/Other/CalendarNormalDate.png
--------------------------------------------------------------------------------
/Class/Other/CalendarTodaysDate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Class/Other/CalendarTodaysDate.png
--------------------------------------------------------------------------------
/Class/Other/CalendarPreviousMonth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Class/Other/CalendarPreviousMonth.png
--------------------------------------------------------------------------------
/Class/Other/CalendarRowBottom@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Class/Other/CalendarRowBottom@2x.png
--------------------------------------------------------------------------------
/Class/Other/CalendarSelectedDate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Class/Other/CalendarSelectedDate.png
--------------------------------------------------------------------------------
/Class/Other/CalendarTodaysDate@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Class/Other/CalendarTodaysDate@2x.png
--------------------------------------------------------------------------------
/Class/Other/CalendarPreviousMonth@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Class/Other/CalendarPreviousMonth@2x.png
--------------------------------------------------------------------------------
/Class/Other/CalendarSelectedDate@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/Class/Other/CalendarSelectedDate@2x.png
--------------------------------------------------------------------------------
/RMCalendar.xcodeproj/xcuserdata/chd.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/RMCalendar.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/RMCalendar.xcodeproj/project.xcworkspace/xcuserdata/chd.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/RMCalendar.xcodeproj/project.xcworkspace/xcuserdata/chd.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/RMCalendar.xcodeproj/project.xcworkspace/xcuserdata/chihaodong.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chihaodong/RMCalendar/HEAD/RMCalendar.xcodeproj/project.xcworkspace/xcuserdata/chihaodong.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Class/Model/TicketModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // TicketModel.m
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/6.
6 | // Copyright (c) 2015年 迟浩东. All rights reserved.
7 | //
8 |
9 | #import "TicketModel.h"
10 |
11 | @implementation TicketModel
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/RMCalendar/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/1.
6 | // Copyright (c) 2015年 迟浩东. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/MJFoundation.h:
--------------------------------------------------------------------------------
1 | //
2 | // MJFoundation.h
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 14/7/16.
6 | // Copyright (c) 2014年 小码哥. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface MJFoundation : NSObject
12 | + (BOOL)isClassFromFoundation:(Class)c;
13 | @end
14 |
--------------------------------------------------------------------------------
/Class/View/RMCalendarCollectionViewLayout.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMCalendarCollectionViewLayout.h
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/15.
6 | // Copyright © 2015年 迟浩东(http://www.ruanman.net). All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RMCalendarCollectionViewLayout : UICollectionViewFlowLayout
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/RMCalendar/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/1.
6 | // Copyright (c) 2015年 迟浩东. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/Class/View/RMCalendarMonthHeaderView.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMCalendarMonthHeaderView.h
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/15.
6 | // Copyright © 2015年 迟浩东(http://www.ruanman.net). All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RMCalendarMonthHeaderView : UICollectionReusableView
12 |
13 | @property (weak, nonatomic) UILabel *masterLabel;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Class/View/RMCollectionCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMCollectionCell.h
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/15.
6 | // Copyright © 2015年 迟浩东(http://www.ruanman.net). All rights reserved.
7 | //
8 |
9 | #import
10 | @class RMCalendarModel;
11 |
12 | @interface RMCollectionCell : UICollectionViewCell
13 |
14 | @property(nonatomic, strong) RMCalendarModel *model;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/RMCalendar/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/1.
6 | // Copyright (c) 2015年 迟浩东. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/RMCalendar.xcodeproj/xcuserdata/chihaodong.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | RMCalendar.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/MJExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // MJExtension.h
3 | // MJExtension
4 | //
5 | // Created by mj on 14-1-15.
6 | // Copyright (c) 2014年 小码哥. All rights reserved.
7 | // 代码地址:https://github.com/CoderMJLee/MJExtension
8 | // 代码地址:http://code4app.com/ios/%E5%AD%97%E5%85%B8-JSON-%E4%B8%8E%E6%A8%A1%E5%9E%8B%E7%9A%84%E8%BD%AC%E6%8D%A2/5339992a933bf062608b4c57
9 |
10 | #import "NSObject+MJCoding.h"
11 | #import "NSObject+MJProperty.h"
12 | #import "NSObject+MJKeyValue.h"
13 | #import "NSString+MJExtension.h"
14 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/NSString+MJExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+MJExtension.h
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 15/6/7.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSString (MJExtension)
12 | /**
13 | * 驼峰转下划线(loveYou -> love_you)
14 | */
15 | - (NSString *)underlineFromCamel;
16 | /**
17 | * 下划线转驼峰(love_you -> loveYou)
18 | */
19 | - (NSString *)camelFromUnderline;
20 | /**
21 | * 首字母变大写
22 | */
23 | - (NSString *)firstCharUpper;
24 | /**
25 | * 首字母变小写
26 | */
27 | - (NSString *)firstCharLower;
28 | @end
29 |
--------------------------------------------------------------------------------
/Class/Category/UIView+CustomFrame.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+CustomFrame.h
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/4/30.
6 | // Copyright (c) 2015年 CHD. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIView (CustomFrame)
12 |
13 | @property (nonatomic, assign) CGFloat x;
14 | @property (nonatomic, assign) CGFloat y;
15 | @property (nonatomic, assign) CGFloat centerX;
16 | @property (nonatomic, assign) CGFloat centerY;
17 | @property (nonatomic, assign) CGFloat width;
18 | @property (nonatomic, assign) CGFloat height;
19 | @property (nonatomic, assign) CGSize size;
20 | @property (nonatomic, assign) CGPoint origin;
21 | @end
22 |
--------------------------------------------------------------------------------
/Class/Model/TicketModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // TicketModel.h
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/6.
6 | // Copyright (c) 2015年 迟浩东. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TicketModel : NSObject
12 | /**
13 | * 年
14 | */
15 | @property (nonatomic, assign) NSInteger year;
16 | /**
17 | * 月
18 | */
19 | @property (nonatomic, assign) NSInteger month;
20 | /**
21 | * 日
22 | */
23 | @property (nonatomic, assign) NSInteger day;
24 | /**
25 | * 剩余数量
26 | */
27 | @property (nonatomic, assign) NSInteger ticketCount;
28 | /**
29 | * 单价
30 | */
31 | @property (nonatomic, assign) float ticketPrice;
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/RMCalendar.xcodeproj/xcuserdata/chd.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | RMCalendar.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | EE4A4FEE1B43E881004B6590
16 |
17 | primary
18 |
19 |
20 | EE4A50071B43E881004B6590
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/MJConst.m:
--------------------------------------------------------------------------------
1 | #ifndef __MJConst__M__
2 | #define __MJConst__M__
3 |
4 | #import
5 |
6 | /**
7 | * 成员变量类型(属性类型)
8 | */
9 | NSString *const MJTypeInt = @"i";
10 | NSString *const MJTypeFloat = @"f";
11 | NSString *const MJTypeDouble = @"d";
12 | NSString *const MJTypeLong = @"q";
13 | NSString *const MJTypeLongLong = @"q";
14 | NSString *const MJTypeChar = @"c";
15 | NSString *const MJTypeBOOL = @"c";
16 | NSString *const MJTypePointer = @"*";
17 |
18 | NSString *const MJTypeIvar = @"^{objc_ivar=}";
19 | NSString *const MJTypeMethod = @"^{objc_method=}";
20 | NSString *const MJTypeBlock = @"@?";
21 | NSString *const MJTypeClass = @"#";
22 | NSString *const MJTypeSEL = @":";
23 | NSString *const MJTypeId = @"@";
24 |
25 | #endif
--------------------------------------------------------------------------------
/RMCalendar/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/RMCalendarTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.ruanman.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/MJType.h:
--------------------------------------------------------------------------------
1 | //
2 | // MJType.h
3 | // MJExtension
4 | //
5 | // Created by mj on 14-1-15.
6 | // Copyright (c) 2014年 小码哥. All rights reserved.
7 | // 包装一种类型
8 |
9 | #import
10 | /**
11 | * 包装一种类型
12 | */
13 | @interface MJType : NSObject
14 | /** 类型标识符 */
15 | @property (nonatomic, copy) NSString *code;
16 |
17 | /** 是否为id类型 */
18 | @property (nonatomic, readonly, getter=isIdType) BOOL idType;
19 |
20 | /** 是否为基本数字类型:int、float等 */
21 | @property (nonatomic, readonly, getter=isNumberType) BOOL numberType;
22 |
23 | /** 对象类型(如果是基本数据类型,此值为nil) */
24 | @property (nonatomic, readonly) Class typeClass;
25 |
26 | /** 类型是否来自于Foundation框架,比如NSString、NSArray */
27 | @property (nonatomic, readonly, getter = isFromFoundation) BOOL fromFoundation;
28 | /** 类型是否不支持KVC */
29 | @property (nonatomic, readonly, getter = isKVCDisabled) BOOL KVCDisabled;
30 |
31 | /**
32 | * 获得缓存的类型对象
33 | */
34 | + (instancetype)cachedTypeWithCode:(NSString *)code;
35 | @end
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/NSObject+MJCoding.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+MJCoding.h
3 | // MJExtension
4 | //
5 | // Created by mj on 14-1-15.
6 | // Copyright (c) 2014年 小码哥. All rights reserved.
7 | //
8 |
9 | #import
10 | /**
11 | * Codeing协议
12 | */
13 | @protocol MJCoding
14 | @optional
15 | /**
16 | * 这个数组中的属性名才会进行归档
17 | */
18 | + (NSArray *)allowedCodingPropertyNames;
19 | /**
20 | * 这个数组中的属性名将会被忽略:不进行归档
21 | */
22 | + (NSArray *)ignoredCodingPropertyNames;
23 | @end
24 |
25 | @interface NSObject (MJCoding)
26 | /**
27 | * 解码(从文件中解析对象)
28 | */
29 | - (void)decode:(NSCoder *)decoder;
30 | /**
31 | * 编码(将对象写入文件中)
32 | */
33 | - (void)encode:(NSCoder *)encoder;
34 | @end
35 |
36 | /**
37 | 归档的实现
38 | */
39 | #define MJCodingImplementation \
40 | - (id)initWithCoder:(NSCoder *)decoder \
41 | { \
42 | if (self = [super init]) { \
43 | [self decode:decoder]; \
44 | } \
45 | return self; \
46 | } \
47 | \
48 | - (void)encodeWithCoder:(NSCoder *)encoder \
49 | { \
50 | [self encode:encoder]; \
51 | }
--------------------------------------------------------------------------------
/RMCalendarTests/RMCalendarTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMCalendarTests.m
3 | // RMCalendarTests
4 | //
5 | // Created by 迟浩东 on 15/7/1.
6 | // Copyright (c) 2015年 迟浩东. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface RMCalendarTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation RMCalendarTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/Class/Category/NSDate+RMCalendarLogic.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSDate+RMCalendarLogic.h
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/15.
6 | // Copyright © 2015年 迟浩东(http://www.ruanman.net). All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSDate (RMCalendarLogic)
12 |
13 | - (NSUInteger)numberOfDaysInCurrentMonth;
14 |
15 | - (NSUInteger)numberOfWeeksInCurrentMonth;
16 |
17 | - (NSUInteger)weeklyOrdinality;
18 |
19 | - (NSDate *)firstDayOfCurrentMonth;
20 |
21 | - (NSDate *)lastDayOfCurrentMonth;
22 |
23 | - (NSDate *)dayInThePreviousMonth;
24 |
25 | - (NSDate *)dayInTheFollowingMonth;
26 |
27 | - (NSDate *)dayInTheFollowingMonth:(int)month;//获取当前日期之后的几个月
28 |
29 | - (NSDate *)dayInTheFollowingDay:(int)day;//获取当前日期之后的几个天
30 |
31 | - (NSDateComponents *)YMDComponents;
32 |
33 | - (NSDate *)dateFromString:(NSString *)dateString;//NSString转NSDate
34 |
35 | - (NSString *)stringFromDate:(NSDate *)date;//NSDate转NSString
36 |
37 | + (int)getDayNumbertoDay:(NSDate *)today beforDay:(NSDate *)beforday;
38 |
39 | -(int)getWeekIntValueWithDate;
40 |
41 |
42 |
43 | //判断日期是今天,明天,后天,周几
44 | -(NSString *)compareIfTodayWithDate;
45 | //通过数字返回星期几
46 | +(NSString *)getWeekStringFromInteger:(int)week;
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/MJFoundation.m:
--------------------------------------------------------------------------------
1 | //
2 | // MJFoundation.m
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 14/7/16.
6 | // Copyright (c) 2014年 小码哥. All rights reserved.
7 | //
8 |
9 | #import "MJFoundation.h"
10 | #import "MJConst.h"
11 | #import
12 |
13 | static NSSet *_foundationClasses;
14 |
15 | @implementation MJFoundation
16 |
17 | + (void)load
18 | {
19 | _foundationClasses = [NSSet setWithObjects:
20 | [NSObject class],
21 | [NSURL class],
22 | [NSDate class],
23 | [NSNumber class],
24 | [NSDecimalNumber class],
25 | [NSData class],
26 | [NSMutableData class],
27 | [NSArray class],
28 | [NSMutableArray class],
29 | [NSDictionary class],
30 | [NSMutableDictionary class],
31 | [NSManagedObject class],
32 | [NSString class],
33 | [NSMutableString class], nil];
34 | }
35 |
36 | + (BOOL)isClassFromFoundation:(Class)c
37 | {
38 | return [_foundationClasses containsObject:c];
39 | }
40 | @end
41 |
--------------------------------------------------------------------------------
/Class/Logic/RMCalendarLogic.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMCalendarLogic.h
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/15.
6 | // Copyright © 2015年 迟浩东(http://www.ruanman.net). All rights reserved.
7 | //
8 |
9 | #import
10 | #import "RMCalendarModel.h"
11 |
12 | /**
13 | * 日历显示的月数
14 | */
15 | typedef NS_ENUM(NSInteger, CalendarShowType){
16 | /**
17 | * 只显示当月
18 | */
19 | CalendarShowTypeSingle,
20 | /**
21 | * 显示多个月数
22 | */
23 | CalendarShowTypeMultiple
24 | };
25 |
26 | @interface RMCalendarLogic : NSObject
27 |
28 | -(NSMutableArray *)reloadCalendarView:(NSDate *)date selectDate:(NSDate *)selectDate needDays:(int)days showType:(CalendarShowType)type isEnable:(BOOL)isEnable priceModelArr:(NSArray *)arr isChineseCalendar:(BOOL)isChineseCalendar;
29 |
30 | -(NSMutableArray *)reloadCalendarView:(NSDate *)date selectDate:(NSDate *)selectDate needDays:(int)days showType:(CalendarShowType)type isEnable:(BOOL)isEnable priceModelArr:(NSArray *)arr;
31 |
32 | - (NSMutableArray *)reloadCalendarView:(NSDate *)date selectDate:(NSDate *)selectDate needDays:(int)days showType:(CalendarShowType)type priceModelArr:(NSArray *)arr;
33 |
34 |
35 | - (NSMutableArray *)reloadCalendarView:(NSDate *)date selectDate:(NSDate *)selectDate needDays:(int)days showType:(CalendarShowType)type;
36 | - (void)selectLogic:(RMCalendarModel *)dayModel;
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/RMCalendar/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.ruanman.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/MJProperty.h:
--------------------------------------------------------------------------------
1 | //
2 | // MJProperty.h
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 15/4/17.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | // 包装一个成员属性
8 |
9 | #import
10 | #import
11 | #import "MJType.h"
12 |
13 | /**
14 | * 包装一个成员
15 | */
16 | @interface MJProperty : NSObject
17 | /** 成员属性 */
18 | @property (nonatomic, assign) objc_property_t property;
19 | /** 成员属性名 */
20 | @property (nonatomic, readonly) NSString *name;
21 |
22 | /** 成员变量的类型 */
23 | @property (nonatomic, readonly) MJType *type;
24 | /** 成员来源于哪个类(可能是父类) */
25 | @property (nonatomic, assign) Class srcClass;
26 |
27 | /**** 同一个成员变量 - 父类和子类的行为可能不一致(key、keys、objectClassInArray) ****/
28 | /** 对应着字典中的key */
29 | - (void)setKey:(NSString *)key forClass:(Class)c;
30 | - (NSString *)keyFromClass:(Class)c;
31 |
32 | /** 对应着字典中的多级key */
33 | - (NSArray *)keysFromClass:(Class)c;
34 |
35 | /** 模型数组中的模型类型 */
36 | - (void)setObjectClassInArray:(Class)objectClass forClass:(Class)c;
37 | - (Class)objectClassInArrayFromClass:(Class)c;
38 | /**** 同一个成员变量 - 父类和子类的行为可能不一致(key、keys、objectClassInArray) ****/
39 |
40 | /**
41 | * 设置成员变量的值
42 | */
43 | - (void)setValue:(id)value forObject:(id)object;
44 | /**
45 | * 得到成员变量的值
46 | */
47 | - (id)valueFromObject:(id)object;
48 |
49 | /**
50 | * 初始化
51 | */
52 | + (instancetype)cachedPropertyWithProperty:(objc_property_t)property;
53 | @end
54 |
--------------------------------------------------------------------------------
/Class/Model/RMCalendarModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMCalendarModel.m
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/15.
6 | // Copyright © 2015年 迟浩东(http://www.ruanman.net). All rights reserved.
7 | //
8 |
9 | #import "RMCalendarModel.h"
10 | #import "NSDate+RMCalendarLogic.h"
11 |
12 | @implementation RMCalendarModel
13 |
14 | - (instancetype)initWithYear:(NSUInteger)year month:(NSUInteger)month day:(NSUInteger)day {
15 | self = [super init];
16 | if (!self) return nil;
17 | self.year = year;
18 | self.month = month;
19 | self.day = day;
20 | return self;
21 | }
22 |
23 | + (instancetype)calendarWithYear:(NSUInteger)year month:(NSUInteger)month day:(NSUInteger)day {
24 | return [[self alloc] initWithYear:year month:month day:day];
25 | }
26 |
27 | //返回当前天的NSDate对象
28 | - (NSDate *)date
29 | {
30 | NSDateComponents *c = [[NSDateComponents alloc] init];
31 | c.year = self.year;
32 | c.month = self.month;
33 | c.day = self.day;
34 | return [[NSCalendar currentCalendar] dateFromComponents:c];
35 | }
36 |
37 | //返回当前天的NSString对象
38 | - (NSString *)toString
39 | {
40 | NSDate *date = [self date];
41 | NSString *string = [date stringFromDate:date];
42 | return string;
43 | }
44 |
45 |
46 | //返回星期
47 | - (NSString *)getWeek
48 | {
49 |
50 | NSDate *date = [self date];
51 |
52 | NSString *week_str = [date compareIfTodayWithDate];
53 |
54 | return week_str;
55 | }
56 |
57 | ////判断是不是同一天
58 | //- (BOOL)isEqualTo:(CalendarDayModel *)day
59 | //{
60 | // BOOL isEqual = (self.year == day.year) && (self.month == day.month) && (self.day == day.day);
61 | // return isEqual;
62 | //}
63 | @end
64 |
--------------------------------------------------------------------------------
/Class/Model/RMCalendarModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMCalendarModel.h
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/15.
6 | // Copyright © 2015年 迟浩东(http://www.ruanman.net). All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TicketModel.h"
11 |
12 | typedef NS_ENUM(NSInteger, CellDayType) {
13 | CellDayTypeEmpty, //不显示
14 | CellDayTypePast, //过去的日期
15 | CellDayTypeFutur, //将来的日期
16 | CellDayTypeWeek, //周末
17 | CellDayTypeClick //被点击的日期
18 |
19 | };
20 |
21 | @interface RMCalendarModel : NSObject
22 |
23 | /**
24 | * 显示样式
25 | */
26 | @property (assign, nonatomic) CellDayType style;
27 | /**
28 | * 年
29 | */
30 | @property (nonatomic, assign) NSUInteger year;
31 | /**
32 | * 月
33 | */
34 | @property (nonatomic, assign) NSUInteger month;
35 | /**
36 | * 周
37 | */
38 | @property (nonatomic, assign) NSUInteger week;
39 | /**
40 | * 日
41 | */
42 | @property (nonatomic, assign) NSUInteger day;
43 |
44 | /**
45 | * 票价模型
46 | */
47 | @property (nonatomic, strong) TicketModel *ticketModel;
48 | /**
49 | * 判断如果当前日期没有价格,是否可以被点击
50 | */
51 | @property (nonatomic, assign) BOOL isEnable;
52 |
53 | @property (nonatomic, strong) NSString *Chinese_calendar;//农历
54 | @property (nonatomic, assign) BOOL isChineseCalendar;
55 | @property (nonatomic, strong) NSString *holiday;//节日
56 |
57 |
58 | + (instancetype)calendarWithYear:(NSUInteger)year month:(NSUInteger)month day:(NSUInteger)day;
59 | - (instancetype)initWithYear:(NSUInteger)year month:(NSUInteger)month day:(NSUInteger)day;
60 | - (NSDate *)date;//返回当前天的NSDate对象
61 | - (NSString *)toString;//返回当前天的NSString对象
62 | - (NSString *)getWeek; //返回星期
63 |
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/RMCalendar.xcodeproj/project.xcworkspace/xcshareddata/RMCalendar.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 59313485-6EF1-4326-A419-3C7AEEBFBD5F
9 | IDESourceControlProjectName
10 | RMCalendar
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | AC1A553D4D6C0F6FE06F6E60C8CA2E5F97003E1F
14 | https://github.com/chihaodong/RMCalendar.git
15 |
16 | IDESourceControlProjectPath
17 | RMCalendar.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | AC1A553D4D6C0F6FE06F6E60C8CA2E5F97003E1F
21 | ../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/chihaodong/RMCalendar.git
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | AC1A553D4D6C0F6FE06F6E60C8CA2E5F97003E1F
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | AC1A553D4D6C0F6FE06F6E60C8CA2E5F97003E1F
36 | IDESourceControlWCCName
37 | RMCalendar
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/NSObject+MJCoding.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+MJCoding.m
3 | // MJExtension
4 | //
5 | // Created by mj on 14-1-15.
6 | // Copyright (c) 2014年 小码哥. All rights reserved.
7 | //
8 |
9 | #import "NSObject+MJCoding.h"
10 | #import "NSObject+MJProperty.h"
11 | #import "MJProperty.h"
12 |
13 | @implementation NSObject (MJCoding)
14 |
15 | - (void)encode:(NSCoder *)encoder
16 | {
17 | Class aClass = [self class];
18 |
19 | NSArray *allowedCodingPropertyNames = [aClass totalAllowedCodingPropertyNames];
20 | NSArray *ignoredCodingPropertyNames = [aClass totalIgnoredCodingPropertyNames];
21 |
22 | [aClass enumerateProperties:^(MJProperty *property, BOOL *stop) {
23 | if (allowedCodingPropertyNames.count && ![allowedCodingPropertyNames containsObject:property.name]) return;
24 | // 检测是否被忽略
25 | if ([ignoredCodingPropertyNames containsObject:property.name]) return;
26 |
27 | id value = [property valueFromObject:self];
28 | if (value == nil) return;
29 | [encoder encodeObject:value forKey:property.name];
30 | }];
31 | }
32 |
33 | - (void)decode:(NSCoder *)decoder
34 | {
35 | Class aClass = [self class];
36 |
37 | NSArray *allowedCodingPropertyNames = [aClass totalAllowedCodingPropertyNames];
38 | NSArray *ignoredCodingPropertyNames = [aClass totalIgnoredCodingPropertyNames];
39 |
40 | [aClass enumerateProperties:^(MJProperty *property, BOOL *stop) {
41 | if (allowedCodingPropertyNames.count && ![allowedCodingPropertyNames containsObject:property.name]) return;
42 | // 检测是否被忽略
43 | if ([ignoredCodingPropertyNames containsObject:property.name]) return;
44 |
45 | id value = [decoder decodeObjectForKey:property.name];
46 | if (value == nil) return;
47 | [property setValue:value forObject:self];
48 | }];
49 | }
50 | @end
51 |
--------------------------------------------------------------------------------
/Class/Controller/RMCalendarController.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMCalendarController.h
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/15.
6 | // Copyright © 2015年 迟浩东(http://www.ruanman.net). All rights reserved.
7 | //
8 |
9 | #import
10 | #import "RMCalendarLogic.h"
11 | /**
12 | * 选中日起,回掉结果
13 | *
14 | * @param model 返回模型
15 | */
16 | typedef void (^CalendarBlock)(RMCalendarModel *model);
17 |
18 |
19 | /**
20 | * 起始页面
21 | */
22 | @interface RMCalendarController : UIViewController
23 |
24 | /**
25 | * UICollectionView 对象,用于显示布局,类似UITableView
26 | */
27 | @property(nonatomic ,strong) UICollectionView* collectionView;
28 | /**
29 | * 用于存放日期模型数组
30 | */
31 | @property(nonatomic ,strong) NSMutableArray *calendarMonth;
32 | /**
33 | * 逻辑处理
34 | */
35 | @property(nonatomic ,strong) RMCalendarLogic *calendarLogic;
36 | /**
37 | * 回调
38 | */
39 | @property(nonatomic, copy) CalendarBlock calendarBlock;
40 | /**
41 | * 天数
42 | */
43 | @property(nonatomic, assign) int days;
44 | /**
45 | * 展示类型
46 | */
47 | @property(nonatomic, assign) CalendarShowType type;
48 | /**
49 | * 用于存放价格模型数组
50 | */
51 | @property(nonatomic, retain) NSMutableArray *modelArr;
52 | /**
53 | * 无价格的日期是否可点击 默认为NO
54 | */
55 | @property(nonatomic, assign) BOOL isEnable;
56 | /**
57 | * 是否展示农历 默认为NO
58 | */
59 | @property(nonatomic, assign) BOOL isDisplayChineseCalendar;
60 |
61 | /**
62 | * 初始化对象
63 | *
64 | * @param days 显示总天数,默认365天
65 | * @param type 显示类型,详细请见 枚举的定义
66 | *
67 | * @return 当前对象
68 | */
69 | - (instancetype)initWithDays:(int)days showType:(CalendarShowType)type;
70 |
71 | - (instancetype)initWithDays:(int)days showType:(CalendarShowType)type modelArrar:(NSMutableArray *)modelArr;
72 |
73 | + (instancetype)calendarWithDays:(int)days showType:(CalendarShowType)type;
74 |
75 | + (instancetype)calendarWithDays:(int)days showType:(CalendarShowType)type modelArrar:(NSMutableArray *)modelArr;
76 |
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/MJType.m:
--------------------------------------------------------------------------------
1 | //
2 | // MJType.m
3 | // MJExtension
4 | //
5 | // Created by mj on 14-1-15.
6 | // Copyright (c) 2014年 小码哥. All rights reserved.
7 | //
8 |
9 | #import "MJType.h"
10 | #import "MJExtension.h"
11 | #import "MJFoundation.h"
12 | #import "MJConst.h"
13 |
14 | @implementation MJType
15 |
16 | static NSMutableDictionary *_cachedTypes;
17 | + (void)load
18 | {
19 | _cachedTypes = [NSMutableDictionary dictionary];
20 | }
21 |
22 | + (instancetype)cachedTypeWithCode:(NSString *)code
23 | {
24 | MJAssertParamNotNil2(code, nil);
25 |
26 | MJType *type = _cachedTypes[code];
27 | if (type == nil) {
28 | type = [[self alloc] init];
29 | type.code = code;
30 | _cachedTypes[code] = type;
31 | }
32 | return type;
33 | }
34 |
35 | - (void)setCode:(NSString *)code
36 | {
37 | _code = code;
38 |
39 | MJAssertParamNotNil(code);
40 |
41 | if ([code isEqualToString:MJTypeId]) {
42 | _idType = YES;
43 | } else if (code.length == 0) {
44 | _KVCDisabled = YES;
45 | } else if (code.length > 3 && [code hasPrefix:@"@\""]) {
46 | // 去掉@"和",截取中间的类型名称
47 | _code = [code substringWithRange:NSMakeRange(2, code.length - 3)];
48 | _typeClass = NSClassFromString(_code);
49 | _fromFoundation = [MJFoundation isClassFromFoundation:_typeClass];
50 | _numberType = (_typeClass == [NSNumber class] || [_typeClass isSubclassOfClass:[NSNumber class]]);
51 | } else if ([code isEqualToString:MJTypeSEL] ||
52 | [code isEqualToString:MJTypeIvar] ||
53 | [code isEqualToString:MJTypeMethod]) {
54 | _KVCDisabled = YES;
55 | }
56 |
57 | // 是否为数字类型
58 | NSString *lowerCode = _code.lowercaseString;
59 | NSArray *numberTypes = @[MJTypeInt, MJTypeFloat, MJTypeDouble, MJTypeLong, MJTypeChar];
60 | if ([numberTypes containsObject:lowerCode]) {
61 | _numberType = YES;
62 | }
63 | }
64 | @end
65 |
--------------------------------------------------------------------------------
/RMCalendar.xcodeproj/xcuserdata/chihaodong.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
18 |
30 |
31 |
32 |
34 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/MJConst.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef __MJConst__H__
3 | #define __MJConst__H__
4 |
5 | #import
6 |
7 | // 过期
8 | #define MJDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead)
9 |
10 | #ifdef DEBUG // 调试状态
11 | // 打开LOG功能
12 | #define MJLog(...) NSLog(__VA_ARGS__)
13 | #else // 发布状态
14 | // 关闭LOG功能
15 | #define MJLog(...)
16 | #endif
17 |
18 | // 构建错误
19 | #define MJBuildError(error, msg) \
20 | if (error) *error = [NSError errorWithDomain:msg code:250 userInfo:nil];
21 |
22 | /**
23 | * 断言
24 | * @param condition 条件
25 | * @param returnValue 返回值
26 | */
27 | #define MJAssertError(condition, returnValue, error, msg) \
28 | if ((condition) == NO) { \
29 | MJBuildError(error, msg); \
30 | return returnValue;\
31 | }
32 |
33 | #define MJAssert2(condition, returnValue) \
34 | if ((condition) == NO) return returnValue;
35 |
36 | /**
37 | * 断言
38 | * @param condition 条件
39 | */
40 | #define MJAssert(condition) MJAssert2(condition, )
41 |
42 | /**
43 | * 断言
44 | * @param param 参数
45 | * @param returnValue 返回值
46 | */
47 | #define MJAssertParamNotNil2(param, returnValue) \
48 | MJAssert2((param) != nil, returnValue)
49 |
50 | /**
51 | * 断言
52 | * @param param 参数
53 | */
54 | #define MJAssertParamNotNil(param) MJAssertParamNotNil2(param, )
55 |
56 | /**
57 | * 打印所有的属性
58 | */
59 | #define MJLogAllIvars \
60 | -(NSString *)description \
61 | { \
62 | return [self keyValues].description; \
63 | }
64 |
65 | /**
66 | * 类型(属性类型)
67 | */
68 | extern NSString *const MJTypeInt;
69 | extern NSString *const MJTypeFloat;
70 | extern NSString *const MJTypeDouble;
71 | extern NSString *const MJTypeLong;
72 | extern NSString *const MJTypeLongLong;
73 | extern NSString *const MJTypeChar;
74 | extern NSString *const MJTypeBOOL;
75 | extern NSString *const MJTypePointer;
76 |
77 | extern NSString *const MJTypeIvar;
78 | extern NSString *const MJTypeMethod;
79 | extern NSString *const MJTypeBlock;
80 | extern NSString *const MJTypeClass;
81 | extern NSString *const MJTypeSEL;
82 | extern NSString *const MJTypeId;
83 |
84 | #endif
--------------------------------------------------------------------------------
/Class/Category/UIView+CustomFrame.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+CustomFrame.m
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/4/30.
6 | // Copyright (c) 2015年 CHD. All rights reserved.
7 | //
8 |
9 | #import "UIView+CustomFrame.h"
10 |
11 | @implementation UIView (CustomFrame)
12 |
13 |
14 | - (void)setX:(CGFloat)x
15 | {
16 | CGRect frame = self.frame;
17 | frame.origin.x = x;
18 | self.frame = frame;
19 | }
20 |
21 | - (void)setY:(CGFloat)y
22 | {
23 | CGRect frame = self.frame;
24 | frame.origin.y = y;
25 | self.frame = frame;
26 | }
27 |
28 | - (CGFloat)x
29 | {
30 | return self.frame.origin.x;
31 | }
32 |
33 | - (CGFloat)y
34 | {
35 | return self.frame.origin.y;
36 | }
37 |
38 | - (void)setCenterX:(CGFloat)centerX
39 | {
40 | CGPoint center = self.center;
41 | center.x = centerX;
42 | self.center = center;
43 | }
44 |
45 | - (CGFloat)centerX
46 | {
47 | return self.center.x;
48 | }
49 |
50 | - (void)setCenterY:(CGFloat)centerY
51 | {
52 | CGPoint center = self.center;
53 | center.y = centerY;
54 | self.center = center;
55 | }
56 |
57 | - (CGFloat)centerY
58 | {
59 | return self.center.y;
60 | }
61 |
62 | - (void)setWidth:(CGFloat)width
63 | {
64 | CGRect frame = self.frame;
65 | frame.size.width = width;
66 | self.frame = frame;
67 | }
68 |
69 | - (void)setHeight:(CGFloat)height
70 | {
71 | CGRect frame = self.frame;
72 | frame.size.height = height;
73 | self.frame = frame;
74 | }
75 |
76 | - (CGFloat)height
77 | {
78 | return self.frame.size.height;
79 | }
80 |
81 | - (CGFloat)width
82 | {
83 | return self.frame.size.width;
84 | }
85 |
86 | - (void)setSize:(CGSize)size
87 | {
88 | CGRect frame = self.frame;
89 | frame.size = size;
90 | self.frame = frame;
91 | }
92 |
93 | - (CGSize)size
94 | {
95 | return self.frame.size;
96 | }
97 |
98 | - (void)setOrigin:(CGPoint)origin
99 | {
100 | CGRect frame = self.frame;
101 | frame.origin = origin;
102 | self.frame = frame;
103 | }
104 |
105 | - (CGPoint)origin
106 | {
107 | return self.frame.origin;
108 | }
109 | @end
110 |
--------------------------------------------------------------------------------
/RMCalendar/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/1.
6 | // Copyright (c) 2015年 迟浩东. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/NSString+MJExtension.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+MJExtension.m
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 15/6/7.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | //
8 |
9 | #import "NSString+MJExtension.h"
10 |
11 | @implementation NSString (MJExtension)
12 | - (NSString *)underlineFromCamel
13 | {
14 | if (self.length == 0) return self;
15 | NSMutableString *string = [NSMutableString string];
16 | for (NSUInteger i = 0; i= 2) [string appendString:[cmp substringFromIndex:1]];
40 | } else {
41 | [string appendString:cmp];
42 | }
43 | }
44 | return string;
45 | }
46 |
47 | - (NSString *)firstCharLower
48 | {
49 | if (self.length == 0) return self;
50 | NSMutableString *string = [NSMutableString string];
51 | [string appendString:[NSString stringWithFormat:@"%c", [self characterAtIndex:0]].lowercaseString];
52 | if (self.length >= 2) [string appendString:[self substringFromIndex:1]];
53 | return string;
54 | }
55 |
56 | - (NSString *)firstCharUpper
57 | {
58 | if (self.length == 0) return self;
59 | NSMutableString *string = [NSMutableString string];
60 | [string appendString:[NSString stringWithFormat:@"%c", [self characterAtIndex:0]].uppercaseString];
61 | if (self.length >= 2) [string appendString:[self substringFromIndex:1]];
62 | return string;
63 | }
64 | @end
65 |
--------------------------------------------------------------------------------
/Class/View/RMCalendarMonthHeaderView.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMCalendarMonthHeaderView.m
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/15.
6 | // Copyright © 2015年 迟浩东(http://www.ruanman.net). All rights reserved.
7 | //
8 |
9 | #import "RMCalendarMonthHeaderView.h"
10 |
11 | #define CATDayLabelWidth ([UIScreen mainScreen].bounds.size.width/7)
12 | #define CATDayLabelHeight 20.0f
13 |
14 | #define COLOR_THEME1 ([UIColor redColor])
15 | #define COLOR_THEME ([UIColor colorWithRed:26/256.0 green:168/256.0 blue:186/256.0 alpha:1])
16 |
17 | @interface RMCalendarMonthHeaderView()
18 |
19 | @property (weak, nonatomic) UILabel *day1OfTheWeekLabel;
20 | @property (weak, nonatomic) UILabel *day2OfTheWeekLabel;
21 | @property (weak, nonatomic) UILabel *day3OfTheWeekLabel;
22 | @property (weak, nonatomic) UILabel *day4OfTheWeekLabel;
23 | @property (weak, nonatomic) UILabel *day5OfTheWeekLabel;
24 | @property (weak, nonatomic) UILabel *day6OfTheWeekLabel;
25 | @property (weak, nonatomic) UILabel *day7OfTheWeekLabel;
26 |
27 | @end
28 |
29 | @implementation RMCalendarMonthHeaderView
30 |
31 | - (instancetype)initWithFrame:(CGRect)frame
32 | {
33 | self = [super initWithFrame:frame];
34 | if (self) {
35 | // Initialization code
36 | [self initWithHeader];
37 | }
38 | return self;
39 | }
40 |
41 | - (void)initWithHeader
42 | {
43 | self.clipsToBounds = YES;
44 | CGFloat headerWidth = [UIScreen mainScreen].bounds.size.width;
45 | //月份
46 | UILabel *masterLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.f, 10.0f, headerWidth, 30.f)];
47 | [masterLabel setTextAlignment:NSTextAlignmentCenter];
48 | [masterLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:17.0f]];
49 | self.masterLabel = masterLabel;
50 | self.masterLabel.textColor = COLOR_THEME;
51 | [self addSubview:self.masterLabel];
52 | CGFloat yOffset = 45.0f;
53 | NSArray *textArray = @[@"日", @"一", @"二", @"三", @"四", @"五", @"六"];
54 | for (int i = 0; i < textArray.count; i++) {
55 | [self initHeaderWeekText:textArray[i] titleColor:COLOR_THEME x:CATDayLabelWidth * i y:yOffset];
56 | }
57 |
58 | }
59 |
60 | // 初始化数据
61 | - (void)initHeaderWeekText:(NSString *)text titleColor:(UIColor *)color x:(CGFloat)x y:(CGFloat)y {
62 | UILabel *titleText = [[UILabel alloc]initWithFrame:CGRectMake(x, y, CATDayLabelWidth, CATDayLabelHeight)];
63 | [titleText setFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:15.0f]];
64 | titleText.textAlignment = NSTextAlignmentCenter;
65 | titleText.textColor = color;
66 | titleText.text = text;
67 | [self addSubview:titleText];
68 | }
69 |
70 | @end
71 |
72 |
--------------------------------------------------------------------------------
/RMCalendar/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/1.
6 | // Copyright (c) 2015年 迟浩东. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "RMCalendarController.h"
11 | #import "MJExtension.h"
12 | #import "TicketModel.h"
13 |
14 | @interface ViewController ()
15 |
16 | @end
17 |
18 | @implementation ViewController
19 |
20 | - (void)viewDidLoad {
21 | [super viewDidLoad];
22 | // Do any additional setup after loading the view, typically from a nib.
23 | }
24 |
25 | - (void)didReceiveMemoryWarning {
26 | [super didReceiveMemoryWarning];
27 | // Dispose of any resources that can be recreated.
28 | }
29 | - (IBAction)btnClick {
30 | // CalendarShowTypeMultiple 显示多月
31 | // CalendarShowTypeSingle 显示单月
32 | RMCalendarController *c = [RMCalendarController calendarWithDays:365 showType:CalendarShowTypeMultiple];
33 |
34 | // 此处用到MJ大神开发的框架,根据自己需求调整是否需要
35 | c.modelArr = [TicketModel objectArrayWithKeyValuesArray:@[@{@"year":@2015, @"month":@7, @"day":@22,
36 | @"ticketCount":@194, @"ticketPrice":@283},
37 | @{@"year":@2015, @"month":@7, @"day":@17,
38 | @"ticketCount":@91, @"ticketPrice":@223},
39 | @{@"year":@2015, @"month":@10, @"day":@4,
40 | @"ticketCount":@91, @"ticketPrice":@23},
41 | @{@"year":@2015, @"month":@7, @"day":@8,
42 | @"ticketCount":@2, @"ticketPrice":@203},
43 | @{@"year":@2015, @"month":@7, @"day":@28,
44 | @"ticketCount":@2, @"ticketPrice":@103},
45 | @{@"year":@2015, @"month":@7, @"day":@18,
46 | @"ticketCount":@0, @"ticketPrice":@153}]]; //最后一条数据ticketCount 为0时不显示
47 | // 是否展现农历
48 | c.isDisplayChineseCalendar = YES;
49 |
50 | // YES 没有价格的日期可点击
51 | // NO 没有价格的日期不可点击
52 | c.isEnable = YES;
53 | c.title = @"单价日历 软曼网";
54 | c.calendarBlock = ^(RMCalendarModel *model) {
55 | if (model.ticketModel.ticketCount) {
56 | NSLog(@"%lu-%lu-%lu-票价%.1f",(unsigned long)model.year,(unsigned long)model.month,(unsigned long)model.day, model.ticketModel.ticketPrice);
57 | } else {
58 | NSLog(@"%lu-%lu-%lu",(unsigned long)model.year,(unsigned long)model.month,(unsigned long)model.day);
59 | }
60 | };
61 | [self.navigationController pushViewController:c animated:YES];
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RMCalendar 单价日历
2 |
3 | 实现功能:
4 |
5 | 2015年7月16日更新
6 |
7 | 添加农历功能,对细节优化修复
8 |
9 | 主要是在日历上显示 当日对应的单价,类似携程、同城、去哪等旅游APP的日历,可以展现当日的票价等功能。
10 |
11 | 
12 | 
13 | 
14 | 
15 |
16 | # 使用方法
17 |
18 | 将项目下的Class文件夹复制到项目中
19 | 导入对应头文件 #import "RMCalendarController.h" 入口
20 |
21 | 创建对象 (有多种方法,具体看代码)
22 | ```
23 | RMCalendarController *c = [RMCalendarController calendarWithDays:365 showType:CalendarShowTypeMultiple];
24 | c.isDisplayChineseCalendar = YES; // 增加农历展现功能 默认不展现
25 | c.isEnable = YES; // 设置是否显示 无价格时可点击
26 | c.modelArr = "TicketModel模型数组"; //具体属性需看 TicketModel.h 文件 传入格式请按照 下面例子
27 | // 返回结果回调
28 | c.calendarBlock = ^(RMCalendarModel *model) {
29 | if (model.ticketModel.ticketCount) {
30 | NSLog(@"%lu-%lu-%lu-票价%.1f",(unsigned long)model.year,(unsigned long)model.month,(unsigned long)model.day, model.ticketModel.ticketPrice);
31 | } else {
32 | NSLog(@"%lu-%lu-%lu",(unsigned long)model.year,(unsigned long)model.month,(unsigned long)model.day);
33 | }
34 | };
35 | ```
36 |
37 | 如:此处用到MJ的第三方框架将字典数组模型转为模型对象,可根据情况是否使用
38 | ```
39 | c.modelArr = [TicketModel objectArrayWithKeyValuesArray:@[@{@"year":@2015, @"month":@7, @"day":@6,
40 | @"ticketCount":@194, @"ticketPrice":@283},
41 | @{@"year":@2015, @"month":@7, @"day":@7,
42 | @"ticketCount":@91, @"ticketPrice":@223},
43 | @{@"year":@2015, @"month":@10, @"day":@4,
44 | @"ticketCount":@91, @"ticketPrice":@23},
45 | @{@"year":@2015, @"month":@7, @"day":@8,
46 | @"ticketCount":@2, @"ticketPrice":@203},
47 | @{@"year":@2015, @"month":@7, @"day":@28,
48 | @"ticketCount":@2, @"ticketPrice":@103},
49 | @{@"year":@2015, @"month":@7, @"day":@18,
50 | @"ticketCount":@0, @"ticketPrice":@153}]]; //最后一条数据ticketCount 为0时不显示
51 |
52 | ```
53 |
54 | #目录结构
55 | Category 一些扩展的方法
56 | Controller 控制器
57 | Logic 业务逻辑
58 | Model 模型
59 | Other 资源图片
60 | View 视图
61 | #声明 AND 致谢
62 | 1、此处用到MJ的模型转换框架:https://github.com/CoderMJLee/MJExtension
63 | 2、日历源代码是由我爱吃番茄开发,只是在原来基础上增加自己的需求和代码优化工作,实现单价日历效果,再次感谢原作者。http://code4app.com/ios/%E4%B8%80%E6%AC%BE%E7%AE%80%E5%8D%95%E7%9A%84%E6%97%A5%E5%8E%86%E6%8E%A7%E4%BB%B6/53fa8a8b933bf0fe0d8b482b
64 |
65 | #版权
66 | 1、第三方框架版权归于原作者,MJ大神
67 | 2、日历部分源码属于原作者:我爱吃番茄
68 | 3、二次开发版权归于本人
69 | #网站
70 | 软曼网:http://www.ruanman.net/ 提供Windows 10系统下载,iOS 开发技术分享,欢迎大家支持 QQ技术交流群:33415610
71 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/MJProperty.m:
--------------------------------------------------------------------------------
1 | //
2 | // MJProperty.m
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 15/4/17.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | //
8 |
9 | #import "MJProperty.h"
10 | #import "MJFoundation.h"
11 | #import "MJConst.h"
12 |
13 | @interface MJProperty()
14 | @property (strong, nonatomic) NSMutableDictionary *keyDict;
15 | @property (strong, nonatomic) NSMutableDictionary *keysDict;
16 | @property (strong, nonatomic) NSMutableDictionary *objectClassInArrayDict;
17 | @end
18 |
19 | @implementation MJProperty
20 |
21 | - (NSMutableDictionary *)keyDict
22 | {
23 | if (!_keyDict) {
24 | self.keyDict = [NSMutableDictionary dictionary];
25 | }
26 | return _keyDict;
27 | }
28 |
29 | - (NSMutableDictionary *)keysDict
30 | {
31 | if (!_keysDict) {
32 | self.keysDict = [NSMutableDictionary dictionary];
33 | }
34 | return _keysDict;
35 | }
36 |
37 | - (NSMutableDictionary *)objectClassInArrayDict
38 | {
39 | if (!_objectClassInArrayDict) {
40 | self.objectClassInArrayDict = [NSMutableDictionary dictionary];
41 | }
42 | return _objectClassInArrayDict;
43 | }
44 |
45 | + (instancetype)cachedPropertyWithProperty:(objc_property_t)property
46 | {
47 | MJProperty *propertyObj = objc_getAssociatedObject(self, property);
48 | if (propertyObj == nil) {
49 | propertyObj = [[self alloc] init];
50 | propertyObj.property = property;
51 | objc_setAssociatedObject(self, property, propertyObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
52 | }
53 | return propertyObj;
54 | }
55 |
56 | - (void)setProperty:(objc_property_t)property
57 | {
58 | _property = property;
59 |
60 | MJAssertParamNotNil(property);
61 |
62 | // 1.属性名
63 | _name = @(property_getName(property));
64 |
65 | // 2.成员类型
66 | NSString *attrs = @(property_getAttributes(property));
67 | NSUInteger loc = 1;
68 | NSUInteger len = [attrs rangeOfString:@","].location - loc;
69 | _type = [MJType cachedTypeWithCode:[attrs substringWithRange:NSMakeRange(loc, len)]];
70 | }
71 |
72 | /**
73 | * 获得成员变量的值
74 | */
75 | - (id)valueFromObject:(id)object
76 | {
77 | if (_type.KVCDisabled) return [NSNull null];
78 | return [object valueForKey:_name];
79 | }
80 |
81 | /**
82 | * 设置成员变量的值
83 | */
84 | - (void)setValue:(id)value forObject:(id)object
85 | {
86 | if (_type.KVCDisabled || value == nil) return;
87 | [object setValue:value forKey:_name];
88 | }
89 |
90 | /** 对应着字典中的key */
91 | - (void)setKey:(NSString *)key forClass:(Class)c
92 | {
93 | if (!key) return;
94 | self.keyDict[NSStringFromClass(c)] = key;
95 | // 如果有多级映射
96 | [self setKeys:[key componentsSeparatedByString:@"."] forClass:c];
97 | }
98 | - (NSString *)keyFromClass:(Class)c
99 | {
100 | return self.keyDict[NSStringFromClass(c)];
101 | }
102 |
103 | /** 对应着字典中的多级key */
104 | - (void)setKeys:(NSArray *)keys forClass:(Class)c
105 | {
106 | if (!keys) return;
107 | self.keysDict[NSStringFromClass(c)] = keys;
108 | }
109 | - (NSArray *)keysFromClass:(Class)c
110 | {
111 | return self.keysDict[NSStringFromClass(c)];
112 | }
113 |
114 | /** 模型数组中的模型类型 */
115 | - (void)setObjectClassInArray:(Class)objectClass forClass:(Class)c
116 | {
117 | if (!objectClass) return;
118 | self.objectClassInArrayDict[NSStringFromClass(c)] = objectClass;
119 | }
120 | - (Class)objectClassInArrayFromClass:(Class)c
121 | {
122 | return self.objectClassInArrayDict[NSStringFromClass(c)];
123 | }
124 | @end
125 |
--------------------------------------------------------------------------------
/RMCalendar/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/NSObject+MJProperty.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+MJProperty.h
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 15/4/17.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class MJProperty, MJProperty;
12 |
13 | /**
14 | * 遍历所有类的block(父类)
15 | */
16 | typedef void (^MJClassesEnumeration)(Class c, BOOL *stop);
17 |
18 | /**
19 | * 遍历成员变量用的block
20 | *
21 | * @param property 成员的包装对象
22 | * @param stop YES代表停止遍历,NO代表继续遍历
23 | */
24 | typedef void (^MJPropertiesEnumeration)(MJProperty *property, BOOL *stop);
25 |
26 | /** 将属性名换为其他key去字典中取值 */
27 | typedef NSDictionary * (^MJReplacedKeyFromPropertyName)();
28 | typedef NSString * (^MJReplacedKeyFromPropertyName121)(NSString *propertyName);
29 | /** 数组中需要转换的模型类 */
30 | typedef NSDictionary * (^MJObjectClassInArray)();
31 | /** 用于过滤字典中的值 */
32 | typedef id (^MJNewValueFormOldValue)(id object, id oldValue, MJProperty *property);
33 |
34 | /** 这个数组中的属性名才会进行字典和模型的转换 */
35 | typedef NSArray * (^MJAllowedPropertyNames)();
36 | /** 这个数组中的属性名才会进行归档 */
37 | typedef NSArray * (^MJAllowedCodingPropertyNames)();
38 |
39 | /** 这个数组中的属性名将会被忽略:不进行字典和模型的转换 */
40 | typedef NSArray * (^MJIgnoredPropertyNames)();
41 | /** 这个数组中的属性名将会被忽略:不进行归档 */
42 | typedef NSArray * (^MJIgnoredCodingPropertyNames)();
43 |
44 | @interface NSObject (MJProperty)
45 | #pragma mark - 遍历
46 | /**
47 | * 遍历所有的成员
48 | */
49 | + (void)enumerateProperties:(MJPropertiesEnumeration)enumeration;
50 |
51 | /**
52 | * 遍历所有的类
53 | */
54 | + (void)enumerateClasses:(MJClassesEnumeration)enumeration;
55 | + (void)enumerateAllClasses:(MJClassesEnumeration)enumeration;
56 |
57 | #pragma mark - 新值配置
58 | /**
59 | * 用于过滤字典中的值
60 | *
61 | * @param newValueFormOldValue 用于过滤字典中的值
62 | */
63 | + (void)setupNewValueFormOldValue:(MJNewValueFormOldValue)newValueFormOldValue;
64 | + (id)getNewValueFormOldValue:(__weak id)oldValue object:(__weak id)object property:(__weak MJProperty *)property;
65 |
66 | #pragma mark - key配置
67 | /**
68 | * 将属性名换为其他key去字典中取值
69 | *
70 | * @param replacedKeyFromPropertyName 将属性名换为其他key去字典中取值
71 | */
72 | + (void)setupReplacedKeyFromPropertyName:(MJReplacedKeyFromPropertyName)replacedKeyFromPropertyName;
73 | /**
74 | * 将属性名换为其他key去字典中取值
75 | *
76 | * @param replacedKeyFromPropertyName 将属性名换为其他key去字典中取值
77 | */
78 | + (void)setupReplacedKeyFromPropertyName121:(MJReplacedKeyFromPropertyName121)replacedKeyFromPropertyName121;
79 |
80 | #pragma mark - array model class配置
81 | /**
82 | * 数组中需要转换的模型类
83 | *
84 | * @param objectClassInArray 数组中需要转换的模型类
85 | */
86 | + (void)setupObjectClassInArray:(MJObjectClassInArray)objectClassInArray;
87 |
88 | #pragma mark - 属性白名单配置
89 | /**
90 | * 这个数组中的属性名才会进行字典和模型的转换
91 | *
92 | * @param allowedPropertyNames 这个数组中的属性名才会进行字典和模型的转换
93 | */
94 | + (void)setupAllowedPropertyNames:(MJAllowedPropertyNames)allowedPropertyNames;
95 |
96 | /**
97 | * 这个数组中的属性名才会进行字典和模型的转换
98 | */
99 | + (NSMutableArray *)totalAllowedPropertyNames;
100 |
101 | #pragma mark - 归档属性白名单配置
102 | /**
103 | * 这个数组中的属性名才会进行归档
104 | *
105 | * @param allowedCodingPropertyNames 这个数组中的属性名才会进行归档
106 | */
107 | + (void)setupAllowedCodingPropertyNames:(MJAllowedCodingPropertyNames)allowedCodingPropertyNames;
108 |
109 | /**
110 | * 这个数组中的属性名才会进行字典和模型的转换
111 | */
112 | + (NSMutableArray *)totalAllowedCodingPropertyNames;
113 |
114 | #pragma mark - 属性黑名单配置
115 | /**
116 | * 这个数组中的属性名将会被忽略:不进行字典和模型的转换
117 | *
118 | * @param ignoredPropertyNames 这个数组中的属性名将会被忽略:不进行字典和模型的转换
119 | */
120 | + (void)setupIgnoredPropertyNames:(MJIgnoredPropertyNames)ignoredPropertyNames;
121 |
122 | /**
123 | * 这个数组中的属性名将会被忽略:不进行字典和模型的转换
124 | */
125 | + (NSMutableArray *)totalIgnoredPropertyNames;
126 |
127 | #pragma mark - 归档属性黑名单配置
128 | /**
129 | * 这个数组中的属性名将会被忽略:不进行归档
130 | *
131 | * @param ignoredCodingPropertyNames 这个数组中的属性名将会被忽略:不进行归档
132 | */
133 | + (void)setupIgnoredCodingPropertyNames:(MJIgnoredCodingPropertyNames)ignoredCodingPropertyNames;
134 |
135 | /**
136 | * 这个数组中的属性名将会被忽略:不进行归档
137 | */
138 | + (NSMutableArray *)totalIgnoredCodingPropertyNames;
139 | @end
--------------------------------------------------------------------------------
/RMCalendar.xcodeproj/xcuserdata/chd.xcuserdatad/xcschemes/RMCalendar.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
77 |
83 |
84 |
85 |
86 |
87 |
88 |
94 |
96 |
102 |
103 |
104 |
105 |
107 |
108 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/Class/View/RMCalendarCollectionViewLayout.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMCalendarCollectionViewLayout.m
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/15.
6 | // Copyright © 2015年 迟浩东(http://www.ruanman.net). All rights reserved.
7 | //
8 |
9 | #import "RMCalendarCollectionViewLayout.h"
10 |
11 | @implementation RMCalendarCollectionViewLayout
12 |
13 | - (instancetype)init
14 | {
15 | float screen = [UIScreen mainScreen].bounds.size.width;
16 | self = [super init];
17 | if (self) {
18 | // 头部年月视图的大小
19 | self.headerReferenceSize = CGSizeMake(screen, 75.0f);
20 | // 每个Cell大小 -1是用作1个像素的间距
21 | self.itemSize = CGSizeMake(screen/7.0-1, screen/7.0);
22 | // 每行的最小间距
23 | self.minimumLineSpacing = 1.0f;
24 | // 每列的最小间距,设置Cell的大小已经留出1个像素大小,所以此处设置0即可
25 | self.minimumInteritemSpacing = 0.0f;
26 | // CollectionView视图的/上/左/下/右,的边距
27 | self.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
28 | }
29 |
30 | return self;
31 | }
32 |
33 |
34 |
35 | - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
36 |
37 | NSMutableArray *answer = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
38 | UICollectionView * const cv = self.collectionView;
39 | CGPoint const contentOffset = cv.contentOffset;
40 |
41 | NSMutableIndexSet *missingSections = [NSMutableIndexSet indexSet];
42 | for (UICollectionViewLayoutAttributes *layoutAttributes in answer) {
43 | if (layoutAttributes.representedElementCategory == UICollectionElementCategoryCell) {
44 | [missingSections addIndex:layoutAttributes.indexPath.section];
45 | }
46 | }
47 | for (UICollectionViewLayoutAttributes *layoutAttributes in answer) {
48 | if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
49 | [missingSections removeIndex:layoutAttributes.indexPath.section];
50 | }
51 | }
52 |
53 | [missingSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
54 |
55 | NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:idx];
56 |
57 | UICollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath];
58 |
59 | [answer addObject:layoutAttributes];
60 |
61 | }];
62 |
63 | for (UICollectionViewLayoutAttributes *layoutAttributes in answer) {
64 |
65 | if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
66 |
67 | NSInteger section = layoutAttributes.indexPath.section;
68 | NSInteger numberOfItemsInSection = [cv numberOfItemsInSection:section];
69 |
70 | NSIndexPath *firstObjectIndexPath = [NSIndexPath indexPathForItem:0 inSection:section];
71 | NSIndexPath *lastObjectIndexPath = [NSIndexPath indexPathForItem:MAX(0, (numberOfItemsInSection - 1)) inSection:section];
72 |
73 | UICollectionViewLayoutAttributes *firstObjectAttrs;
74 | UICollectionViewLayoutAttributes *lastObjectAttrs;
75 |
76 | if (numberOfItemsInSection > 0) {
77 | firstObjectAttrs = [self layoutAttributesForItemAtIndexPath:firstObjectIndexPath];
78 | lastObjectAttrs = [self layoutAttributesForItemAtIndexPath:lastObjectIndexPath];
79 | } else {
80 | firstObjectAttrs = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader
81 | atIndexPath:firstObjectIndexPath];
82 | lastObjectAttrs = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter
83 | atIndexPath:lastObjectIndexPath];
84 | }
85 |
86 | CGFloat headerHeight = CGRectGetHeight(layoutAttributes.frame);
87 | CGPoint origin = layoutAttributes.frame.origin;
88 | origin.y = MIN(
89 | MAX(
90 | contentOffset.y + cv.contentInset.top,
91 | (CGRectGetMinY(firstObjectAttrs.frame) - headerHeight)
92 | ),
93 | (CGRectGetMaxY(lastObjectAttrs.frame) - headerHeight)
94 | );
95 |
96 | layoutAttributes.zIndex = 1024;
97 | layoutAttributes.frame = (CGRect){
98 | .origin = origin,
99 | .size = layoutAttributes.frame.size
100 | };
101 |
102 | }
103 |
104 | }
105 |
106 | return answer;
107 |
108 | }
109 |
110 | - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBound {
111 |
112 | return YES;
113 |
114 | }
115 |
116 | @end
117 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/NSObject+MJKeyValue.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+MJKeyValue.h
3 | // MJExtension
4 | //
5 | // Created by mj on 13-8-24.
6 | // Copyright (c) 2013年 小码哥. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "MJConst.h"
11 | #import
12 | #import "MJProperty.h"
13 |
14 | /**
15 | * KeyValue协议
16 | */
17 | @protocol MJKeyValue
18 | @optional
19 | /**
20 | * 只有这个数组中的属性名才允许进行字典和模型的转换
21 | */
22 | + (NSArray *)allowedPropertyNames;
23 |
24 | /**
25 | * 这个数组中的属性名将会被忽略:不进行字典和模型的转换
26 | */
27 | + (NSArray *)ignoredPropertyNames;
28 |
29 | /**
30 | * 将属性名换为其他key去字典中取值
31 | *
32 | * @return 字典中的key是属性名,value是从字典中取值用的key
33 | */
34 | + (NSDictionary *)replacedKeyFromPropertyName;
35 |
36 | /**
37 | * 将属性名换为其他key去字典中取值
38 | *
39 | * @return 从字典中取值用的key
40 | */
41 | + (NSString *)replacedKeyFromPropertyName121:(NSString *)propertyName;
42 |
43 | /**
44 | * 数组中需要转换的模型类
45 | *
46 | * @return 字典中的key是数组属性名,value是数组中存放模型的Class(Class类型或者NSString类型)
47 | */
48 | + (NSDictionary *)objectClassInArray;
49 |
50 | /**
51 | * 旧值换新值,用于过滤字典中的值
52 | *
53 | * @param oldValue 旧值
54 | *
55 | * @return 新值
56 | */
57 | - (id)newValueFromOldValue:(id)oldValue property:(MJProperty *)property;
58 |
59 | /**
60 | * 当字典转模型完毕时调用
61 | */
62 | - (void)keyValuesDidFinishConvertingToObject;
63 |
64 | /**
65 | * 当模型转字典完毕时调用
66 | */
67 | - (void)objectDidFinishConvertingToKeyValues;
68 | @end
69 |
70 | @interface NSObject (MJKeyValue)
71 | /**
72 | * 将字典的键值对转成模型属性
73 | * @param keyValues 字典
74 | */
75 | - (instancetype)setKeyValues:(id)keyValues;
76 | - (instancetype)setKeyValues:(id)keyValues error:(NSError **)error;
77 |
78 | /**
79 | * 将字典的键值对转成模型属性
80 | * @param keyValues 字典
81 | * @param context CoreData上下文
82 | */
83 | - (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context;
84 | - (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context error:(NSError **)error;
85 |
86 | /**
87 | * 将模型转成字典
88 | * @return 字典
89 | */
90 | - (NSMutableDictionary *)keyValues;
91 | - (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys;
92 | - (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys;
93 | - (NSMutableDictionary *)keyValuesWithError:(NSError **)error;
94 | - (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys error:(NSError **)error;
95 | - (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys error:(NSError **)error;
96 |
97 | /**
98 | * 通过模型数组来创建一个字典数组
99 | * @param objectArray 模型数组
100 | * @return 字典数组
101 | */
102 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray;
103 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys;
104 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys;
105 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray error:(NSError **)error;
106 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys error:(NSError **)error;
107 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys error:(NSError **)error;
108 |
109 | #pragma mark - 字典转模型
110 | /**
111 | * 通过字典来创建一个模型
112 | * @param keyValues 字典(可以是NSDictionary、NSData、NSString)
113 | * @return 新建的对象
114 | */
115 | + (instancetype)objectWithKeyValues:(id)keyValues;
116 | + (instancetype)objectWithKeyValues:(id)keyValues error:(NSError **)error;
117 |
118 | /**
119 | * 通过字典来创建一个CoreData模型
120 | * @param keyValues 字典(可以是NSDictionary、NSData、NSString)
121 | * @param context CoreData上下文
122 | * @return 新建的对象
123 | */
124 | + (instancetype)objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context;
125 | + (instancetype)objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context error:(NSError **)error;
126 |
127 | /**
128 | * 通过plist来创建一个模型
129 | * @param filename 文件名(仅限于mainBundle中的文件)
130 | * @return 新建的对象
131 | */
132 | + (instancetype)objectWithFilename:(NSString *)filename;
133 | + (instancetype)objectWithFilename:(NSString *)filename error:(NSError **)error;
134 |
135 | /**
136 | * 通过plist来创建一个模型
137 | * @param file 文件全路径
138 | * @return 新建的对象
139 | */
140 | + (instancetype)objectWithFile:(NSString *)file;
141 | + (instancetype)objectWithFile:(NSString *)file error:(NSError **)error;
142 |
143 | #pragma mark - 字典数组转模型数组
144 | /**
145 | * 通过字典数组来创建一个模型数组
146 | * @param keyValuesArray 字典数组(可以是NSDictionary、NSData、NSString)
147 | * @return 模型数组
148 | */
149 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray;
150 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray error:(NSError **)error;
151 |
152 | /**
153 | * 通过字典数组来创建一个模型数组
154 | * @param keyValuesArray 字典数组(可以是NSDictionary、NSData、NSString)
155 | * @param context CoreData上下文
156 | * @return 模型数组
157 | */
158 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context;
159 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context error:(NSError **)error;
160 |
161 | /**
162 | * 通过plist来创建一个模型数组
163 | * @param filename 文件名(仅限于mainBundle中的文件)
164 | * @return 模型数组
165 | */
166 | + (NSMutableArray *)objectArrayWithFilename:(NSString *)filename;
167 | + (NSMutableArray *)objectArrayWithFilename:(NSString *)filename error:(NSError **)error;
168 |
169 | /**
170 | * 通过plist来创建一个模型数组
171 | * @param file 文件全路径
172 | * @return 模型数组
173 | */
174 | + (NSMutableArray *)objectArrayWithFile:(NSString *)file;
175 | + (NSMutableArray *)objectArrayWithFile:(NSString *)file error:(NSError **)error;
176 |
177 | #pragma mark - 转换为JSON
178 | - (NSData *)JSONData;
179 | - (id)JSONObject;
180 | - (NSString *)JSONString;
181 | @end
182 |
--------------------------------------------------------------------------------
/RMCalendar/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
31 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/Class/View/RMCollectionCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMCollectionCell.m
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/15.
6 | // Copyright © 2015年 迟浩东(http://www.ruanman.net). All rights reserved.
7 | //
8 |
9 | #import "RMCollectionCell.h"
10 | #import "UIView+CustomFrame.h"
11 | #import "RMCalendarModel.h"
12 |
13 | #import "TicketModel.h"
14 |
15 | #define kFont(x) [UIFont systemFontOfSize:x]
16 | #define COLOR_HIGHLIGHT ([UIColor redColor])
17 | #define COLOR_NOAML ([UIColor colorWithRed:26/256.0 green:168/256.0 blue:186/256.0 alpha:1])
18 |
19 | @interface RMCollectionCell()
20 |
21 | /**
22 | * 显示日期
23 | */
24 | @property (nonatomic, weak) UILabel *dayLabel;
25 | /**
26 | * 显示农历
27 | */
28 | @property (nonatomic, weak) UILabel *chineseCalendar;
29 | /**
30 | * 选中的背景图片
31 | */
32 | @property (nonatomic, weak) UIImageView *selectImageView;
33 | /**
34 | * 票价 此处可根据项目需求自行修改
35 | */
36 | @property (nonatomic, weak) UILabel *price;
37 |
38 |
39 | @end
40 |
41 | @implementation RMCollectionCell
42 |
43 | - (nonnull instancetype)initWithFrame:(CGRect)frame {
44 | self = [super initWithFrame:frame];
45 | if (!self) return nil;
46 | [self initCellView];
47 | return self;
48 | }
49 |
50 | - (void)initCellView {
51 |
52 | //选中时显示的图片
53 | UIImageView *selectImageView = [[UIImageView alloc]initWithFrame:self.bounds];
54 | selectImageView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"CalendarSelectedDate"]];
55 | self.selectImageView = selectImageView;
56 | [self addSubview:selectImageView];
57 |
58 | UILabel *dayLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 0, self.bounds.size.width * 0.5, self.bounds.size.width * 0.5)];
59 | dayLabel.font = kFont(14);
60 | self.dayLabel = dayLabel;
61 | [self addSubview:dayLabel];
62 |
63 | UILabel *chineseCalendar = [[UILabel alloc] initWithFrame:CGRectMake(self.bounds.size.width * 0.5, 0, dayLabel.width, dayLabel.height)];
64 | chineseCalendar.font = kFont(9);
65 | chineseCalendar.textAlignment = NSTextAlignmentCenter;
66 | self.chineseCalendar = chineseCalendar;
67 | [self addSubview:chineseCalendar];
68 |
69 | #warning 价格Label 可根据需求修改
70 | UILabel *price = [[UILabel alloc] initWithFrame:CGRectMake(0, dayLabel.height, self.bounds.size.width, dayLabel.height)];
71 | price.font = kFont(9);
72 | price.textAlignment = NSTextAlignmentCenter;
73 | self.price = price;
74 | [self addSubview:price];
75 | }
76 |
77 | - (void)setModel:(RMCalendarModel *)model {
78 | _model = model;
79 | //没有剩余票数
80 | if (!model.ticketModel.ticketCount || model.style == CellDayTypePast) {
81 | self.price.hidden = YES;
82 | model.isEnable ? model.style : model.style != CellDayTypeEmpty ? model.style = CellDayTypePast : model.style;
83 | } else {
84 | self.price.hidden = NO;
85 | self.price.textColor = [UIColor orangeColor];
86 | self.price.text = [NSString stringWithFormat:@"¥%.1f",model.ticketModel.ticketPrice];
87 | }
88 | self.chineseCalendar.text = model.Chinese_calendar;
89 | self.chineseCalendar.hidden = NO;
90 | /**
91 | * 如果不展示农历,则日期居中
92 | */
93 | if (!model.isChineseCalendar) {
94 | self.dayLabel.x = 0;
95 | self.dayLabel.width = self.bounds.size.width;
96 | self.dayLabel.textAlignment = NSTextAlignmentCenter;
97 | }
98 |
99 | switch (model.style) {
100 | case CellDayTypeEmpty:
101 | self.selectImageView.hidden = YES;
102 | self.dayLabel.hidden = YES;
103 | self.backgroundColor = [UIColor whiteColor];
104 | self.chineseCalendar.hidden = YES;
105 | break;
106 | case CellDayTypePast:
107 | self.dayLabel.hidden = NO;
108 | self.selectImageView.hidden = YES;
109 | if (model.holiday) {
110 | self.dayLabel.text = model.holiday;
111 | self.dayLabel.width = self.bounds.size.width;
112 | self.chineseCalendar.hidden = YES;
113 | } else {
114 | self.dayLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)model.day];
115 | }
116 | self.chineseCalendar.textColor = [UIColor lightGrayColor];
117 | self.dayLabel.textColor = [UIColor lightGrayColor];
118 | self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"CalendarDisableDate"]];
119 | break;
120 |
121 | case CellDayTypeWeek:
122 | // 以下内容暂时无用 将来可以设置 周六 日 特殊颜色时 可用
123 | // self.dayLabel.hidden = NO;
124 | // self.selectImageView.hidden = YES;
125 | // if (model.holiday) {
126 | // self.dayLabel.text = model.holiday;
127 | // self.dayLabel.textColor = COLOR_HIGHLIGHT;
128 | // } else {
129 | // self.dayLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)model.day];
130 | // self.dayLabel.textColor = COLOR_NOAML;
131 | // }
132 | // self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"CalendarNormalDate"]];
133 | // self.chineseCalendar.textColor = [UIColor blackColor];
134 | // break;
135 |
136 | case CellDayTypeFutur:
137 | self.dayLabel.hidden = NO;
138 | self.selectImageView.hidden = YES;
139 | if (model.holiday) {
140 | self.dayLabel.text = model.holiday;
141 | self.dayLabel.width = self.bounds.size.width;
142 | self.chineseCalendar.hidden = YES;
143 | self.dayLabel.textColor = COLOR_HIGHLIGHT;
144 | } else {
145 | self.dayLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)model.day];
146 | self.dayLabel.textColor = COLOR_NOAML;
147 | }
148 | self.chineseCalendar.textColor = [UIColor blackColor];
149 | self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"CalendarNormalDate"]];
150 | break;
151 |
152 | case CellDayTypeClick:
153 | self.dayLabel.hidden = NO;
154 | self.selectImageView.hidden = NO;
155 | self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"CalendarNormalDate"]];
156 | self.dayLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)model.day];
157 | self.dayLabel.textColor = [UIColor whiteColor];
158 | self.price.textColor = [UIColor whiteColor];
159 | self.chineseCalendar.textColor = [UIColor whiteColor];
160 | break;
161 |
162 | default:
163 | break;
164 | }
165 |
166 | }
167 |
168 | @end
169 |
--------------------------------------------------------------------------------
/Class/Controller/RMCalendarController.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMCalendarController.m
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/15.
6 | // Copyright © 2015年 迟浩东(http://www.ruanman.net). All rights reserved.
7 | //
8 |
9 | #import "RMCalendarController.h"
10 | #import "RMCalendarCollectionViewLayout.h"
11 | #import "RMCollectionCell.h"
12 | #import "RMCalendarMonthHeaderView.h"
13 | #import "RMCalendarLogic.h"
14 |
15 | @interface RMCalendarController ()
16 |
17 | @end
18 |
19 | @implementation RMCalendarController
20 |
21 | static NSString *MonthHeader = @"MonthHeaderView";
22 |
23 | static NSString *DayCell = @"DayCell";
24 |
25 | /**
26 | * 初始化模型数组对象
27 | */
28 | - (NSMutableArray *)calendarMonth {
29 | if (!_calendarMonth) {
30 | _calendarMonth = [NSMutableArray array];
31 | }
32 | return _calendarMonth;
33 | }
34 |
35 | - (RMCalendarLogic *)calendarLogic {
36 | if (!_calendarLogic) {
37 | _calendarLogic = [[RMCalendarLogic alloc] init];
38 | }
39 | return _calendarLogic;
40 | }
41 |
42 | - (instancetype)initWithDays:(int)days showType:(CalendarShowType)type modelArrar:(NSMutableArray *)modelArr {
43 | self = [super init];
44 | if (!self) return nil;
45 | self.days = days;
46 | self.type = type;
47 | self.modelArr = modelArr;
48 | return self;
49 | }
50 |
51 | - (instancetype)initWithDays:(int)days showType:(CalendarShowType)type {
52 | self = [super init];
53 | if (!self) return nil;
54 | self.days = days;
55 | self.type = type;
56 | return self;
57 | }
58 |
59 | + (instancetype)calendarWithDays:(int)days showType:(CalendarShowType)type modelArrar:(NSMutableArray *)modelArr {
60 | return [[self alloc] initWithDays:days showType:type modelArrar:modelArr];
61 | }
62 |
63 | + (instancetype)calendarWithDays:(int)days showType:(CalendarShowType)type {
64 | return [[self alloc] initWithDays:days showType:type];
65 | }
66 |
67 | - (void)setModelArr:(NSMutableArray *)modelArr {
68 | #if __has_feature(objc_arc)
69 | _modelArr = modelArr;
70 | #else
71 | if (_modelArr != modelArr) {
72 | [_modelArr release];
73 | _modelArr = [modelArr retain];
74 | }
75 | #endif
76 | }
77 |
78 | - (void)viewDidLoad {
79 | [super viewDidLoad];
80 | // 定义Layout对象
81 | RMCalendarCollectionViewLayout *layout = [[RMCalendarCollectionViewLayout alloc] init];
82 |
83 | // 初始化CollectionView
84 | self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
85 |
86 | #if !__has_feature(objc_arc)
87 | [layout release];
88 | #endif
89 |
90 | // 注册CollectionView的Cell
91 | [self.collectionView registerClass:[RMCollectionCell class] forCellWithReuseIdentifier:DayCell];
92 |
93 | [self.collectionView registerClass:[RMCalendarMonthHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:MonthHeader];
94 |
95 | // self.collectionView.bounces = NO;//将网格视图的下拉效果关闭
96 |
97 | self.collectionView.delegate = self;//实现网格视图的delegate
98 |
99 | self.collectionView.dataSource = self;//实现网格视图的dataSource
100 |
101 | self.collectionView.backgroundColor = [UIColor whiteColor];
102 |
103 | [self.view addSubview:self.collectionView];
104 |
105 | self.calendarMonth = [self getMonthArrayOfDays:self.days showType:self.type isEnable:self.isEnable modelArr:self.modelArr];
106 | }
107 |
108 | - (void)didReceiveMemoryWarning {
109 | [super didReceiveMemoryWarning];
110 | }
111 |
112 | /**
113 | * 获取Days天数内的数组
114 | *
115 | * @param days 天数
116 | * @param type 显示类型
117 | * @param arr 模型数组
118 | * @return 数组
119 | */
120 | - (NSMutableArray *)getMonthArrayOfDays:(int)days showType:(CalendarShowType)type isEnable:(BOOL)isEnable modelArr:(NSArray *)arr
121 | {
122 | NSDate *date = [NSDate date];
123 |
124 | NSDate *selectdate = [NSDate date];
125 | //返回数据模型数组
126 | return [self.calendarLogic reloadCalendarView:date selectDate:selectdate needDays:days showType:type isEnable:isEnable priceModelArr:arr isChineseCalendar:self.isDisplayChineseCalendar];
127 | }
128 |
129 | #pragma mark - CollectionView 数据源
130 |
131 | // 返回组数
132 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
133 | return self.calendarMonth.count;
134 | }
135 | // 返回每组行数
136 | - (NSInteger)collectionView:(nonnull UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
137 | NSArray *arrary = [self.calendarMonth objectAtIndex:section];
138 | return arrary.count;
139 | }
140 |
141 | #pragma mark - CollectionView 代理
142 |
143 | - (UICollectionViewCell *)collectionView:(nonnull UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath {
144 | RMCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:DayCell forIndexPath:indexPath];
145 | NSArray *months = [self.calendarMonth objectAtIndex:indexPath.section];
146 | RMCalendarModel *model = [months objectAtIndex:indexPath.row];
147 | cell.model = model;
148 | return cell;
149 | }
150 |
151 | - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
152 | {
153 | UICollectionReusableView *reusableview = nil;
154 |
155 | if (kind == UICollectionElementKindSectionHeader){
156 |
157 | NSMutableArray *month_Array = [self.calendarMonth objectAtIndex:indexPath.section];
158 | RMCalendarModel *model = [month_Array objectAtIndex:15];
159 |
160 | RMCalendarMonthHeaderView *monthHeader = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:MonthHeader forIndexPath:indexPath];
161 | monthHeader.masterLabel.text = [NSString stringWithFormat:@"%lu年 %lu月",(unsigned long)model.year,(unsigned long)model.month];//@"日期";
162 | monthHeader.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8f];
163 | reusableview = monthHeader;
164 | }
165 | return reusableview;
166 |
167 | }
168 |
169 | - (void)collectionView:(nonnull UICollectionView *)collectionView didSelectItemAtIndexPath:(nonnull NSIndexPath *)indexPath {
170 | NSArray *months = [self.calendarMonth objectAtIndex:indexPath.section];
171 | RMCalendarModel *model = [months objectAtIndex:indexPath.row];
172 | if (model.style == CellDayTypeClick || model.style == CellDayTypeFutur || model.style == CellDayTypeWeek) {
173 | [self.calendarLogic selectLogic:model];
174 | if (self.calendarBlock) {
175 | self.calendarBlock(model);
176 | }
177 | }
178 | [self.collectionView reloadData];
179 | }
180 |
181 | - (BOOL)collectionView:(nonnull UICollectionView *)collectionView shouldSelectItemAtIndexPath:(nonnull NSIndexPath *)indexPath {
182 | return YES;
183 | }
184 |
185 | -(void)dealloc {
186 | #if !__has_feature(objc_arc)
187 | [self.collectionView release];
188 | [super dealloc];
189 | #endif
190 | }
191 |
192 |
193 | @end
194 |
--------------------------------------------------------------------------------
/Class/Category/NSDate+RMCalendarLogic.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSDate+RMCalendarLogic.m
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/15.
6 | // Copyright © 2015年 迟浩东(http://www.ruanman.net). All rights reserved.
7 | //
8 |
9 | #import "NSDate+RMCalendarLogic.h"
10 |
11 | @implementation NSDate (RMCalendarLogic)
12 |
13 | /*计算这个月有多少天*/
14 | - (NSUInteger)numberOfDaysInCurrentMonth
15 | {
16 | // 频繁调用 [NSCalendar currentCalendar] 可能存在性能问题
17 | return [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:self].length;
18 | }
19 |
20 |
21 | //获取这个月有多少周
22 | - (NSUInteger)numberOfWeeksInCurrentMonth
23 | {
24 | NSUInteger weekday = [[self firstDayOfCurrentMonth] weeklyOrdinality];
25 | NSUInteger days = [self numberOfDaysInCurrentMonth];
26 | NSUInteger weeks = 0;
27 |
28 | if (weekday > 1) {
29 | weeks += 1, days -= (7 - weekday + 1);
30 | }
31 |
32 | weeks += days / 7;
33 | weeks += (days % 7 > 0) ? 1 : 0;
34 |
35 | return weeks;
36 | }
37 |
38 |
39 |
40 | /*计算这个月的第一天是礼拜几*/
41 | - (NSUInteger)weeklyOrdinality
42 | {
43 | return [[NSCalendar currentCalendar] ordinalityOfUnit:NSDayCalendarUnit inUnit:NSWeekCalendarUnit forDate:self];
44 | }
45 |
46 |
47 |
48 | //计算这个月最开始的一天
49 | - (NSDate *)firstDayOfCurrentMonth
50 | {
51 | NSDate *startDate = nil;
52 | BOOL ok = [[NSCalendar currentCalendar] rangeOfUnit:NSMonthCalendarUnit startDate:&startDate interval:NULL forDate:self];
53 | NSAssert1(ok, @"Failed to calculate the first day of the month based on %@", self);
54 | return startDate;
55 | }
56 |
57 |
58 | - (NSDate *)lastDayOfCurrentMonth
59 | {
60 | NSCalendarUnit calendarUnit = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
61 | NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:calendarUnit fromDate:self];
62 | dateComponents.day = [self numberOfDaysInCurrentMonth];
63 | return [[NSCalendar currentCalendar] dateFromComponents:dateComponents];
64 | }
65 |
66 | //上一个月
67 | - (NSDate *)dayInThePreviousMonth
68 | {
69 | NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
70 | dateComponents.month = -1;
71 | return [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:self options:0];
72 | }
73 |
74 | //下一个月
75 | - (NSDate *)dayInTheFollowingMonth
76 | {
77 | NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
78 | dateComponents.month = 1;
79 | return [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:self options:0];
80 | }
81 |
82 |
83 | //获取当前日期之后的几个月
84 | - (NSDate *)dayInTheFollowingMonth:(int)month
85 | {
86 | NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
87 | dateComponents.month = month;
88 | return [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:self options:0];
89 | }
90 |
91 | //获取当前日期之后的几个天
92 | - (NSDate *)dayInTheFollowingDay:(int)day
93 | {
94 | NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
95 | dateComponents.day = day;
96 | return [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:self options:0];
97 | }
98 |
99 | //获取年月日对象
100 | - (NSDateComponents *)YMDComponents
101 | {
102 | return [[NSCalendar currentCalendar] components:
103 | NSYearCalendarUnit|
104 | NSMonthCalendarUnit|
105 | NSDayCalendarUnit|
106 | NSWeekdayCalendarUnit fromDate:self];
107 | }
108 |
109 |
110 | //-----------------------------------------
111 | //
112 | //NSString转NSDate
113 | - (NSDate *)dateFromString:(NSString *)dateString
114 | {
115 |
116 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
117 |
118 | // [dateFormatter setDateFormat: @"yyyy-MM-dd HH:mm:ss"];
119 | [dateFormatter setDateFormat: @"yyyy-MM-dd"];
120 |
121 | NSDate *destDate= [dateFormatter dateFromString:dateString];
122 |
123 | return destDate;
124 |
125 | }
126 |
127 |
128 |
129 | //NSDate转NSString
130 | - (NSString *)stringFromDate:(NSDate *)date
131 | {
132 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
133 |
134 | //zzz表示时区,zzz可以删除,这样返回的日期字符将不包含时区信息。
135 |
136 | // [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss zzz"];
137 | [dateFormatter setDateFormat:@"yyyy-MM-dd"];
138 |
139 | NSString *destDateString = [dateFormatter stringFromDate:date];
140 |
141 | return destDateString;
142 | }
143 |
144 |
145 | + (int)getDayNumbertoDay:(NSDate *)today beforDay:(NSDate *)beforday
146 | {
147 |
148 | NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];//日历控件对象
149 | NSDateComponents *components = [calendar components:NSDayCalendarUnit fromDate:today toDate:beforday options:0];
150 | // NSDateComponents *components = [calendar components:NSMonthCalendarUnit|NSDayCalendarUnit fromDate:today toDate:beforday options:0];
151 | int day = (int)[components day];//两个日历之间相差多少月// NSInteger days = [components day];//两个之间相差几天
152 | return day;
153 | }
154 |
155 |
156 | //周日是“1”,周一是“2”...
157 | - (int)getWeekIntValueWithDate
158 | {
159 | int weekIntValue;
160 |
161 | NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSChineseCalendar];
162 | NSDateComponents *comps= [calendar components:(NSYearCalendarUnit |
163 | NSMonthCalendarUnit |
164 | NSDayCalendarUnit |
165 | NSWeekdayCalendarUnit) fromDate:self];
166 | return weekIntValue = (int)[comps weekday];
167 | }
168 |
169 |
170 |
171 |
172 | //判断日期是今天,明天,后天,周几
173 | -(NSString *)compareIfTodayWithDate
174 | {
175 | NSDate *todate = [NSDate date];//今天
176 | NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSChineseCalendar];
177 | NSDateComponents *comps_today= [calendar components:(NSYearCalendarUnit |
178 | NSMonthCalendarUnit |
179 | NSDayCalendarUnit |
180 | NSWeekdayCalendarUnit) fromDate:todate];
181 |
182 |
183 | NSDateComponents *comps_other= [calendar components:(NSYearCalendarUnit |
184 | NSMonthCalendarUnit |
185 | NSDayCalendarUnit |
186 | NSWeekdayCalendarUnit) fromDate:self];
187 |
188 |
189 | //获取星期对应的数字
190 | int weekIntValue = [self getWeekIntValueWithDate];
191 |
192 | if (comps_today.year == comps_other.year &&
193 | comps_today.month == comps_other.month &&
194 | comps_today.day == comps_other.day) {
195 | return @"今天";
196 |
197 | }else if (comps_today.year == comps_other.year &&
198 | comps_today.month == comps_other.month &&
199 | (comps_today.day - comps_other.day) == -1){
200 | return @"明天";
201 |
202 | }else if (comps_today.year == comps_other.year &&
203 | comps_today.month == comps_other.month &&
204 | (comps_today.day - comps_other.day) == -2){
205 | return @"后天";
206 |
207 | }else{
208 | //直接返回当时日期的字符串(这里让它返回空)
209 | return [NSDate getWeekStringFromInteger:weekIntValue];//周几
210 | }
211 | }
212 |
213 |
214 |
215 | //通过数字返回星期几
216 | +(NSString *)getWeekStringFromInteger:(int)week
217 | {
218 | NSString *str_week;
219 |
220 | switch (week) {
221 | case 1:
222 | str_week = @"周日";
223 | break;
224 | case 2:
225 | str_week = @"周一";
226 | break;
227 | case 3:
228 | str_week = @"周二";
229 | break;
230 | case 4:
231 | str_week = @"周三";
232 | break;
233 | case 5:
234 | str_week = @"周四";
235 | break;
236 | case 6:
237 | str_week = @"周五";
238 | break;
239 | case 7:
240 | str_week = @"周六";
241 | break;
242 | }
243 | return str_week;
244 | }
245 |
246 |
247 | @end
248 |
--------------------------------------------------------------------------------
/RMCalendar/MJExtension/NSObject+MJProperty.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+MJProperty.m
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 15/4/17.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | //
8 |
9 | #import "NSObject+MJProperty.h"
10 | #import "NSObject+MJKeyValue.h"
11 | #import "NSObject+MJCoding.h"
12 | #import "MJProperty.h"
13 | #import "MJFoundation.h"
14 | #import
15 |
16 | static const char MJReplacedKeyFromPropertyNameKey = '\0';
17 | static const char MJReplacedKeyFromPropertyName121Key = '\0';
18 | static const char MJNewValueFromOldValueKey = '\0';
19 | static const char MJObjectClassInArrayKey = '\0';
20 | static const char MJAllowedPropertyNamesKey = '\0';
21 | static const char MJAllowedCodingPropertyNamesKey = '\0';
22 | static const char MJIgnoredPropertyNamesKey = '\0';
23 | static const char MJIgnoredCodingPropertyNamesKey = '\0';
24 |
25 | @implementation NSObject (Property)
26 | #pragma mark - --私有方法--
27 | + (NSString *)propertyKey:(NSString *)propertyName
28 | {
29 | MJAssertParamNotNil2(propertyName, nil);
30 |
31 | __block NSString *key = nil;
32 | // 查看有没有需要替换的key
33 | if ([self respondsToSelector:@selector(replacedKeyFromPropertyName121:)]) {
34 | key = [self replacedKeyFromPropertyName121:propertyName];
35 | }
36 |
37 | // 调用block
38 | if (!key) {
39 | [self enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
40 | MJReplacedKeyFromPropertyName121 block = objc_getAssociatedObject(c, &MJReplacedKeyFromPropertyName121Key);
41 | if (block) {
42 | key = block(propertyName);
43 | }
44 | if (key) *stop = YES;
45 | }];
46 | }
47 |
48 | // 查看有没有需要替换的key
49 | if (!key && [self respondsToSelector:@selector(replacedKeyFromPropertyName)]) {
50 | key = [self replacedKeyFromPropertyName][propertyName];
51 | }
52 |
53 | if (!key) {
54 | [self enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
55 | NSDictionary *dict = objc_getAssociatedObject(c, &MJReplacedKeyFromPropertyNameKey);
56 | if (dict) {
57 | key = dict[propertyName];
58 | }
59 | if (key) *stop = YES;
60 | }];
61 | }
62 |
63 | // 2.用属性名作为key
64 | if (!key) key = propertyName;
65 |
66 | return key;
67 | }
68 |
69 | + (Class)propertyObjectClassInArray:(NSString *)propertyName
70 | {
71 | __block id aClass = nil;
72 | if ([self respondsToSelector:@selector(objectClassInArray)]) {
73 | aClass = [self objectClassInArray][propertyName];
74 | }
75 |
76 | if (!aClass) {
77 | [self enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
78 | NSDictionary *dict = objc_getAssociatedObject(c, &MJObjectClassInArrayKey);
79 | if (dict) {
80 | aClass = dict[propertyName];
81 | }
82 | if (aClass) *stop = YES;
83 | }];
84 | }
85 |
86 | // 如果是NSString类型
87 | if ([aClass isKindOfClass:[NSString class]]) {
88 | aClass = NSClassFromString(aClass);
89 | }
90 | return aClass;
91 | }
92 |
93 | #pragma mark - --公共方法--
94 | + (void)enumerateProperties:(MJPropertiesEnumeration)enumeration
95 | {
96 | // 获得成员变量
97 | NSArray *cachedProperties = [self properties];
98 |
99 | // 遍历成员变量
100 | BOOL stop = NO;
101 | for (MJProperty *property in cachedProperties) {
102 | enumeration(property, &stop);
103 | if (stop) break;
104 | }
105 | }
106 |
107 | + (void)enumerateClasses:(MJClassesEnumeration)enumeration
108 | {
109 | // 1.没有block就直接返回
110 | if (enumeration == nil) return;
111 |
112 | // 2.停止遍历的标记
113 | BOOL stop = NO;
114 |
115 | // 3.当前正在遍历的类
116 | Class c = self;
117 |
118 | // 4.开始遍历每一个类
119 | while (c && !stop) {
120 | // 4.1.执行操作
121 | enumeration(c, &stop);
122 |
123 | // 4.2.获得父类
124 | c = class_getSuperclass(c);
125 |
126 | if ([MJFoundation isClassFromFoundation:c]) break;
127 | }
128 | }
129 |
130 | + (void)enumerateAllClasses:(MJClassesEnumeration)enumeration
131 | {
132 | // 1.没有block就直接返回
133 | if (enumeration == nil) return;
134 |
135 | // 2.停止遍历的标记
136 | BOOL stop = NO;
137 |
138 | // 3.当前正在遍历的类
139 | Class c = self;
140 |
141 | // 4.开始遍历每一个类
142 | while (c && !stop) {
143 | // 4.1.执行操作
144 | enumeration(c, &stop);
145 |
146 | // 4.2.获得父类
147 | c = class_getSuperclass(c);
148 | }
149 | }
150 |
151 | #pragma mark - 公共方法
152 | + (NSMutableArray *)properties
153 | {
154 | static const char MJCachedPropertiesKey = '\0';
155 |
156 | // 获得成员变量
157 | // 通过关联对象,以及提前定义好的MJCachedPropertiesKey来进行运行时,对所有属性的获取。
158 |
159 | //***objc_getAssociatedObject 方法用于判断当前是否已经获取过MJCachedPropertiesKey对应的关联对象
160 | // 1> 关联到的对象
161 | // 2> 关联的属性 key
162 | NSMutableArray *cachedProperties = objc_getAssociatedObject(self, &MJCachedPropertiesKey);
163 | //***
164 | if (cachedProperties == nil) {
165 | cachedProperties = [NSMutableArray array];
166 |
167 | /**遍历这个类的父类*/
168 | [self enumerateClasses:^(__unsafe_unretained Class c, BOOL *stop) {
169 | // 1.获得所有的成员变量
170 | unsigned int outCount = 0;
171 | /**
172 | class_copyIvarList 成员变量,提示有很多第三方框架会使用 Ivar,能够获得更多的信息
173 | 但是:在 swift 中,由于语法结构的变化,使用 Ivar 非常不稳定,经常会崩溃!
174 | class_copyPropertyList 属性
175 | class_copyMethodList 方法
176 | class_copyProtocolList 协议
177 | */
178 | objc_property_t *properties = class_copyPropertyList(c, &outCount);
179 |
180 | // 2.遍历每一个成员变量
181 | for (unsigned int i = 0; i 模型
27 | + (instancetype)objectWithKeyValues:(id)keyValues
28 | {
29 | return [self objectWithKeyValues:keyValues error:nil];
30 | }
31 |
32 | + (instancetype)objectWithKeyValues:(id)keyValues error:(NSError *__autoreleasing *)error
33 | {
34 | return [self objectWithKeyValues:keyValues context:nil error:error];
35 | }
36 |
37 | + (instancetype)objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context
38 | {
39 | return [self objectWithKeyValues:keyValues context:context error:nil];
40 | }
41 |
42 | + (instancetype)objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context error:(NSError *__autoreleasing *)error
43 | {
44 | if (keyValues == nil) return nil;
45 | if ([self isSubclassOfClass:[NSManagedObject class]] && context) {
46 | return [[NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass(self) inManagedObjectContext:context] setKeyValues:keyValues context:context error:error];
47 | }
48 | return [[[self alloc] init] setKeyValues:keyValues error:error];
49 | }
50 |
51 | + (instancetype)objectWithFilename:(NSString *)filename
52 | {
53 | return [self objectWithFilename:filename error:nil];
54 | }
55 |
56 | + (instancetype)objectWithFilename:(NSString *)filename error:(NSError *__autoreleasing *)error
57 | {
58 | MJAssertError(filename != nil, nil, error, @"filename参数为nil");
59 |
60 | return [self objectWithFile:[[NSBundle mainBundle] pathForResource:filename ofType:nil] error:error];
61 | }
62 |
63 | + (instancetype)objectWithFile:(NSString *)file
64 | {
65 | return [self objectWithFile:file error:nil];
66 | }
67 |
68 | + (instancetype)objectWithFile:(NSString *)file error:(NSError *__autoreleasing *)error
69 | {
70 | MJAssertError(file != nil, nil, error, @"file参数为nil");
71 |
72 | return [self objectWithKeyValues:[NSDictionary dictionaryWithContentsOfFile:file] error:error];
73 | }
74 |
75 | - (instancetype)setKeyValues:(id)keyValues
76 | {
77 | return [self setKeyValues:keyValues error:nil];
78 | }
79 |
80 | - (instancetype)setKeyValues:(id)keyValues error:(NSError *__autoreleasing *)error
81 | {
82 | return [self setKeyValues:keyValues context:nil error:error];
83 | }
84 |
85 | - (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context
86 | {
87 | return [self setKeyValues:keyValues context:context error:nil];
88 | }
89 |
90 | /**
91 | 核心代码:
92 | */
93 | - (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context error:(NSError *__autoreleasing *)error
94 | {
95 | // 如果是JSON字符串
96 | if ([keyValues isKindOfClass:[NSString class]]) {
97 | keyValues = [((NSString *)keyValues) JSONObject];
98 | } else if ([keyValues isKindOfClass:[NSData class]]) {
99 | keyValues = [NSJSONSerialization JSONObjectWithData:keyValues options:kNilOptions error:nil];
100 | }
101 |
102 | MJAssertError([keyValues isKindOfClass:[NSDictionary class]], self, error, @"keyValues参数不是一个字典");
103 |
104 | @try {
105 | Class aClass = [self class];
106 | NSArray *allowedPropertyNames = [aClass totalAllowedPropertyNames];
107 | NSArray *ignoredPropertyNames = [aClass totalIgnoredPropertyNames];
108 |
109 | //通过封装的方法回调一个通过运行时编写的,用于返回属性列表的方法。
110 | [aClass enumerateProperties:^(MJProperty *property, BOOL *stop) {
111 | // 0.检测是否被忽略
112 | if (allowedPropertyNames.count && ![allowedPropertyNames containsObject:property.name]) return;
113 | if ([ignoredPropertyNames containsObject:property.name]) return;
114 |
115 | // 1.取出属性值
116 | id value = keyValues ;
117 | NSArray *keys = [property keysFromClass:[self class]];
118 | for (NSString *key in keys) {
119 | if (![value isKindOfClass:[NSDictionary class]]) continue;
120 | value = value[key];
121 | }
122 |
123 | // 值的过滤
124 | if ([self respondsToSelector:@selector(newValueFromOldValue:property:)]) {
125 | value = [self newValueFromOldValue:value property:property];
126 | } else {
127 | id newValue = [aClass getNewValueFormOldValue:value object:self property:property];
128 | if (newValue) value = newValue;
129 | }
130 |
131 | if (!value || value == [NSNull null]) return;
132 |
133 | // 2.如果是模型属性
134 | MJType *type = property.type;
135 | Class typeClass = type.typeClass;
136 | Class objectClass = [property objectClassInArrayFromClass:[self class]];
137 | if (!type.isFromFoundation && typeClass) {
138 | value = [typeClass objectWithKeyValues:value context:context error:error];
139 | } else if (objectClass) {
140 | // 3.字典数组-->模型数组
141 | value = [objectClass objectArrayWithKeyValuesArray:value context:context error:error];
142 | } else if (typeClass == [NSString class]) {
143 | if ([value isKindOfClass:[NSNumber class]]) {
144 | // NSNumber -> NSString
145 | value = [value description];
146 | } else if ([value isKindOfClass:[NSURL class]]) {
147 | // NSURL -> NSString
148 | value = [value absoluteString];
149 | }
150 | } else if ([value isKindOfClass:[NSString class]]) {
151 | if (typeClass == [NSURL class]) {
152 | // NSString -> NSURL
153 | // 字符串转码
154 | value = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)value,(CFStringRef)@"!$&'()*+,-./:;=?@_~%#[]", NULL,kCFStringEncodingUTF8));
155 | value = [NSURL URLWithString:value];
156 | } else if (type.isNumberType) {
157 | NSString *oldValue = value;
158 |
159 | // NSString -> NSNumber
160 | value = [_numberFormatter numberFromString:oldValue];
161 |
162 | // 如果是BOOL
163 | if ([type.code isEqualToString:MJTypeBOOL]) {
164 | // 字符串转BOOL(字符串没有charValue方法)
165 | // 系统会调用字符串的charValue转为BOOL类型
166 | NSString *lower = [oldValue lowercaseString];
167 | if ([lower isEqualToString:@"yes"] || [lower isEqualToString:@"true"]) {
168 | value = @YES;
169 | } else if ([lower isEqualToString:@"no"] || [lower isEqualToString:@"false"]) {
170 | value = @NO;
171 | }
172 | }
173 | }
174 | }
175 |
176 | // 4.赋值
177 | [property setValue:value forObject:self];
178 | }];
179 |
180 | // 转换完毕
181 | if ([self respondsToSelector:@selector(keyValuesDidFinishConvertingToObject)]) {
182 | [self keyValuesDidFinishConvertingToObject];
183 | }
184 | } @catch (NSException *exception) {
185 | MJBuildError(error, exception.reason);
186 | }
187 | return self;
188 | }
189 |
190 | #pragma mark - 字典数组 -> 模型数组
191 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(NSArray *)keyValuesArray
192 | {
193 | return [self objectArrayWithKeyValuesArray:keyValuesArray error:nil];
194 | }
195 |
196 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(NSArray *)keyValuesArray error:(NSError *__autoreleasing *)error
197 | {
198 | return [self objectArrayWithKeyValuesArray:keyValuesArray context:nil error:error];
199 | }
200 |
201 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context
202 | {
203 | return [self objectArrayWithKeyValuesArray:keyValuesArray context:context error:nil];
204 | }
205 |
206 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context error:(NSError *__autoreleasing *)error
207 | {
208 | // 如果是JSON字符串
209 | if ([keyValuesArray isKindOfClass:[NSString class]]) {
210 | keyValuesArray = [((NSString *)keyValuesArray) JSONObject];
211 | } else if ([keyValuesArray isKindOfClass:[NSData class]]) {
212 | keyValuesArray = [NSJSONSerialization JSONObjectWithData:keyValuesArray options:kNilOptions error:nil];
213 | }
214 |
215 | // 如果数组里面放的是NSString、NSNumber等数据
216 | if ([MJFoundation isClassFromFoundation:self]) return keyValuesArray;
217 |
218 | // 1.判断真实性
219 | MJAssertError([keyValuesArray isKindOfClass:[NSArray class]], nil, error, @"keyValuesArray参数不是一个数组");
220 |
221 | // 2.创建数组
222 | NSMutableArray *modelArray = [NSMutableArray array];
223 |
224 | // 3.遍历
225 | for (NSDictionary *keyValues in keyValuesArray) {
226 | if ([keyValues isKindOfClass:[NSArray class]]){
227 | [modelArray addObject:[self objectArrayWithKeyValuesArray:keyValues context:context error:error]];
228 | } else {
229 | id model = [self objectWithKeyValues:keyValues context:context error:error];
230 | if (model) [modelArray addObject:model];
231 | }
232 | }
233 |
234 | return modelArray;
235 | }
236 |
237 | + (NSMutableArray *)objectArrayWithFilename:(NSString *)filename
238 | {
239 | return [self objectArrayWithFilename:filename error:nil];
240 | }
241 |
242 | + (NSMutableArray *)objectArrayWithFilename:(NSString *)filename error:(NSError *__autoreleasing *)error
243 | {
244 | MJAssertError(filename != nil, nil, error, @"filename参数为nil");
245 |
246 | return [self objectArrayWithFile:[[NSBundle mainBundle] pathForResource:filename ofType:nil] error:error];
247 | }
248 |
249 | + (NSMutableArray *)objectArrayWithFile:(NSString *)file
250 | {
251 | return [self objectArrayWithFile:file error:nil];
252 | }
253 |
254 | + (NSMutableArray *)objectArrayWithFile:(NSString *)file error:(NSError *__autoreleasing *)error
255 | {
256 | MJAssertError(file != nil, nil, error, @"file参数为nil");
257 |
258 | return [self objectArrayWithKeyValuesArray:[NSArray arrayWithContentsOfFile:file] error:error];
259 | }
260 |
261 | #pragma mark - 模型 -> 字典
262 | - (NSMutableDictionary *)keyValues
263 | {
264 | return [self keyValuesWithError:nil];
265 | }
266 |
267 | - (NSMutableDictionary *)keyValuesWithError:(NSError *__autoreleasing *)error
268 | {
269 | return [self keyValuesWithIgnoredKeys:nil error:error];
270 | }
271 |
272 | - (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys
273 | {
274 | return [self keyValuesWithKeys:keys error:nil];
275 | }
276 |
277 | - (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys
278 | {
279 | return [self keyValuesWithIgnoredKeys:ignoredKeys error:nil];
280 | }
281 |
282 | - (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys error:(NSError *__autoreleasing *)error
283 | {
284 | return [self keyValuesWithKeys:keys ignoredKeys:nil error:error];
285 | }
286 |
287 | - (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys error:(NSError *__autoreleasing *)error
288 | {
289 | return [self keyValuesWithKeys:nil ignoredKeys:ignoredKeys error:error];
290 | }
291 |
292 | - (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys ignoredKeys:(NSArray *)ignoredKeys error:(NSError *__autoreleasing *)error
293 | {
294 | // 如果自己不是模型类
295 | if ([MJFoundation isClassFromFoundation:[self class]]) return (NSMutableDictionary *)self;
296 |
297 | __block NSMutableDictionary *keyValues = [NSMutableDictionary dictionary];
298 |
299 | @try {
300 | Class aClass = [self class];
301 | NSArray *allowedPropertyNames = [aClass totalAllowedPropertyNames];
302 | NSArray *ignoredPropertyNames = [aClass totalIgnoredPropertyNames];
303 |
304 | [aClass enumerateProperties:^(MJProperty *property, BOOL *stop) {
305 | // 0.检测是否被忽略
306 | if (allowedPropertyNames.count && ![allowedPropertyNames containsObject:property.name]) return;
307 | if ([ignoredPropertyNames containsObject:property.name]) return;
308 | if (keys.count && ![keys containsObject:property.name]) return;
309 | if ([ignoredKeys containsObject:property.name]) return;
310 |
311 | // 1.取出属性值
312 | id value = [property valueFromObject:self];
313 | if (!value) return;
314 |
315 | // 2.如果是模型属性
316 | MJType *type = property.type;
317 | Class typeClass = type.typeClass;
318 | Class objectClass = [property objectClassInArrayFromClass:[self class]];
319 | if (!type.isFromFoundation && typeClass) {
320 | value = [value keyValues];
321 | } else if (objectClass) {
322 | // 3.处理数组里面有模型的情况
323 | value = [objectClass keyValuesArrayWithObjectArray:value];
324 | } else if (typeClass == [NSURL class]) {
325 | value = [value absoluteString];
326 | }
327 |
328 | // 4.赋值
329 | NSArray *keys = [property keysFromClass:[self class]];
330 | NSUInteger keyCount = keys.count;
331 | // 创建字典
332 | __block NSMutableDictionary *innerDict = keyValues;
333 | [keys enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) {
334 | if (idx == keyCount - 1) { // 最后一个属性
335 | innerDict[key] = value;
336 | } else { // 字典
337 | NSMutableDictionary *tempDict = innerDict[key];
338 | if (tempDict == nil) {
339 | tempDict = [NSMutableDictionary dictionary];
340 | innerDict[key] = tempDict;
341 | }
342 | innerDict = tempDict;
343 | }
344 | }];
345 | }];
346 |
347 | // 去除系统自动增加的元素
348 | [keyValues removeObjectsForKeys:@[@"superclass", @"debugDescription", @"description", @"hash"]];
349 |
350 | // 转换完毕
351 | if ([self respondsToSelector:@selector(objectDidFinishConvertingToKeyValues)]) {
352 | [self objectDidFinishConvertingToKeyValues];
353 | }
354 | } @catch (NSException *exception) {
355 | MJBuildError(error, exception.reason);
356 | }
357 |
358 | return keyValues;
359 | }
360 | #pragma mark - 模型数组 -> 字典数组
361 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray
362 | {
363 | return [self keyValuesArrayWithObjectArray:objectArray error:nil];
364 | }
365 |
366 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray error:(NSError *__autoreleasing *)error
367 | {
368 | return [self keyValuesArrayWithObjectArray:objectArray ignoredKeys:nil error:error];
369 | }
370 |
371 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys
372 | {
373 | return [self keyValuesArrayWithObjectArray:objectArray keys:keys error:nil];
374 | }
375 |
376 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys
377 | {
378 | return [self keyValuesArrayWithObjectArray:objectArray ignoredKeys:ignoredKeys error:nil];
379 | }
380 |
381 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys error:(NSError *__autoreleasing *)error
382 | {
383 | return [self keyValuesArrayWithObjectArray:objectArray keys:keys ignoredKeys:nil error:error];
384 | }
385 |
386 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys error:(NSError *__autoreleasing *)error
387 | {
388 | return [self keyValuesArrayWithObjectArray:objectArray keys:nil ignoredKeys:ignoredKeys error:error];
389 | }
390 |
391 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys ignoredKeys:(NSArray *)ignoredKeys error:(NSError *__autoreleasing *)error
392 | {
393 | // 0.判断真实性
394 | MJAssertError([objectArray isKindOfClass:[NSArray class]], nil, error, @"objectArray参数不是一个数组");
395 |
396 | // 1.创建数组
397 | NSMutableArray *keyValuesArray = [NSMutableArray array];
398 | for (id object in objectArray) {
399 | if (keys) {
400 | [keyValuesArray addObject:[object keyValuesWithKeys:keys error:error]];
401 | } else {
402 | [keyValuesArray addObject:[object keyValuesWithIgnoredKeys:ignoredKeys error:error]];
403 | }
404 | }
405 | return keyValuesArray;
406 | }
407 |
408 | #pragma mark - 转换为JSON
409 | - (NSData *)JSONData
410 | {
411 | if ([self isKindOfClass:[NSString class]]) {
412 | return [((NSString *)self) dataUsingEncoding:NSUTF8StringEncoding];
413 | }
414 |
415 | return [NSJSONSerialization dataWithJSONObject:[self JSONObject] options:kNilOptions error:nil];
416 | }
417 |
418 | - (id)JSONObject
419 | {
420 | if ([self isKindOfClass:[NSString class]]) {
421 | return [NSJSONSerialization JSONObjectWithData:[((NSString *)self) dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];
422 | }
423 |
424 | return self.keyValues;
425 | }
426 |
427 | - (NSString *)JSONString
428 | {
429 | if ([self isKindOfClass:[NSString class]]) {
430 | return (NSString *)self;
431 | }
432 |
433 | return [[NSString alloc] initWithData:[self JSONData] encoding:NSUTF8StringEncoding];
434 | }
435 | @end
436 |
--------------------------------------------------------------------------------
/Class/Logic/RMCalendarLogic.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMCalendarLogic.m
3 | // RMCalendar
4 | //
5 | // Created by 迟浩东 on 15/7/15.
6 | // Copyright © 2015年 迟浩东(http://www.ruanman.net). All rights reserved.
7 | //
8 |
9 | #import "RMCalendarLogic.h"
10 | #import "NSDate+RMCalendarLogic.h"
11 | #import "TicketModel.h"
12 |
13 | @interface RMCalendarLogic()
14 |
15 | /**
16 | * 今天的日期
17 | */
18 | @property (nonatomic, strong) NSDate *today;
19 | /**
20 | * 之后的日期
21 | */
22 | @property (nonatomic, strong) NSDate *before;
23 | /**
24 | * 选中的日期
25 | */
26 | @property (nonatomic, strong) NSDate *select;
27 | /**
28 | * 日期模型
29 | */
30 | @property (nonatomic, strong) RMCalendarModel *model;
31 | /**
32 | * 价格模型数组
33 | */
34 | @property (nonatomic, strong) NSArray *priceModelArr;
35 |
36 | @property (nonatomic, assign) BOOL isEnable;
37 |
38 | @property (nonatomic, assign) BOOL isDisplayChineseCalender;
39 |
40 | @end
41 |
42 | @implementation RMCalendarLogic
43 |
44 | #warning 初始化 模型数组,可根据功能进行修改
45 | - (NSArray *)priceModelArr {
46 | if (!_priceModelArr) {
47 | _priceModelArr = [NSArray array];
48 | }
49 | return _priceModelArr;
50 | }
51 |
52 | -(NSMutableArray *)reloadCalendarView:(NSDate *)date selectDate:(NSDate *)selectDate needDays:(int)days showType:(CalendarShowType)type isEnable:(BOOL)isEnable priceModelArr:(NSArray *)arr isChineseCalendar:(BOOL)isChineseCalendar {
53 | self.isDisplayChineseCalender = isChineseCalendar;
54 | return [self reloadCalendarView:date selectDate:selectDate needDays:days showType:type isEnable:isEnable priceModelArr:arr];
55 | }
56 |
57 | -(NSMutableArray *)reloadCalendarView:(NSDate *)date selectDate:(NSDate *)selectDate needDays:(int)days showType:(CalendarShowType)type isEnable:(BOOL)isEnable priceModelArr:(NSArray *)arr {
58 | self.isEnable = isEnable;
59 | return [self reloadCalendarView:date selectDate:selectDate needDays:days showType:type priceModelArr:arr];
60 | }
61 |
62 | -(NSMutableArray *)reloadCalendarView:(NSDate *)date selectDate:(NSDate *)selectDate needDays:(int)days showType:(CalendarShowType)type priceModelArr:(NSArray *)arr {
63 | #warning 此处根据自己需求可修改
64 | // 存放价格模型
65 | self.priceModelArr = arr;
66 | return [self reloadCalendarView:date selectDate:selectDate needDays:days showType:type];
67 | }
68 |
69 | - (NSMutableArray *)reloadCalendarView:(NSDate *)date selectDate:(NSDate *)selectDate needDays:(int)days showType:(CalendarShowType)type {
70 | //如果为空就从当天的日期开始
71 | if(date == nil){
72 | date = [NSDate date];
73 | }
74 |
75 | //默认选择中的时间
76 | if (selectDate == nil) {
77 | selectDate = date;
78 | }
79 |
80 | self.today = date;//起始日期
81 |
82 | self.before = [date dayInTheFollowingDay:days];//计算它days天以后的时间
83 |
84 | self.select = selectDate;//选择的日期
85 |
86 | NSDateComponents *todayDC= [self.today YMDComponents];
87 |
88 | NSDateComponents *beforeDC= [self.before YMDComponents];
89 |
90 | NSInteger todayYear = todayDC.year;
91 |
92 | NSInteger todayMonth = todayDC.month;
93 |
94 | NSInteger beforeYear = beforeDC.year;
95 |
96 | NSInteger beforeMonth = beforeDC.month;
97 |
98 | NSInteger months = (beforeYear-todayYear) * 12 + (beforeMonth - todayMonth);
99 |
100 | NSMutableArray *calendarMonth = [[NSMutableArray alloc]init];//每个月的dayModel数组
101 |
102 | if (type == CalendarShowTypeSingle) {
103 | months = 0;
104 | }
105 |
106 | for (int i = 0; i <= months; i++) {
107 |
108 | NSDate *month = [self.today dayInTheFollowingMonth:i];
109 | NSMutableArray *calendarDays = [[NSMutableArray alloc]init];
110 | [self calculateDaysInPreviousMonthWithDate:month andArray:calendarDays];
111 | [self calculateDaysInCurrentMonthWithDate:month andArray:calendarDays];
112 | if (type == CalendarShowTypeMultiple) {
113 | [self calculateDaysInFollowingMonthWithDate:month andArray:calendarDays];//计算下月份的天数
114 | }
115 |
116 | // [self calculateDaysIsWeekendandArray:calendarDays];
117 |
118 | [calendarMonth insertObject:calendarDays atIndex:i];
119 | }
120 |
121 | return calendarMonth;
122 | }
123 |
124 | //计算上月份的天数
125 |
126 | - (NSMutableArray *)calculateDaysInPreviousMonthWithDate:(NSDate *)date andArray:(NSMutableArray *)array
127 | {
128 | NSUInteger weeklyOrdinality = [[date firstDayOfCurrentMonth] weeklyOrdinality];//计算这个的第一天是礼拜几,并转为int型
129 | NSDate *dayInThePreviousMonth = [date dayInThePreviousMonth];//上一个月的NSDate对象
130 | int daysCount = (int)[dayInThePreviousMonth numberOfDaysInCurrentMonth];//计算上个月有多少天
131 | int partialDaysCount = (int)weeklyOrdinality - 1;//获取上月在这个月的日历上显示的天数
132 | NSDateComponents *components = [dayInThePreviousMonth YMDComponents];//获取年月日对象
133 |
134 | for (int i = daysCount - partialDaysCount + 1; i < daysCount + 1; ++i) {
135 |
136 | RMCalendarModel *calendarDay = [RMCalendarModel calendarWithYear:components.year month:components.month day:i];
137 | calendarDay.style = CellDayTypeEmpty;//不显示
138 | calendarDay.isChineseCalendar = self.isDisplayChineseCalender; //此处需要赋值 农历是否展现 否则点击时产生错位
139 | [array addObject:calendarDay];
140 | }
141 |
142 |
143 | return NULL;
144 | }
145 |
146 |
147 |
148 | //计算下月份的天数
149 |
150 | - (void)calculateDaysInFollowingMonthWithDate:(NSDate *)date andArray:(NSMutableArray *)array
151 | {
152 | NSUInteger weeklyOrdinality = [[date lastDayOfCurrentMonth] weeklyOrdinality];
153 | if (weeklyOrdinality == 7) return ;
154 |
155 | NSUInteger partialDaysCount = 7 - weeklyOrdinality;
156 | NSDateComponents *components = [[date dayInTheFollowingMonth] YMDComponents];
157 |
158 | for (int i = 1; i < partialDaysCount + 1; ++i) {
159 | RMCalendarModel *calendarDay = [RMCalendarModel calendarWithYear:components.year month:components.month day:i];
160 | calendarDay.style = CellDayTypeEmpty;
161 | calendarDay.isChineseCalendar = self.isDisplayChineseCalender; //此处需要赋值 农历是否展现 否则点击时产生错位
162 | [array addObject:calendarDay];
163 | }
164 | }
165 |
166 |
167 | //计算当月的天数
168 |
169 | - (void)calculateDaysInCurrentMonthWithDate:(NSDate *)date andArray:(NSMutableArray *)array
170 | {
171 |
172 | NSUInteger daysCount = [date numberOfDaysInCurrentMonth];//计算这个月有多少天
173 | NSDateComponents *components = [date YMDComponents];//今天日期的年月日
174 |
175 | for (int i = 1; i < daysCount + 1; ++i) {
176 | RMCalendarModel *calendarDay = [RMCalendarModel calendarWithYear:components.year month:components.month day:i];
177 | calendarDay.week = [[calendarDay date]getWeekIntValueWithDate];
178 | calendarDay.isChineseCalendar = self.isDisplayChineseCalender; //此处需要赋值 农历是否展现 否则点击时产生错位
179 | if (self.isDisplayChineseCalender) {
180 | calendarDay.Chinese_calendar = [self LunarForSolarYear:components.year Month:components.month Day:i];
181 | [self LunarForSolarYear:calendarDay];
182 | }
183 | [self changStyle:calendarDay];
184 | [array addObject:calendarDay];
185 | }
186 | }
187 |
188 |
189 |
190 |
191 | - (void)changStyle:(RMCalendarModel *)model
192 | {
193 |
194 | NSDateComponents *calendarToDay = [self.today YMDComponents];//今天
195 | NSDateComponents *calendarbefore = [self.before YMDComponents];//最后一天
196 | NSDateComponents *calendarSelect = [self.select YMDComponents];//默认选择的那一天
197 | model.isEnable = self.isEnable;
198 |
199 | //被点击选中
200 | if(calendarSelect.year == model.year &
201 | calendarSelect.month == model.month &
202 | calendarSelect.day == model.day){
203 |
204 | model.style = CellDayTypeClick;
205 | self.model = model;
206 | //没被点击选中
207 | }else{
208 |
209 | //昨天乃至过去的时间设置一个灰度
210 | if (calendarToDay.year >= model.year &
211 | calendarToDay.month >= model.month &
212 | calendarToDay.day > model.day) {
213 |
214 | model.style = CellDayTypePast;
215 |
216 | //之后的时间时间段
217 | }else if (calendarbefore.year <= model.year &
218 | calendarbefore.month <= model.month &
219 | calendarbefore.day <= model.day) {
220 |
221 | model.style = CellDayTypePast;
222 |
223 | //需要正常显示的时间段
224 | }else{
225 |
226 | //周末
227 | if (model.week == 1 || model.week == 7){
228 | model.style = CellDayTypeWeek;
229 |
230 | //工作日
231 | }else{
232 | model.style = CellDayTypeFutur;
233 | }
234 | }
235 | }
236 | #warning for进行模型日期匹配,将价格和日期关联,此处可根据项目需求进行修改
237 | for (int i = 0; i < self.priceModelArr.count; i++) {
238 | TicketModel *tModel = self.priceModelArr[i];
239 | if (tModel.year == model.year &
240 | tModel.month == model.month &
241 | tModel.day == model.day) {
242 | model.ticketModel = tModel;
243 | }
244 | }
245 |
246 |
247 | //===================================
248 | //这里来判断节日
249 | //今天
250 | if (calendarToDay.year == model.year &&
251 | calendarToDay.month == model.month &&
252 | calendarToDay.day == model.day) {
253 | model.holiday = @"今天";
254 | //明天
255 | // }else if(calendarToDay.year == calendarDay.year &&
256 | // calendarToDay.month == calendarDay.month &&
257 | // calendarToDay.day - calendarDay.day == -1){
258 | // calendarDay.holiday = @"明天";
259 | //
260 | // //后天
261 | // }else if(calendarToDay.year == calendarDay.year &&
262 | // calendarToDay.month == calendarDay.month &&
263 | // calendarToDay.day - calendarDay.day == -2){
264 | // calendarDay.holiday = @"后天";
265 | //1.1元旦
266 | }else if (model.month == 1 &&
267 | model.day == 1){
268 | model.holiday = @"元旦";
269 |
270 | //2.14情人节
271 | }else if (model.month == 2 &&
272 | model.day == 14){
273 | model.holiday = @"情人节";
274 |
275 | //3.8妇女节
276 | }else if (model.month == 3 &&
277 | model.day == 8){
278 | model.holiday = @"妇女节";
279 |
280 | //5.1劳动节
281 | }else if (model.month == 5 &&
282 | model.day == 1){
283 | model.holiday = @"劳动节";
284 |
285 | //6.1儿童节
286 | }else if (model.month == 6 &&
287 | model.day == 1){
288 | model.holiday = @"儿童节";
289 |
290 | //8.1建军节
291 | }else if (model.month == 8 &&
292 | model.day == 1){
293 | model.holiday = @"建军节";
294 |
295 | //9.10教师节
296 | }else if (model.month == 9 &&
297 | model.day == 10){
298 | model.holiday = @"教师节";
299 |
300 | //10.1国庆节
301 | }else if (model.month == 10 &&
302 | model.day == 1){
303 | model.holiday = @"国庆节";
304 |
305 | //11.1植树节
306 | }else if (model.month == 11 &&
307 | model.day == 1){
308 | model.holiday = @"植树节";
309 |
310 | //11.11光棍节
311 | }else if (model.month == 11 &&
312 | model.day == 11){
313 | model.holiday = @"光棍节";
314 |
315 | }else{
316 |
317 | // 这里写其它的节日
318 |
319 | }
320 |
321 | }
322 |
323 | #pragma mark - 农历转换函数
324 |
325 | -(void)LunarForSolarYear:(RMCalendarModel *)calendarDay{
326 |
327 | NSString *solarYear = [self LunarForSolarYear:calendarDay.year Month:calendarDay.month Day:calendarDay.day];
328 |
329 | NSArray *solarYear_arr= [solarYear componentsSeparatedByString:@"-"];
330 |
331 | if([solarYear_arr[0]isEqualToString:@"正月"] &&
332 | [solarYear_arr[1]isEqualToString:@"初一"]){
333 |
334 | //正月初一:春节
335 | calendarDay.holiday = @"春节";
336 |
337 | }else if([solarYear_arr[0]isEqualToString:@"正月"] &&
338 | [solarYear_arr[1]isEqualToString:@"十五"]){
339 |
340 |
341 | //正月十五:元宵节
342 | calendarDay.holiday = @"元宵节";
343 |
344 | }else if([solarYear_arr[0]isEqualToString:@"二月"] &&
345 | [solarYear_arr[1]isEqualToString:@"初二"]){
346 |
347 | //二月初二:春龙节(龙抬头)
348 | calendarDay.holiday = @"龙抬头";
349 |
350 | }else if([solarYear_arr[0]isEqualToString:@"五月"] &&
351 | [solarYear_arr[1]isEqualToString:@"初五"]){
352 |
353 | //五月初五:端午节
354 | calendarDay.holiday = @"端午节";
355 |
356 | }else if([solarYear_arr[0]isEqualToString:@"七月"] &&
357 | [solarYear_arr[1]isEqualToString:@"初七"]){
358 |
359 | //七月初七:七夕情人节
360 | calendarDay.holiday = @"七夕节";
361 |
362 | }else if([solarYear_arr[0]isEqualToString:@"八月"] &&
363 | [solarYear_arr[1]isEqualToString:@"十五"]){
364 |
365 | //八月十五:中秋节
366 | calendarDay.holiday = @"中秋节";
367 |
368 | }else if([solarYear_arr[0]isEqualToString:@"九月"] &&
369 | [solarYear_arr[1]isEqualToString:@"初九"]){
370 |
371 | //九月初九:重阳节、中国老年节(义务助老活动日)
372 | calendarDay.holiday = @"重阳节";
373 |
374 | }else if([solarYear_arr[0]isEqualToString:@"腊月"] &&
375 | [solarYear_arr[1]isEqualToString:@"初八"]){
376 |
377 | //腊月初八:腊八节
378 | calendarDay.holiday = @"腊八节";
379 |
380 | }else if([solarYear_arr[0]isEqualToString:@"腊月"] &&
381 | [solarYear_arr[1]isEqualToString:@"二十四"]){
382 |
383 |
384 | //腊月二十四 小年
385 | calendarDay.holiday = @"小年";
386 |
387 | }else if([solarYear_arr[0]isEqualToString:@"腊月"] &&
388 | [solarYear_arr[1]isEqualToString:@"三十"]){
389 |
390 | //腊月三十(小月二十九):除夕
391 | calendarDay.holiday = @"除夕";
392 |
393 | }
394 |
395 | if ([solarYear_arr[1] isEqualToString:@"初一"])
396 | {
397 | calendarDay.Chinese_calendar = solarYear_arr[0];
398 | } else {
399 | calendarDay.Chinese_calendar = solarYear_arr[1];
400 | }
401 |
402 |
403 |
404 | }
405 |
406 | -(NSString *)LunarForSolarYear:(NSUInteger)wCurYear Month:(NSInteger)wCurMonth Day:(NSUInteger)wCurDay{
407 |
408 |
409 |
410 | //农历日期名
411 | NSArray *cDayName = [NSArray arrayWithObjects:@"*",@"初一",@"初二",@"初三",@"初四",@"初五",@"初六",@"初七",@"初八",@"初九",@"初十",
412 | @"十一",@"十二",@"十三",@"十四",@"十五",@"十六",@"十七",@"十八",@"十九",@"二十",
413 | @"廿一",@"廿二",@"廿三",@"廿四",@"廿五",@"廿六",@"廿七",@"廿八",@"廿九",@"三十",nil];
414 |
415 | //农历月份名
416 | NSArray *cMonName = [NSArray arrayWithObjects:@"*",@"正月",@"二月",@"三月",@"四月",@"五月",@"六月",@"七月",@"八月",@"九月",@"十月",@"十一月",@"腊月",nil];
417 |
418 | //公历每月前面的天数
419 | const int wMonthAdd[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
420 |
421 | //农历数据
422 | const int wNongliData[100] = {2635,333387,1701,1748,267701,694,2391,133423,1175,396438
423 | ,3402,3749,331177,1453,694,201326,2350,465197,3221,3402
424 | ,400202,2901,1386,267611,605,2349,137515,2709,464533,1738
425 | ,2901,330421,1242,2651,199255,1323,529706,3733,1706,398762
426 | ,2741,1206,267438,2647,1318,204070,3477,461653,1386,2413
427 | ,330077,1197,2637,268877,3365,531109,2900,2922,398042,2395
428 | ,1179,267415,2635,661067,1701,1748,398772,2742,2391,330031
429 | ,1175,1611,200010,3749,527717,1452,2742,332397,2350,3222
430 | ,268949,3402,3493,133973,1386,464219,605,2349,334123,2709
431 | ,2890,267946,2773,592565,1210,2651,395863,1323,2707,265877};
432 |
433 | static int nTheDate,nIsEnd,m,k,n,i,nBit;
434 |
435 |
436 | //计算到初始时间1921年2月8日的天数:1921-2-8(正月初一)
437 | nTheDate = (int)((wCurYear - 1921) * 365 + (wCurYear - 1921) / 4 + wCurDay + wMonthAdd[wCurMonth - 1] - 38);
438 |
439 | if((!(wCurYear % 4)) && (wCurMonth > 2))
440 | nTheDate = nTheDate + 1;
441 |
442 | //计算农历天干、地支、月、日
443 | nIsEnd = 0;
444 | m = 0;
445 | while(nIsEnd != 1)
446 | {
447 | if(wNongliData[m] < 4095)
448 | k = 11;
449 | else
450 | k = 12;
451 | n = k;
452 | while(n>=0)
453 | {
454 | //获取wNongliData(m)的第n个二进制位的值
455 | nBit = wNongliData[m];
456 | for(i=1;i wNongliData[m] / 65536 + 1)
482 | wCurMonth = wCurMonth - 1;
483 | }
484 |
485 |
486 | //生成农历月
487 | NSString *szNongliMonth;
488 | if (wCurMonth < 1){
489 | szNongliMonth = [NSString stringWithFormat:@"闰%@",(NSString *)[cMonName objectAtIndex:-1 * wCurMonth]];
490 | }else{
491 | szNongliMonth = (NSString *)[cMonName objectAtIndex:wCurMonth];
492 | }
493 |
494 | //生成农历日
495 | NSString *szNongliDay = [cDayName objectAtIndex:wCurDay];
496 |
497 | //合并
498 | NSString *lunarDate = [NSString stringWithFormat:@"%@-%@",szNongliMonth,szNongliDay];
499 |
500 | return lunarDate;
501 | }
502 |
503 |
504 |
505 |
506 | - (void)selectLogic:(RMCalendarModel *)dayModel
507 | {
508 |
509 | if (dayModel.style == CellDayTypeClick) {
510 | return;
511 | }
512 |
513 | dayModel.style = CellDayTypeClick;
514 | //周末
515 | if (self.model.week == 1 || self.model.week == 7){
516 | self.model.style = CellDayTypeWeek;
517 |
518 | //工作日
519 | }else{
520 | self.model.style = CellDayTypeFutur;
521 | }
522 | self.model = dayModel;
523 | }
524 |
525 |
526 | @end
527 |
--------------------------------------------------------------------------------
/RMCalendar.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | EE4A4FF51B43E881004B6590 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = EE4A4FF41B43E881004B6590 /* main.m */; };
11 | EE4A4FF81B43E881004B6590 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EE4A4FF71B43E881004B6590 /* AppDelegate.m */; };
12 | EE4A4FFB1B43E881004B6590 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EE4A4FFA1B43E881004B6590 /* ViewController.m */; };
13 | EE4A4FFE1B43E881004B6590 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EE4A4FFC1B43E881004B6590 /* Main.storyboard */; };
14 | EE4A50001B43E881004B6590 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EE4A4FFF1B43E881004B6590 /* Images.xcassets */; };
15 | EE4A50031B43E881004B6590 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = EE4A50011B43E881004B6590 /* LaunchScreen.xib */; };
16 | EE4A500F1B43E881004B6590 /* RMCalendarTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EE4A500E1B43E881004B6590 /* RMCalendarTests.m */; };
17 | EE4A503B1B43E8EF004B6590 /* NSDate+RMCalendarLogic.m in Sources */ = {isa = PBXBuildFile; fileRef = EE4A501B1B43E8EF004B6590 /* NSDate+RMCalendarLogic.m */; };
18 | EE4A503C1B43E8EF004B6590 /* UIView+CustomFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = EE4A501D1B43E8EF004B6590 /* UIView+CustomFrame.m */; };
19 | EE4A503D1B43E8EF004B6590 /* RMCalendarController.m in Sources */ = {isa = PBXBuildFile; fileRef = EE4A50201B43E8EF004B6590 /* RMCalendarController.m */; };
20 | EE4A503E1B43E8EF004B6590 /* RMCalendarLogic.m in Sources */ = {isa = PBXBuildFile; fileRef = EE4A50231B43E8EF004B6590 /* RMCalendarLogic.m */; };
21 | EE4A503F1B43E8EF004B6590 /* RMCalendarModel.m in Sources */ = {isa = PBXBuildFile; fileRef = EE4A50261B43E8EF004B6590 /* RMCalendarModel.m */; };
22 | EE4A50401B43E8EF004B6590 /* CalendarDisableDate.png in Resources */ = {isa = PBXBuildFile; fileRef = EE4A50281B43E8EF004B6590 /* CalendarDisableDate.png */; };
23 | EE4A50411B43E8EF004B6590 /* CalendarNormalDate.png in Resources */ = {isa = PBXBuildFile; fileRef = EE4A50291B43E8EF004B6590 /* CalendarNormalDate.png */; };
24 | EE4A50421B43E8EF004B6590 /* CalendarPreviousMonth.png in Resources */ = {isa = PBXBuildFile; fileRef = EE4A502A1B43E8EF004B6590 /* CalendarPreviousMonth.png */; };
25 | EE4A50431B43E8EF004B6590 /* CalendarPreviousMonth@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EE4A502B1B43E8EF004B6590 /* CalendarPreviousMonth@2x.png */; };
26 | EE4A50441B43E8EF004B6590 /* CalendarRow.png in Resources */ = {isa = PBXBuildFile; fileRef = EE4A502C1B43E8EF004B6590 /* CalendarRow.png */; };
27 | EE4A50451B43E8EF004B6590 /* CalendarRow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EE4A502D1B43E8EF004B6590 /* CalendarRow@2x.png */; };
28 | EE4A50461B43E8EF004B6590 /* CalendarRowBottom.png in Resources */ = {isa = PBXBuildFile; fileRef = EE4A502E1B43E8EF004B6590 /* CalendarRowBottom.png */; };
29 | EE4A50471B43E8EF004B6590 /* CalendarRowBottom@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EE4A502F1B43E8EF004B6590 /* CalendarRowBottom@2x.png */; };
30 | EE4A50481B43E8EF004B6590 /* CalendarSelectedDate.png in Resources */ = {isa = PBXBuildFile; fileRef = EE4A50301B43E8EF004B6590 /* CalendarSelectedDate.png */; };
31 | EE4A50491B43E8EF004B6590 /* CalendarSelectedDate@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EE4A50311B43E8EF004B6590 /* CalendarSelectedDate@2x.png */; };
32 | EE4A504A1B43E8EF004B6590 /* CalendarTodaysDate.png in Resources */ = {isa = PBXBuildFile; fileRef = EE4A50321B43E8EF004B6590 /* CalendarTodaysDate.png */; };
33 | EE4A504B1B43E8EF004B6590 /* CalendarTodaysDate@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EE4A50331B43E8EF004B6590 /* CalendarTodaysDate@2x.png */; };
34 | EE4A504C1B43E8EF004B6590 /* RMCalendarCollectionViewLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = EE4A50361B43E8EF004B6590 /* RMCalendarCollectionViewLayout.m */; };
35 | EE4A504D1B43E8EF004B6590 /* RMCalendarMonthHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = EE4A50381B43E8EF004B6590 /* RMCalendarMonthHeaderView.m */; };
36 | EE4A504E1B43E8EF004B6590 /* RMCollectionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = EE4A503A1B43E8EF004B6590 /* RMCollectionCell.m */; };
37 | EE4A50501B43E902004B6590 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EE4A504F1B43E902004B6590 /* Default-568h@2x.png */; };
38 | EEDB721D1B4A1EA3003F6AC6 /* TicketModel.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDB721C1B4A1EA3003F6AC6 /* TicketModel.m */; };
39 | EEDB72301B4A4A0C003F6AC6 /* MJConst.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDB72201B4A4A0C003F6AC6 /* MJConst.m */; };
40 | EEDB72311B4A4A0C003F6AC6 /* MJFoundation.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDB72231B4A4A0C003F6AC6 /* MJFoundation.m */; };
41 | EEDB72321B4A4A0C003F6AC6 /* MJProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDB72251B4A4A0C003F6AC6 /* MJProperty.m */; };
42 | EEDB72331B4A4A0C003F6AC6 /* MJType.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDB72271B4A4A0C003F6AC6 /* MJType.m */; };
43 | EEDB72341B4A4A0C003F6AC6 /* NSObject+MJCoding.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDB72291B4A4A0C003F6AC6 /* NSObject+MJCoding.m */; };
44 | EEDB72351B4A4A0C003F6AC6 /* NSObject+MJKeyValue.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDB722B1B4A4A0C003F6AC6 /* NSObject+MJKeyValue.m */; };
45 | EEDB72361B4A4A0C003F6AC6 /* NSObject+MJProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDB722D1B4A4A0C003F6AC6 /* NSObject+MJProperty.m */; };
46 | EEDB72371B4A4A0C003F6AC6 /* NSString+MJExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDB722F1B4A4A0C003F6AC6 /* NSString+MJExtension.m */; };
47 | /* End PBXBuildFile section */
48 |
49 | /* Begin PBXContainerItemProxy section */
50 | EE4A50091B43E881004B6590 /* PBXContainerItemProxy */ = {
51 | isa = PBXContainerItemProxy;
52 | containerPortal = EE4A4FE71B43E881004B6590 /* Project object */;
53 | proxyType = 1;
54 | remoteGlobalIDString = EE4A4FEE1B43E881004B6590;
55 | remoteInfo = RMCalendar;
56 | };
57 | /* End PBXContainerItemProxy section */
58 |
59 | /* Begin PBXFileReference section */
60 | EE4A4FEF1B43E881004B6590 /* RMCalendar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RMCalendar.app; sourceTree = BUILT_PRODUCTS_DIR; };
61 | EE4A4FF31B43E881004B6590 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
62 | EE4A4FF41B43E881004B6590 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
63 | EE4A4FF61B43E881004B6590 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
64 | EE4A4FF71B43E881004B6590 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
65 | EE4A4FF91B43E881004B6590 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
66 | EE4A4FFA1B43E881004B6590 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
67 | EE4A4FFD1B43E881004B6590 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
68 | EE4A4FFF1B43E881004B6590 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
69 | EE4A50021B43E881004B6590 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
70 | EE4A50081B43E881004B6590 /* RMCalendarTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RMCalendarTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
71 | EE4A500D1B43E881004B6590 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
72 | EE4A500E1B43E881004B6590 /* RMCalendarTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RMCalendarTests.m; sourceTree = ""; };
73 | EE4A501A1B43E8EF004B6590 /* NSDate+RMCalendarLogic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+RMCalendarLogic.h"; sourceTree = ""; };
74 | EE4A501B1B43E8EF004B6590 /* NSDate+RMCalendarLogic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+RMCalendarLogic.m"; sourceTree = ""; };
75 | EE4A501C1B43E8EF004B6590 /* UIView+CustomFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+CustomFrame.h"; sourceTree = ""; };
76 | EE4A501D1B43E8EF004B6590 /* UIView+CustomFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+CustomFrame.m"; sourceTree = ""; };
77 | EE4A501F1B43E8EF004B6590 /* RMCalendarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMCalendarController.h; sourceTree = ""; };
78 | EE4A50201B43E8EF004B6590 /* RMCalendarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMCalendarController.m; sourceTree = ""; };
79 | EE4A50221B43E8EF004B6590 /* RMCalendarLogic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMCalendarLogic.h; sourceTree = ""; };
80 | EE4A50231B43E8EF004B6590 /* RMCalendarLogic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMCalendarLogic.m; sourceTree = ""; };
81 | EE4A50251B43E8EF004B6590 /* RMCalendarModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMCalendarModel.h; sourceTree = ""; };
82 | EE4A50261B43E8EF004B6590 /* RMCalendarModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMCalendarModel.m; sourceTree = ""; };
83 | EE4A50281B43E8EF004B6590 /* CalendarDisableDate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = CalendarDisableDate.png; sourceTree = ""; };
84 | EE4A50291B43E8EF004B6590 /* CalendarNormalDate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = CalendarNormalDate.png; sourceTree = ""; };
85 | EE4A502A1B43E8EF004B6590 /* CalendarPreviousMonth.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = CalendarPreviousMonth.png; sourceTree = ""; };
86 | EE4A502B1B43E8EF004B6590 /* CalendarPreviousMonth@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "CalendarPreviousMonth@2x.png"; sourceTree = ""; };
87 | EE4A502C1B43E8EF004B6590 /* CalendarRow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = CalendarRow.png; sourceTree = ""; };
88 | EE4A502D1B43E8EF004B6590 /* CalendarRow@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "CalendarRow@2x.png"; sourceTree = ""; };
89 | EE4A502E1B43E8EF004B6590 /* CalendarRowBottom.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = CalendarRowBottom.png; sourceTree = ""; };
90 | EE4A502F1B43E8EF004B6590 /* CalendarRowBottom@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "CalendarRowBottom@2x.png"; sourceTree = ""; };
91 | EE4A50301B43E8EF004B6590 /* CalendarSelectedDate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = CalendarSelectedDate.png; sourceTree = ""; };
92 | EE4A50311B43E8EF004B6590 /* CalendarSelectedDate@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "CalendarSelectedDate@2x.png"; sourceTree = ""; };
93 | EE4A50321B43E8EF004B6590 /* CalendarTodaysDate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = CalendarTodaysDate.png; sourceTree = ""; };
94 | EE4A50331B43E8EF004B6590 /* CalendarTodaysDate@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "CalendarTodaysDate@2x.png"; sourceTree = ""; };
95 | EE4A50351B43E8EF004B6590 /* RMCalendarCollectionViewLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMCalendarCollectionViewLayout.h; sourceTree = ""; };
96 | EE4A50361B43E8EF004B6590 /* RMCalendarCollectionViewLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMCalendarCollectionViewLayout.m; sourceTree = ""; };
97 | EE4A50371B43E8EF004B6590 /* RMCalendarMonthHeaderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMCalendarMonthHeaderView.h; sourceTree = ""; };
98 | EE4A50381B43E8EF004B6590 /* RMCalendarMonthHeaderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMCalendarMonthHeaderView.m; sourceTree = ""; };
99 | EE4A50391B43E8EF004B6590 /* RMCollectionCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMCollectionCell.h; sourceTree = ""; };
100 | EE4A503A1B43E8EF004B6590 /* RMCollectionCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMCollectionCell.m; sourceTree = ""; };
101 | EE4A504F1B43E902004B6590 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; };
102 | EEDB721B1B4A1EA3003F6AC6 /* TicketModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TicketModel.h; sourceTree = ""; };
103 | EEDB721C1B4A1EA3003F6AC6 /* TicketModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TicketModel.m; sourceTree = ""; };
104 | EEDB721F1B4A4A0C003F6AC6 /* MJConst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJConst.h; sourceTree = ""; };
105 | EEDB72201B4A4A0C003F6AC6 /* MJConst.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJConst.m; sourceTree = ""; };
106 | EEDB72211B4A4A0C003F6AC6 /* MJExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJExtension.h; sourceTree = ""; };
107 | EEDB72221B4A4A0C003F6AC6 /* MJFoundation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJFoundation.h; sourceTree = ""; };
108 | EEDB72231B4A4A0C003F6AC6 /* MJFoundation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJFoundation.m; sourceTree = ""; };
109 | EEDB72241B4A4A0C003F6AC6 /* MJProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJProperty.h; sourceTree = ""; };
110 | EEDB72251B4A4A0C003F6AC6 /* MJProperty.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJProperty.m; sourceTree = ""; };
111 | EEDB72261B4A4A0C003F6AC6 /* MJType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJType.h; sourceTree = ""; };
112 | EEDB72271B4A4A0C003F6AC6 /* MJType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJType.m; sourceTree = ""; };
113 | EEDB72281B4A4A0C003F6AC6 /* NSObject+MJCoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+MJCoding.h"; sourceTree = ""; };
114 | EEDB72291B4A4A0C003F6AC6 /* NSObject+MJCoding.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MJCoding.m"; sourceTree = ""; };
115 | EEDB722A1B4A4A0C003F6AC6 /* NSObject+MJKeyValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+MJKeyValue.h"; sourceTree = ""; };
116 | EEDB722B1B4A4A0C003F6AC6 /* NSObject+MJKeyValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MJKeyValue.m"; sourceTree = ""; };
117 | EEDB722C1B4A4A0C003F6AC6 /* NSObject+MJProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+MJProperty.h"; sourceTree = ""; };
118 | EEDB722D1B4A4A0C003F6AC6 /* NSObject+MJProperty.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MJProperty.m"; sourceTree = ""; };
119 | EEDB722E1B4A4A0C003F6AC6 /* NSString+MJExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MJExtension.h"; sourceTree = ""; };
120 | EEDB722F1B4A4A0C003F6AC6 /* NSString+MJExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MJExtension.m"; sourceTree = ""; };
121 | /* End PBXFileReference section */
122 |
123 | /* Begin PBXFrameworksBuildPhase section */
124 | EE4A4FEC1B43E881004B6590 /* Frameworks */ = {
125 | isa = PBXFrameworksBuildPhase;
126 | buildActionMask = 2147483647;
127 | files = (
128 | );
129 | runOnlyForDeploymentPostprocessing = 0;
130 | };
131 | EE4A50051B43E881004B6590 /* Frameworks */ = {
132 | isa = PBXFrameworksBuildPhase;
133 | buildActionMask = 2147483647;
134 | files = (
135 | );
136 | runOnlyForDeploymentPostprocessing = 0;
137 | };
138 | /* End PBXFrameworksBuildPhase section */
139 |
140 | /* Begin PBXGroup section */
141 | EE4A4FE61B43E881004B6590 = {
142 | isa = PBXGroup;
143 | children = (
144 | EE4A4FF11B43E881004B6590 /* RMCalendar */,
145 | EE4A500B1B43E881004B6590 /* RMCalendarTests */,
146 | EE4A4FF01B43E881004B6590 /* Products */,
147 | );
148 | sourceTree = "";
149 | };
150 | EE4A4FF01B43E881004B6590 /* Products */ = {
151 | isa = PBXGroup;
152 | children = (
153 | EE4A4FEF1B43E881004B6590 /* RMCalendar.app */,
154 | EE4A50081B43E881004B6590 /* RMCalendarTests.xctest */,
155 | );
156 | name = Products;
157 | sourceTree = "";
158 | };
159 | EE4A4FF11B43E881004B6590 /* RMCalendar */ = {
160 | isa = PBXGroup;
161 | children = (
162 | EEDB721E1B4A4A0C003F6AC6 /* MJExtension */,
163 | EE4A50181B43E8EF004B6590 /* Class */,
164 | EE4A4FF61B43E881004B6590 /* AppDelegate.h */,
165 | EE4A4FF71B43E881004B6590 /* AppDelegate.m */,
166 | EE4A4FF91B43E881004B6590 /* ViewController.h */,
167 | EE4A4FFA1B43E881004B6590 /* ViewController.m */,
168 | EE4A4FFC1B43E881004B6590 /* Main.storyboard */,
169 | EE4A4FFF1B43E881004B6590 /* Images.xcassets */,
170 | EE4A50011B43E881004B6590 /* LaunchScreen.xib */,
171 | EE4A4FF21B43E881004B6590 /* Supporting Files */,
172 | );
173 | path = RMCalendar;
174 | sourceTree = "";
175 | };
176 | EE4A4FF21B43E881004B6590 /* Supporting Files */ = {
177 | isa = PBXGroup;
178 | children = (
179 | EE4A504F1B43E902004B6590 /* Default-568h@2x.png */,
180 | EE4A4FF31B43E881004B6590 /* Info.plist */,
181 | EE4A4FF41B43E881004B6590 /* main.m */,
182 | );
183 | name = "Supporting Files";
184 | sourceTree = "";
185 | };
186 | EE4A500B1B43E881004B6590 /* RMCalendarTests */ = {
187 | isa = PBXGroup;
188 | children = (
189 | EE4A500E1B43E881004B6590 /* RMCalendarTests.m */,
190 | EE4A500C1B43E881004B6590 /* Supporting Files */,
191 | );
192 | path = RMCalendarTests;
193 | sourceTree = "";
194 | };
195 | EE4A500C1B43E881004B6590 /* Supporting Files */ = {
196 | isa = PBXGroup;
197 | children = (
198 | EE4A500D1B43E881004B6590 /* Info.plist */,
199 | );
200 | name = "Supporting Files";
201 | sourceTree = "";
202 | };
203 | EE4A50181B43E8EF004B6590 /* Class */ = {
204 | isa = PBXGroup;
205 | children = (
206 | EE4A50191B43E8EF004B6590 /* Category */,
207 | EE4A501E1B43E8EF004B6590 /* Controller */,
208 | EE4A50211B43E8EF004B6590 /* Logic */,
209 | EE4A50241B43E8EF004B6590 /* Model */,
210 | EE4A50271B43E8EF004B6590 /* Other */,
211 | EE4A50341B43E8EF004B6590 /* View */,
212 | );
213 | path = Class;
214 | sourceTree = SOURCE_ROOT;
215 | };
216 | EE4A50191B43E8EF004B6590 /* Category */ = {
217 | isa = PBXGroup;
218 | children = (
219 | EE4A501A1B43E8EF004B6590 /* NSDate+RMCalendarLogic.h */,
220 | EE4A501B1B43E8EF004B6590 /* NSDate+RMCalendarLogic.m */,
221 | EE4A501C1B43E8EF004B6590 /* UIView+CustomFrame.h */,
222 | EE4A501D1B43E8EF004B6590 /* UIView+CustomFrame.m */,
223 | );
224 | path = Category;
225 | sourceTree = "";
226 | };
227 | EE4A501E1B43E8EF004B6590 /* Controller */ = {
228 | isa = PBXGroup;
229 | children = (
230 | EE4A501F1B43E8EF004B6590 /* RMCalendarController.h */,
231 | EE4A50201B43E8EF004B6590 /* RMCalendarController.m */,
232 | );
233 | path = Controller;
234 | sourceTree = "";
235 | };
236 | EE4A50211B43E8EF004B6590 /* Logic */ = {
237 | isa = PBXGroup;
238 | children = (
239 | EE4A50221B43E8EF004B6590 /* RMCalendarLogic.h */,
240 | EE4A50231B43E8EF004B6590 /* RMCalendarLogic.m */,
241 | );
242 | path = Logic;
243 | sourceTree = "";
244 | };
245 | EE4A50241B43E8EF004B6590 /* Model */ = {
246 | isa = PBXGroup;
247 | children = (
248 | EE4A50251B43E8EF004B6590 /* RMCalendarModel.h */,
249 | EE4A50261B43E8EF004B6590 /* RMCalendarModel.m */,
250 | EEDB721B1B4A1EA3003F6AC6 /* TicketModel.h */,
251 | EEDB721C1B4A1EA3003F6AC6 /* TicketModel.m */,
252 | );
253 | path = Model;
254 | sourceTree = "";
255 | };
256 | EE4A50271B43E8EF004B6590 /* Other */ = {
257 | isa = PBXGroup;
258 | children = (
259 | EE4A50281B43E8EF004B6590 /* CalendarDisableDate.png */,
260 | EE4A50291B43E8EF004B6590 /* CalendarNormalDate.png */,
261 | EE4A502A1B43E8EF004B6590 /* CalendarPreviousMonth.png */,
262 | EE4A502B1B43E8EF004B6590 /* CalendarPreviousMonth@2x.png */,
263 | EE4A502C1B43E8EF004B6590 /* CalendarRow.png */,
264 | EE4A502D1B43E8EF004B6590 /* CalendarRow@2x.png */,
265 | EE4A502E1B43E8EF004B6590 /* CalendarRowBottom.png */,
266 | EE4A502F1B43E8EF004B6590 /* CalendarRowBottom@2x.png */,
267 | EE4A50301B43E8EF004B6590 /* CalendarSelectedDate.png */,
268 | EE4A50311B43E8EF004B6590 /* CalendarSelectedDate@2x.png */,
269 | EE4A50321B43E8EF004B6590 /* CalendarTodaysDate.png */,
270 | EE4A50331B43E8EF004B6590 /* CalendarTodaysDate@2x.png */,
271 | );
272 | path = Other;
273 | sourceTree = "";
274 | };
275 | EE4A50341B43E8EF004B6590 /* View */ = {
276 | isa = PBXGroup;
277 | children = (
278 | EE4A50351B43E8EF004B6590 /* RMCalendarCollectionViewLayout.h */,
279 | EE4A50361B43E8EF004B6590 /* RMCalendarCollectionViewLayout.m */,
280 | EE4A50371B43E8EF004B6590 /* RMCalendarMonthHeaderView.h */,
281 | EE4A50381B43E8EF004B6590 /* RMCalendarMonthHeaderView.m */,
282 | EE4A50391B43E8EF004B6590 /* RMCollectionCell.h */,
283 | EE4A503A1B43E8EF004B6590 /* RMCollectionCell.m */,
284 | );
285 | path = View;
286 | sourceTree = "";
287 | };
288 | EEDB721E1B4A4A0C003F6AC6 /* MJExtension */ = {
289 | isa = PBXGroup;
290 | children = (
291 | EEDB721F1B4A4A0C003F6AC6 /* MJConst.h */,
292 | EEDB72201B4A4A0C003F6AC6 /* MJConst.m */,
293 | EEDB72211B4A4A0C003F6AC6 /* MJExtension.h */,
294 | EEDB72221B4A4A0C003F6AC6 /* MJFoundation.h */,
295 | EEDB72231B4A4A0C003F6AC6 /* MJFoundation.m */,
296 | EEDB72241B4A4A0C003F6AC6 /* MJProperty.h */,
297 | EEDB72251B4A4A0C003F6AC6 /* MJProperty.m */,
298 | EEDB72261B4A4A0C003F6AC6 /* MJType.h */,
299 | EEDB72271B4A4A0C003F6AC6 /* MJType.m */,
300 | EEDB72281B4A4A0C003F6AC6 /* NSObject+MJCoding.h */,
301 | EEDB72291B4A4A0C003F6AC6 /* NSObject+MJCoding.m */,
302 | EEDB722A1B4A4A0C003F6AC6 /* NSObject+MJKeyValue.h */,
303 | EEDB722B1B4A4A0C003F6AC6 /* NSObject+MJKeyValue.m */,
304 | EEDB722C1B4A4A0C003F6AC6 /* NSObject+MJProperty.h */,
305 | EEDB722D1B4A4A0C003F6AC6 /* NSObject+MJProperty.m */,
306 | EEDB722E1B4A4A0C003F6AC6 /* NSString+MJExtension.h */,
307 | EEDB722F1B4A4A0C003F6AC6 /* NSString+MJExtension.m */,
308 | );
309 | path = MJExtension;
310 | sourceTree = "";
311 | };
312 | /* End PBXGroup section */
313 |
314 | /* Begin PBXNativeTarget section */
315 | EE4A4FEE1B43E881004B6590 /* RMCalendar */ = {
316 | isa = PBXNativeTarget;
317 | buildConfigurationList = EE4A50121B43E881004B6590 /* Build configuration list for PBXNativeTarget "RMCalendar" */;
318 | buildPhases = (
319 | EE4A4FEB1B43E881004B6590 /* Sources */,
320 | EE4A4FEC1B43E881004B6590 /* Frameworks */,
321 | EE4A4FED1B43E881004B6590 /* Resources */,
322 | );
323 | buildRules = (
324 | );
325 | dependencies = (
326 | );
327 | name = RMCalendar;
328 | productName = RMCalendar;
329 | productReference = EE4A4FEF1B43E881004B6590 /* RMCalendar.app */;
330 | productType = "com.apple.product-type.application";
331 | };
332 | EE4A50071B43E881004B6590 /* RMCalendarTests */ = {
333 | isa = PBXNativeTarget;
334 | buildConfigurationList = EE4A50151B43E881004B6590 /* Build configuration list for PBXNativeTarget "RMCalendarTests" */;
335 | buildPhases = (
336 | EE4A50041B43E881004B6590 /* Sources */,
337 | EE4A50051B43E881004B6590 /* Frameworks */,
338 | EE4A50061B43E881004B6590 /* Resources */,
339 | );
340 | buildRules = (
341 | );
342 | dependencies = (
343 | EE4A500A1B43E881004B6590 /* PBXTargetDependency */,
344 | );
345 | name = RMCalendarTests;
346 | productName = RMCalendarTests;
347 | productReference = EE4A50081B43E881004B6590 /* RMCalendarTests.xctest */;
348 | productType = "com.apple.product-type.bundle.unit-test";
349 | };
350 | /* End PBXNativeTarget section */
351 |
352 | /* Begin PBXProject section */
353 | EE4A4FE71B43E881004B6590 /* Project object */ = {
354 | isa = PBXProject;
355 | attributes = {
356 | LastUpgradeCheck = 0640;
357 | ORGANIZATIONNAME = "迟浩东";
358 | TargetAttributes = {
359 | EE4A4FEE1B43E881004B6590 = {
360 | CreatedOnToolsVersion = 6.4;
361 | };
362 | EE4A50071B43E881004B6590 = {
363 | CreatedOnToolsVersion = 6.4;
364 | TestTargetID = EE4A4FEE1B43E881004B6590;
365 | };
366 | };
367 | };
368 | buildConfigurationList = EE4A4FEA1B43E881004B6590 /* Build configuration list for PBXProject "RMCalendar" */;
369 | compatibilityVersion = "Xcode 3.2";
370 | developmentRegion = English;
371 | hasScannedForEncodings = 0;
372 | knownRegions = (
373 | en,
374 | Base,
375 | );
376 | mainGroup = EE4A4FE61B43E881004B6590;
377 | productRefGroup = EE4A4FF01B43E881004B6590 /* Products */;
378 | projectDirPath = "";
379 | projectRoot = "";
380 | targets = (
381 | EE4A4FEE1B43E881004B6590 /* RMCalendar */,
382 | EE4A50071B43E881004B6590 /* RMCalendarTests */,
383 | );
384 | };
385 | /* End PBXProject section */
386 |
387 | /* Begin PBXResourcesBuildPhase section */
388 | EE4A4FED1B43E881004B6590 /* Resources */ = {
389 | isa = PBXResourcesBuildPhase;
390 | buildActionMask = 2147483647;
391 | files = (
392 | EE4A50481B43E8EF004B6590 /* CalendarSelectedDate.png in Resources */,
393 | EE4A4FFE1B43E881004B6590 /* Main.storyboard in Resources */,
394 | EE4A504B1B43E8EF004B6590 /* CalendarTodaysDate@2x.png in Resources */,
395 | EE4A50451B43E8EF004B6590 /* CalendarRow@2x.png in Resources */,
396 | EE4A50031B43E881004B6590 /* LaunchScreen.xib in Resources */,
397 | EE4A50411B43E8EF004B6590 /* CalendarNormalDate.png in Resources */,
398 | EE4A50431B43E8EF004B6590 /* CalendarPreviousMonth@2x.png in Resources */,
399 | EE4A50441B43E8EF004B6590 /* CalendarRow.png in Resources */,
400 | EE4A50491B43E8EF004B6590 /* CalendarSelectedDate@2x.png in Resources */,
401 | EE4A50421B43E8EF004B6590 /* CalendarPreviousMonth.png in Resources */,
402 | EE4A504A1B43E8EF004B6590 /* CalendarTodaysDate.png in Resources */,
403 | EE4A50461B43E8EF004B6590 /* CalendarRowBottom.png in Resources */,
404 | EE4A50401B43E8EF004B6590 /* CalendarDisableDate.png in Resources */,
405 | EE4A50501B43E902004B6590 /* Default-568h@2x.png in Resources */,
406 | EE4A50471B43E8EF004B6590 /* CalendarRowBottom@2x.png in Resources */,
407 | EE4A50001B43E881004B6590 /* Images.xcassets in Resources */,
408 | );
409 | runOnlyForDeploymentPostprocessing = 0;
410 | };
411 | EE4A50061B43E881004B6590 /* Resources */ = {
412 | isa = PBXResourcesBuildPhase;
413 | buildActionMask = 2147483647;
414 | files = (
415 | );
416 | runOnlyForDeploymentPostprocessing = 0;
417 | };
418 | /* End PBXResourcesBuildPhase section */
419 |
420 | /* Begin PBXSourcesBuildPhase section */
421 | EE4A4FEB1B43E881004B6590 /* Sources */ = {
422 | isa = PBXSourcesBuildPhase;
423 | buildActionMask = 2147483647;
424 | files = (
425 | EEDB72341B4A4A0C003F6AC6 /* NSObject+MJCoding.m in Sources */,
426 | EE4A503E1B43E8EF004B6590 /* RMCalendarLogic.m in Sources */,
427 | EEDB72311B4A4A0C003F6AC6 /* MJFoundation.m in Sources */,
428 | EEDB721D1B4A1EA3003F6AC6 /* TicketModel.m in Sources */,
429 | EEDB72351B4A4A0C003F6AC6 /* NSObject+MJKeyValue.m in Sources */,
430 | EE4A503B1B43E8EF004B6590 /* NSDate+RMCalendarLogic.m in Sources */,
431 | EE4A504E1B43E8EF004B6590 /* RMCollectionCell.m in Sources */,
432 | EE4A4FFB1B43E881004B6590 /* ViewController.m in Sources */,
433 | EEDB72371B4A4A0C003F6AC6 /* NSString+MJExtension.m in Sources */,
434 | EE4A4FF81B43E881004B6590 /* AppDelegate.m in Sources */,
435 | EE4A4FF51B43E881004B6590 /* main.m in Sources */,
436 | EE4A503D1B43E8EF004B6590 /* RMCalendarController.m in Sources */,
437 | EE4A503F1B43E8EF004B6590 /* RMCalendarModel.m in Sources */,
438 | EE4A504C1B43E8EF004B6590 /* RMCalendarCollectionViewLayout.m in Sources */,
439 | EEDB72361B4A4A0C003F6AC6 /* NSObject+MJProperty.m in Sources */,
440 | EE4A503C1B43E8EF004B6590 /* UIView+CustomFrame.m in Sources */,
441 | EEDB72331B4A4A0C003F6AC6 /* MJType.m in Sources */,
442 | EE4A504D1B43E8EF004B6590 /* RMCalendarMonthHeaderView.m in Sources */,
443 | EEDB72321B4A4A0C003F6AC6 /* MJProperty.m in Sources */,
444 | EEDB72301B4A4A0C003F6AC6 /* MJConst.m in Sources */,
445 | );
446 | runOnlyForDeploymentPostprocessing = 0;
447 | };
448 | EE4A50041B43E881004B6590 /* Sources */ = {
449 | isa = PBXSourcesBuildPhase;
450 | buildActionMask = 2147483647;
451 | files = (
452 | EE4A500F1B43E881004B6590 /* RMCalendarTests.m in Sources */,
453 | );
454 | runOnlyForDeploymentPostprocessing = 0;
455 | };
456 | /* End PBXSourcesBuildPhase section */
457 |
458 | /* Begin PBXTargetDependency section */
459 | EE4A500A1B43E881004B6590 /* PBXTargetDependency */ = {
460 | isa = PBXTargetDependency;
461 | target = EE4A4FEE1B43E881004B6590 /* RMCalendar */;
462 | targetProxy = EE4A50091B43E881004B6590 /* PBXContainerItemProxy */;
463 | };
464 | /* End PBXTargetDependency section */
465 |
466 | /* Begin PBXVariantGroup section */
467 | EE4A4FFC1B43E881004B6590 /* Main.storyboard */ = {
468 | isa = PBXVariantGroup;
469 | children = (
470 | EE4A4FFD1B43E881004B6590 /* Base */,
471 | );
472 | name = Main.storyboard;
473 | sourceTree = "";
474 | };
475 | EE4A50011B43E881004B6590 /* LaunchScreen.xib */ = {
476 | isa = PBXVariantGroup;
477 | children = (
478 | EE4A50021B43E881004B6590 /* Base */,
479 | );
480 | name = LaunchScreen.xib;
481 | sourceTree = "";
482 | };
483 | /* End PBXVariantGroup section */
484 |
485 | /* Begin XCBuildConfiguration section */
486 | EE4A50101B43E881004B6590 /* Debug */ = {
487 | isa = XCBuildConfiguration;
488 | buildSettings = {
489 | ALWAYS_SEARCH_USER_PATHS = NO;
490 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
491 | CLANG_CXX_LIBRARY = "libc++";
492 | CLANG_ENABLE_MODULES = YES;
493 | CLANG_ENABLE_OBJC_ARC = YES;
494 | CLANG_WARN_BOOL_CONVERSION = YES;
495 | CLANG_WARN_CONSTANT_CONVERSION = YES;
496 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
497 | CLANG_WARN_EMPTY_BODY = YES;
498 | CLANG_WARN_ENUM_CONVERSION = YES;
499 | CLANG_WARN_INT_CONVERSION = YES;
500 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
501 | CLANG_WARN_UNREACHABLE_CODE = YES;
502 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
503 | CODE_SIGN_IDENTITY = "iPhone Developer: Haodong Chi (J2Q67UL82P)";
504 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Haodong Chi (J2Q67UL82P)";
505 | COPY_PHASE_STRIP = NO;
506 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
507 | ENABLE_STRICT_OBJC_MSGSEND = YES;
508 | GCC_C_LANGUAGE_STANDARD = gnu99;
509 | GCC_DYNAMIC_NO_PIC = NO;
510 | GCC_NO_COMMON_BLOCKS = YES;
511 | GCC_OPTIMIZATION_LEVEL = 0;
512 | GCC_PREPROCESSOR_DEFINITIONS = (
513 | "DEBUG=1",
514 | "$(inherited)",
515 | );
516 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
517 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
518 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
519 | GCC_WARN_UNDECLARED_SELECTOR = YES;
520 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
521 | GCC_WARN_UNUSED_FUNCTION = YES;
522 | GCC_WARN_UNUSED_VARIABLE = YES;
523 | IPHONEOS_DEPLOYMENT_TARGET = 8.4;
524 | MTL_ENABLE_DEBUG_INFO = YES;
525 | ONLY_ACTIVE_ARCH = YES;
526 | SDKROOT = iphoneos;
527 | };
528 | name = Debug;
529 | };
530 | EE4A50111B43E881004B6590 /* Release */ = {
531 | isa = XCBuildConfiguration;
532 | buildSettings = {
533 | ALWAYS_SEARCH_USER_PATHS = NO;
534 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
535 | CLANG_CXX_LIBRARY = "libc++";
536 | CLANG_ENABLE_MODULES = YES;
537 | CLANG_ENABLE_OBJC_ARC = YES;
538 | CLANG_WARN_BOOL_CONVERSION = YES;
539 | CLANG_WARN_CONSTANT_CONVERSION = YES;
540 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
541 | CLANG_WARN_EMPTY_BODY = YES;
542 | CLANG_WARN_ENUM_CONVERSION = YES;
543 | CLANG_WARN_INT_CONVERSION = YES;
544 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
545 | CLANG_WARN_UNREACHABLE_CODE = YES;
546 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
547 | CODE_SIGN_IDENTITY = "iPhone Developer: Haodong Chi (J2Q67UL82P)";
548 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
549 | COPY_PHASE_STRIP = NO;
550 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
551 | ENABLE_NS_ASSERTIONS = NO;
552 | ENABLE_STRICT_OBJC_MSGSEND = YES;
553 | GCC_C_LANGUAGE_STANDARD = gnu99;
554 | GCC_NO_COMMON_BLOCKS = YES;
555 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
556 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
557 | GCC_WARN_UNDECLARED_SELECTOR = YES;
558 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
559 | GCC_WARN_UNUSED_FUNCTION = YES;
560 | GCC_WARN_UNUSED_VARIABLE = YES;
561 | IPHONEOS_DEPLOYMENT_TARGET = 8.4;
562 | MTL_ENABLE_DEBUG_INFO = NO;
563 | SDKROOT = iphoneos;
564 | VALIDATE_PRODUCT = YES;
565 | };
566 | name = Release;
567 | };
568 | EE4A50131B43E881004B6590 /* Debug */ = {
569 | isa = XCBuildConfiguration;
570 | buildSettings = {
571 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
572 | INFOPLIST_FILE = RMCalendar/Info.plist;
573 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
574 | PRODUCT_NAME = "$(TARGET_NAME)";
575 | };
576 | name = Debug;
577 | };
578 | EE4A50141B43E881004B6590 /* Release */ = {
579 | isa = XCBuildConfiguration;
580 | buildSettings = {
581 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
582 | INFOPLIST_FILE = RMCalendar/Info.plist;
583 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
584 | PRODUCT_NAME = "$(TARGET_NAME)";
585 | };
586 | name = Release;
587 | };
588 | EE4A50161B43E881004B6590 /* Debug */ = {
589 | isa = XCBuildConfiguration;
590 | buildSettings = {
591 | BUNDLE_LOADER = "$(TEST_HOST)";
592 | FRAMEWORK_SEARCH_PATHS = (
593 | "$(SDKROOT)/Developer/Library/Frameworks",
594 | "$(inherited)",
595 | );
596 | GCC_PREPROCESSOR_DEFINITIONS = (
597 | "DEBUG=1",
598 | "$(inherited)",
599 | );
600 | INFOPLIST_FILE = RMCalendarTests/Info.plist;
601 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
602 | PRODUCT_NAME = "$(TARGET_NAME)";
603 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RMCalendar.app/RMCalendar";
604 | };
605 | name = Debug;
606 | };
607 | EE4A50171B43E881004B6590 /* Release */ = {
608 | isa = XCBuildConfiguration;
609 | buildSettings = {
610 | BUNDLE_LOADER = "$(TEST_HOST)";
611 | FRAMEWORK_SEARCH_PATHS = (
612 | "$(SDKROOT)/Developer/Library/Frameworks",
613 | "$(inherited)",
614 | );
615 | INFOPLIST_FILE = RMCalendarTests/Info.plist;
616 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
617 | PRODUCT_NAME = "$(TARGET_NAME)";
618 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RMCalendar.app/RMCalendar";
619 | };
620 | name = Release;
621 | };
622 | /* End XCBuildConfiguration section */
623 |
624 | /* Begin XCConfigurationList section */
625 | EE4A4FEA1B43E881004B6590 /* Build configuration list for PBXProject "RMCalendar" */ = {
626 | isa = XCConfigurationList;
627 | buildConfigurations = (
628 | EE4A50101B43E881004B6590 /* Debug */,
629 | EE4A50111B43E881004B6590 /* Release */,
630 | );
631 | defaultConfigurationIsVisible = 0;
632 | defaultConfigurationName = Release;
633 | };
634 | EE4A50121B43E881004B6590 /* Build configuration list for PBXNativeTarget "RMCalendar" */ = {
635 | isa = XCConfigurationList;
636 | buildConfigurations = (
637 | EE4A50131B43E881004B6590 /* Debug */,
638 | EE4A50141B43E881004B6590 /* Release */,
639 | );
640 | defaultConfigurationIsVisible = 0;
641 | defaultConfigurationName = Release;
642 | };
643 | EE4A50151B43E881004B6590 /* Build configuration list for PBXNativeTarget "RMCalendarTests" */ = {
644 | isa = XCConfigurationList;
645 | buildConfigurations = (
646 | EE4A50161B43E881004B6590 /* Debug */,
647 | EE4A50171B43E881004B6590 /* Release */,
648 | );
649 | defaultConfigurationIsVisible = 0;
650 | defaultConfigurationName = Release;
651 | };
652 | /* End XCConfigurationList section */
653 | };
654 | rootObject = EE4A4FE71B43E881004B6590 /* Project object */;
655 | }
656 |
--------------------------------------------------------------------------------