├── .gitignore ├── LICENSE ├── MSSCalendar ├── MSSCalendar.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── MSSCalendar │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── MSSCalendar │ ├── MSSCalendarCollectionReusableView.h │ ├── MSSCalendarCollectionReusableView.m │ ├── MSSCalendarCollectionViewCell.h │ ├── MSSCalendarCollectionViewCell.m │ ├── MSSCalendarDefine.h │ ├── MSSCalendarHeaderModel.h │ ├── MSSCalendarHeaderModel.m │ ├── MSSCalendarManager.h │ ├── MSSCalendarManager.m │ ├── MSSCalendarPopView.h │ ├── MSSCalendarPopView.m │ ├── MSSCalendarViewController.h │ ├── MSSCalendarViewController.m │ ├── MSSChineseCalendarManager.h │ ├── MSSChineseCalendarManager.m │ ├── MSSCircleLabel.h │ └── MSSCircleLabel.m │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── README.md └── calendar.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata 19 | 20 | ## Other 21 | *.xccheckout 22 | *.moved-aside 23 | *.xcuserstate 24 | *.xcscmblueprint 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 MSS0306 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 40D3946B1CB2130400ECF20D /* MSSChineseCalendarManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 40D3946A1CB2130400ECF20D /* MSSChineseCalendarManager.m */; }; 11 | 40D3946E1CB23B0700ECF20D /* MSSCalendarHeaderModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 40D3946D1CB23B0700ECF20D /* MSSCalendarHeaderModel.m */; }; 12 | 40D394721CB24D6600ECF20D /* MSSCircleLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 40D394711CB24D6600ECF20D /* MSSCircleLabel.m */; }; 13 | 40D6199B1CC3671400A531EA /* MSSCalendarPopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 40D6199A1CC3671400A531EA /* MSSCalendarPopView.m */; }; 14 | 40F521631CB10EBF006FFA37 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 40F521621CB10EBF006FFA37 /* main.m */; }; 15 | 40F521661CB10EBF006FFA37 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 40F521651CB10EBF006FFA37 /* AppDelegate.m */; }; 16 | 40F521691CB10EBF006FFA37 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 40F521681CB10EBF006FFA37 /* ViewController.m */; }; 17 | 40F5216C1CB10EBF006FFA37 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 40F5216A1CB10EBF006FFA37 /* Main.storyboard */; }; 18 | 40F5216E1CB10EBF006FFA37 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 40F5216D1CB10EBF006FFA37 /* Assets.xcassets */; }; 19 | 40F521711CB10EBF006FFA37 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 40F5216F1CB10EBF006FFA37 /* LaunchScreen.storyboard */; }; 20 | 40F5217B1CB10F52006FFA37 /* MSSCalendarManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 40F5217A1CB10F52006FFA37 /* MSSCalendarManager.m */; }; 21 | 40F521811CB10FB7006FFA37 /* MSSCalendarViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 40F521801CB10FB7006FFA37 /* MSSCalendarViewController.m */; }; 22 | 40F521841CB10FDD006FFA37 /* MSSCalendarCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 40F521831CB10FDD006FFA37 /* MSSCalendarCollectionViewCell.m */; }; 23 | 40F521871CB10FF8006FFA37 /* MSSCalendarCollectionReusableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 40F521861CB10FF8006FFA37 /* MSSCalendarCollectionReusableView.m */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | 40D394691CB2130400ECF20D /* MSSChineseCalendarManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSSChineseCalendarManager.h; sourceTree = ""; }; 28 | 40D3946A1CB2130400ECF20D /* MSSChineseCalendarManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MSSChineseCalendarManager.m; sourceTree = ""; }; 29 | 40D3946C1CB23B0700ECF20D /* MSSCalendarHeaderModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSSCalendarHeaderModel.h; sourceTree = ""; }; 30 | 40D3946D1CB23B0700ECF20D /* MSSCalendarHeaderModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MSSCalendarHeaderModel.m; sourceTree = ""; }; 31 | 40D3946F1CB23FD300ECF20D /* MSSCalendarDefine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MSSCalendarDefine.h; sourceTree = ""; }; 32 | 40D394701CB24D6600ECF20D /* MSSCircleLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSSCircleLabel.h; sourceTree = ""; }; 33 | 40D394711CB24D6600ECF20D /* MSSCircleLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MSSCircleLabel.m; sourceTree = ""; }; 34 | 40D619991CC3671400A531EA /* MSSCalendarPopView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSSCalendarPopView.h; sourceTree = ""; }; 35 | 40D6199A1CC3671400A531EA /* MSSCalendarPopView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MSSCalendarPopView.m; sourceTree = ""; }; 36 | 40F5215E1CB10EBF006FFA37 /* MSSCalendar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MSSCalendar.app; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | 40F521621CB10EBF006FFA37 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 38 | 40F521641CB10EBF006FFA37 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 39 | 40F521651CB10EBF006FFA37 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 40 | 40F521671CB10EBF006FFA37 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 41 | 40F521681CB10EBF006FFA37 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 42 | 40F5216B1CB10EBF006FFA37 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 43 | 40F5216D1CB10EBF006FFA37 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 44 | 40F521701CB10EBF006FFA37 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 45 | 40F521721CB10EBF006FFA37 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 46 | 40F521791CB10F52006FFA37 /* MSSCalendarManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSSCalendarManager.h; sourceTree = ""; }; 47 | 40F5217A1CB10F52006FFA37 /* MSSCalendarManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MSSCalendarManager.m; sourceTree = ""; }; 48 | 40F5217F1CB10FB7006FFA37 /* MSSCalendarViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSSCalendarViewController.h; sourceTree = ""; }; 49 | 40F521801CB10FB7006FFA37 /* MSSCalendarViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MSSCalendarViewController.m; sourceTree = ""; }; 50 | 40F521821CB10FDD006FFA37 /* MSSCalendarCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSSCalendarCollectionViewCell.h; sourceTree = ""; }; 51 | 40F521831CB10FDD006FFA37 /* MSSCalendarCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MSSCalendarCollectionViewCell.m; sourceTree = ""; }; 52 | 40F521851CB10FF8006FFA37 /* MSSCalendarCollectionReusableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSSCalendarCollectionReusableView.h; sourceTree = ""; }; 53 | 40F521861CB10FF8006FFA37 /* MSSCalendarCollectionReusableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MSSCalendarCollectionReusableView.m; sourceTree = ""; }; 54 | /* End PBXFileReference section */ 55 | 56 | /* Begin PBXFrameworksBuildPhase section */ 57 | 40F5215B1CB10EBF006FFA37 /* Frameworks */ = { 58 | isa = PBXFrameworksBuildPhase; 59 | buildActionMask = 2147483647; 60 | files = ( 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | 40F521551CB10EBF006FFA37 = { 68 | isa = PBXGroup; 69 | children = ( 70 | 40F521601CB10EBF006FFA37 /* MSSCalendar */, 71 | 40F5215F1CB10EBF006FFA37 /* Products */, 72 | ); 73 | sourceTree = ""; 74 | }; 75 | 40F5215F1CB10EBF006FFA37 /* Products */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 40F5215E1CB10EBF006FFA37 /* MSSCalendar.app */, 79 | ); 80 | name = Products; 81 | sourceTree = ""; 82 | }; 83 | 40F521601CB10EBF006FFA37 /* MSSCalendar */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | 40F521781CB10F1C006FFA37 /* MSSCalendar */, 87 | 40F521641CB10EBF006FFA37 /* AppDelegate.h */, 88 | 40F521651CB10EBF006FFA37 /* AppDelegate.m */, 89 | 40F521671CB10EBF006FFA37 /* ViewController.h */, 90 | 40F521681CB10EBF006FFA37 /* ViewController.m */, 91 | 40F5216A1CB10EBF006FFA37 /* Main.storyboard */, 92 | 40F5216D1CB10EBF006FFA37 /* Assets.xcassets */, 93 | 40F5216F1CB10EBF006FFA37 /* LaunchScreen.storyboard */, 94 | 40F521721CB10EBF006FFA37 /* Info.plist */, 95 | 40F521611CB10EBF006FFA37 /* Supporting Files */, 96 | ); 97 | path = MSSCalendar; 98 | sourceTree = ""; 99 | }; 100 | 40F521611CB10EBF006FFA37 /* Supporting Files */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 40F521621CB10EBF006FFA37 /* main.m */, 104 | ); 105 | name = "Supporting Files"; 106 | sourceTree = ""; 107 | }; 108 | 40F521781CB10F1C006FFA37 /* MSSCalendar */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 40D3946F1CB23FD300ECF20D /* MSSCalendarDefine.h */, 112 | 40F5217F1CB10FB7006FFA37 /* MSSCalendarViewController.h */, 113 | 40F521801CB10FB7006FFA37 /* MSSCalendarViewController.m */, 114 | 40F521791CB10F52006FFA37 /* MSSCalendarManager.h */, 115 | 40F5217A1CB10F52006FFA37 /* MSSCalendarManager.m */, 116 | 40D394691CB2130400ECF20D /* MSSChineseCalendarManager.h */, 117 | 40D3946A1CB2130400ECF20D /* MSSChineseCalendarManager.m */, 118 | 40D3946C1CB23B0700ECF20D /* MSSCalendarHeaderModel.h */, 119 | 40D3946D1CB23B0700ECF20D /* MSSCalendarHeaderModel.m */, 120 | 40F521821CB10FDD006FFA37 /* MSSCalendarCollectionViewCell.h */, 121 | 40F521831CB10FDD006FFA37 /* MSSCalendarCollectionViewCell.m */, 122 | 40F521851CB10FF8006FFA37 /* MSSCalendarCollectionReusableView.h */, 123 | 40F521861CB10FF8006FFA37 /* MSSCalendarCollectionReusableView.m */, 124 | 40D394701CB24D6600ECF20D /* MSSCircleLabel.h */, 125 | 40D394711CB24D6600ECF20D /* MSSCircleLabel.m */, 126 | 40D619991CC3671400A531EA /* MSSCalendarPopView.h */, 127 | 40D6199A1CC3671400A531EA /* MSSCalendarPopView.m */, 128 | ); 129 | path = MSSCalendar; 130 | sourceTree = ""; 131 | }; 132 | /* End PBXGroup section */ 133 | 134 | /* Begin PBXNativeTarget section */ 135 | 40F5215D1CB10EBF006FFA37 /* MSSCalendar */ = { 136 | isa = PBXNativeTarget; 137 | buildConfigurationList = 40F521751CB10EBF006FFA37 /* Build configuration list for PBXNativeTarget "MSSCalendar" */; 138 | buildPhases = ( 139 | 40F5215A1CB10EBF006FFA37 /* Sources */, 140 | 40F5215B1CB10EBF006FFA37 /* Frameworks */, 141 | 40F5215C1CB10EBF006FFA37 /* Resources */, 142 | ); 143 | buildRules = ( 144 | ); 145 | dependencies = ( 146 | ); 147 | name = MSSCalendar; 148 | productName = MSSCalendar; 149 | productReference = 40F5215E1CB10EBF006FFA37 /* MSSCalendar.app */; 150 | productType = "com.apple.product-type.application"; 151 | }; 152 | /* End PBXNativeTarget section */ 153 | 154 | /* Begin PBXProject section */ 155 | 40F521561CB10EBF006FFA37 /* Project object */ = { 156 | isa = PBXProject; 157 | attributes = { 158 | LastUpgradeCheck = 0720; 159 | ORGANIZATIONNAME = "于威"; 160 | TargetAttributes = { 161 | 40F5215D1CB10EBF006FFA37 = { 162 | CreatedOnToolsVersion = 7.2.1; 163 | DevelopmentTeam = Q6L8ALP6SS; 164 | }; 165 | }; 166 | }; 167 | buildConfigurationList = 40F521591CB10EBF006FFA37 /* Build configuration list for PBXProject "MSSCalendar" */; 168 | compatibilityVersion = "Xcode 3.2"; 169 | developmentRegion = English; 170 | hasScannedForEncodings = 0; 171 | knownRegions = ( 172 | en, 173 | Base, 174 | ); 175 | mainGroup = 40F521551CB10EBF006FFA37; 176 | productRefGroup = 40F5215F1CB10EBF006FFA37 /* Products */; 177 | projectDirPath = ""; 178 | projectRoot = ""; 179 | targets = ( 180 | 40F5215D1CB10EBF006FFA37 /* MSSCalendar */, 181 | ); 182 | }; 183 | /* End PBXProject section */ 184 | 185 | /* Begin PBXResourcesBuildPhase section */ 186 | 40F5215C1CB10EBF006FFA37 /* Resources */ = { 187 | isa = PBXResourcesBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | 40F521711CB10EBF006FFA37 /* LaunchScreen.storyboard in Resources */, 191 | 40F5216E1CB10EBF006FFA37 /* Assets.xcassets in Resources */, 192 | 40F5216C1CB10EBF006FFA37 /* Main.storyboard in Resources */, 193 | ); 194 | runOnlyForDeploymentPostprocessing = 0; 195 | }; 196 | /* End PBXResourcesBuildPhase section */ 197 | 198 | /* Begin PBXSourcesBuildPhase section */ 199 | 40F5215A1CB10EBF006FFA37 /* Sources */ = { 200 | isa = PBXSourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | 40F521691CB10EBF006FFA37 /* ViewController.m in Sources */, 204 | 40F521661CB10EBF006FFA37 /* AppDelegate.m in Sources */, 205 | 40F521841CB10FDD006FFA37 /* MSSCalendarCollectionViewCell.m in Sources */, 206 | 40F521631CB10EBF006FFA37 /* main.m in Sources */, 207 | 40F521871CB10FF8006FFA37 /* MSSCalendarCollectionReusableView.m in Sources */, 208 | 40D3946E1CB23B0700ECF20D /* MSSCalendarHeaderModel.m in Sources */, 209 | 40D3946B1CB2130400ECF20D /* MSSChineseCalendarManager.m in Sources */, 210 | 40F521811CB10FB7006FFA37 /* MSSCalendarViewController.m in Sources */, 211 | 40D394721CB24D6600ECF20D /* MSSCircleLabel.m in Sources */, 212 | 40D6199B1CC3671400A531EA /* MSSCalendarPopView.m in Sources */, 213 | 40F5217B1CB10F52006FFA37 /* MSSCalendarManager.m in Sources */, 214 | ); 215 | runOnlyForDeploymentPostprocessing = 0; 216 | }; 217 | /* End PBXSourcesBuildPhase section */ 218 | 219 | /* Begin PBXVariantGroup section */ 220 | 40F5216A1CB10EBF006FFA37 /* Main.storyboard */ = { 221 | isa = PBXVariantGroup; 222 | children = ( 223 | 40F5216B1CB10EBF006FFA37 /* Base */, 224 | ); 225 | name = Main.storyboard; 226 | sourceTree = ""; 227 | }; 228 | 40F5216F1CB10EBF006FFA37 /* LaunchScreen.storyboard */ = { 229 | isa = PBXVariantGroup; 230 | children = ( 231 | 40F521701CB10EBF006FFA37 /* Base */, 232 | ); 233 | name = LaunchScreen.storyboard; 234 | sourceTree = ""; 235 | }; 236 | /* End PBXVariantGroup section */ 237 | 238 | /* Begin XCBuildConfiguration section */ 239 | 40F521731CB10EBF006FFA37 /* Debug */ = { 240 | isa = XCBuildConfiguration; 241 | buildSettings = { 242 | ALWAYS_SEARCH_USER_PATHS = NO; 243 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 244 | CLANG_CXX_LIBRARY = "libc++"; 245 | CLANG_ENABLE_MODULES = YES; 246 | CLANG_ENABLE_OBJC_ARC = YES; 247 | CLANG_WARN_BOOL_CONVERSION = YES; 248 | CLANG_WARN_CONSTANT_CONVERSION = YES; 249 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 250 | CLANG_WARN_EMPTY_BODY = YES; 251 | CLANG_WARN_ENUM_CONVERSION = YES; 252 | CLANG_WARN_INT_CONVERSION = YES; 253 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 254 | CLANG_WARN_UNREACHABLE_CODE = YES; 255 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 256 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 257 | COPY_PHASE_STRIP = NO; 258 | DEBUG_INFORMATION_FORMAT = dwarf; 259 | ENABLE_STRICT_OBJC_MSGSEND = YES; 260 | ENABLE_TESTABILITY = YES; 261 | GCC_C_LANGUAGE_STANDARD = gnu99; 262 | GCC_DYNAMIC_NO_PIC = NO; 263 | GCC_NO_COMMON_BLOCKS = YES; 264 | GCC_OPTIMIZATION_LEVEL = 0; 265 | GCC_PREPROCESSOR_DEFINITIONS = ( 266 | "DEBUG=1", 267 | "$(inherited)", 268 | ); 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 276 | MTL_ENABLE_DEBUG_INFO = YES; 277 | ONLY_ACTIVE_ARCH = YES; 278 | SDKROOT = iphoneos; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | }; 281 | name = Debug; 282 | }; 283 | 40F521741CB10EBF006FFA37 /* Release */ = { 284 | isa = XCBuildConfiguration; 285 | buildSettings = { 286 | ALWAYS_SEARCH_USER_PATHS = NO; 287 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 288 | CLANG_CXX_LIBRARY = "libc++"; 289 | CLANG_ENABLE_MODULES = YES; 290 | CLANG_ENABLE_OBJC_ARC = YES; 291 | CLANG_WARN_BOOL_CONVERSION = YES; 292 | CLANG_WARN_CONSTANT_CONVERSION = YES; 293 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 294 | CLANG_WARN_EMPTY_BODY = YES; 295 | CLANG_WARN_ENUM_CONVERSION = YES; 296 | CLANG_WARN_INT_CONVERSION = YES; 297 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 298 | CLANG_WARN_UNREACHABLE_CODE = YES; 299 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 300 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 301 | COPY_PHASE_STRIP = NO; 302 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 303 | ENABLE_NS_ASSERTIONS = NO; 304 | ENABLE_STRICT_OBJC_MSGSEND = YES; 305 | GCC_C_LANGUAGE_STANDARD = gnu99; 306 | GCC_NO_COMMON_BLOCKS = YES; 307 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 308 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 309 | GCC_WARN_UNDECLARED_SELECTOR = YES; 310 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 311 | GCC_WARN_UNUSED_FUNCTION = YES; 312 | GCC_WARN_UNUSED_VARIABLE = YES; 313 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 314 | MTL_ENABLE_DEBUG_INFO = NO; 315 | SDKROOT = iphoneos; 316 | TARGETED_DEVICE_FAMILY = "1,2"; 317 | VALIDATE_PRODUCT = YES; 318 | }; 319 | name = Release; 320 | }; 321 | 40F521761CB10EBF006FFA37 /* Debug */ = { 322 | isa = XCBuildConfiguration; 323 | buildSettings = { 324 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 325 | INFOPLIST_FILE = MSSCalendar/Info.plist; 326 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 327 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 328 | PRODUCT_BUNDLE_IDENTIFIER = com.mss.MSSCalendar; 329 | PRODUCT_NAME = "$(TARGET_NAME)"; 330 | }; 331 | name = Debug; 332 | }; 333 | 40F521771CB10EBF006FFA37 /* Release */ = { 334 | isa = XCBuildConfiguration; 335 | buildSettings = { 336 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 337 | INFOPLIST_FILE = MSSCalendar/Info.plist; 338 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 339 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 340 | PRODUCT_BUNDLE_IDENTIFIER = com.mss.MSSCalendar; 341 | PRODUCT_NAME = "$(TARGET_NAME)"; 342 | }; 343 | name = Release; 344 | }; 345 | /* End XCBuildConfiguration section */ 346 | 347 | /* Begin XCConfigurationList section */ 348 | 40F521591CB10EBF006FFA37 /* Build configuration list for PBXProject "MSSCalendar" */ = { 349 | isa = XCConfigurationList; 350 | buildConfigurations = ( 351 | 40F521731CB10EBF006FFA37 /* Debug */, 352 | 40F521741CB10EBF006FFA37 /* Release */, 353 | ); 354 | defaultConfigurationIsVisible = 0; 355 | defaultConfigurationName = Release; 356 | }; 357 | 40F521751CB10EBF006FFA37 /* Build configuration list for PBXNativeTarget "MSSCalendar" */ = { 358 | isa = XCConfigurationList; 359 | buildConfigurations = ( 360 | 40F521761CB10EBF006FFA37 /* Debug */, 361 | 40F521771CB10EBF006FFA37 /* Release */, 362 | ); 363 | defaultConfigurationIsVisible = 0; 364 | defaultConfigurationName = Release; 365 | }; 366 | /* End XCConfigurationList section */ 367 | }; 368 | rootObject = 40F521561CB10EBF006FFA37 /* Project object */; 369 | } 370 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/3. 6 | // Copyright © 2016年 于威. 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 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/3. 6 | // Copyright © 2016年 于威. 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 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/Assets.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 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 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 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCalendarCollectionReusableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCalendarCollectionReusableView.h 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/3. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MSSCalendarCollectionReusableView : UICollectionReusableView 12 | 13 | @property (nonatomic,strong)UILabel *headerLabel; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCalendarCollectionReusableView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCalendarCollectionReusableView.m 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/3. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import "MSSCalendarCollectionReusableView.h" 10 | #import "MSSCalendarDefine.h" 11 | 12 | @implementation MSSCalendarCollectionReusableView 13 | 14 | - (instancetype)initWithFrame:(CGRect)frame 15 | { 16 | self = [super initWithFrame:frame]; 17 | if (self) { 18 | // Initialization code 19 | [self createReusableView]; 20 | } 21 | return self; 22 | } 23 | 24 | - (void)createReusableView 25 | { 26 | UIView *headerView = [[UIView alloc]init]; 27 | headerView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); 28 | [self addSubview:headerView]; 29 | 30 | _headerLabel = [[UILabel alloc]init]; 31 | _headerLabel.frame = CGRectMake(10, 0, self.frame.size.width - 10, self.frame.size.height); 32 | _headerLabel.textAlignment = NSTextAlignmentCenter; 33 | _headerLabel.backgroundColor = [UIColor clearColor]; 34 | _headerLabel.textColor = MSS_HeaderViewTextColor; 35 | [headerView addSubview:_headerLabel]; 36 | 37 | 38 | UIView *topLineView = [[UIView alloc]init]; 39 | topLineView.frame = CGRectMake(0, 0, headerView.frame.size.width, MSS_ONE_PIXEL); 40 | topLineView.backgroundColor = MSS_HeaderViewLineColor; 41 | [headerView addSubview:topLineView]; 42 | 43 | UIView *bottomLineView = [[UIView alloc]init]; 44 | bottomLineView.frame = CGRectMake(0, headerView.frame.size.height - MSS_ONE_PIXEL, headerView.frame.size.width, MSS_ONE_PIXEL); 45 | bottomLineView.backgroundColor = MSS_HeaderViewLineColor; 46 | [headerView addSubview:bottomLineView]; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCalendarCollectionViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCalendarCollectionViewCell.h 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/3. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MSSCircleLabel.h" 11 | 12 | @interface MSSCalendarCollectionViewCell : UICollectionViewCell 13 | 14 | @property (nonatomic,strong)UIImageView *imageView; 15 | @property (nonatomic,strong)MSSCircleLabel *dateLabel; 16 | @property (nonatomic,strong)UILabel *subLabel; 17 | @property (nonatomic,assign)BOOL isSelected; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCalendarCollectionViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCalendarCollectionViewCell.m 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/3. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import "MSSCalendarCollectionViewCell.h" 10 | #import "MSSCalendarDefine.h" 11 | 12 | @implementation MSSCalendarCollectionViewCell 13 | 14 | - (instancetype)initWithFrame:(CGRect)frame 15 | { 16 | self = [super initWithFrame:frame]; 17 | { 18 | [self createCell]; 19 | } 20 | return self; 21 | } 22 | 23 | - (void)createCell 24 | { 25 | _imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.contentView.frame.size.width, self.contentView.frame.size.height)]; 26 | [self.contentView addSubview:_imageView]; 27 | 28 | _dateLabel = [[MSSCircleLabel alloc]initWithFrame:CGRectMake(0, MSS_Iphone6Scale(10), self.contentView.frame.size.width, self.frame.size.height / 2 - MSS_Iphone6Scale(10))]; 29 | _dateLabel.textAlignment = NSTextAlignmentCenter; 30 | _dateLabel.font = [UIFont systemFontOfSize:13.0f]; 31 | [self.contentView addSubview:_dateLabel]; 32 | 33 | _subLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, CGRectGetMaxY(_dateLabel.frame), self.contentView.frame.size.width, _dateLabel.frame.size.height)]; 34 | _subLabel.textAlignment = NSTextAlignmentCenter; 35 | _subLabel.font = [UIFont systemFontOfSize:10.0f]; 36 | [self.contentView addSubview:_subLabel]; 37 | } 38 | 39 | - (void)setIsSelected:(BOOL)isSelected 40 | { 41 | _dateLabel.isSelected = isSelected; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCalendarDefine.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCalendarDefine.h 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/4. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #define MSS_SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width) 10 | #define MSS_SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height) 11 | #define MSS_UTILS_COLORRGB(r,g,b) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1] 12 | #define MSS_Iphone6Scale(x) ((x) * MSS_SCREEN_WIDTH / 375.0f) 13 | #define MSS_ONE_PIXEL (1.0f / [[UIScreen mainScreen] scale]) 14 | 15 | /*定义属性*/ 16 | // DateLabel默认文字颜色 17 | #define MSS_TextColor [UIColor blackColor] 18 | // DateLabel选中时的背景色 19 | #define MSS_SelectBackgroundColor MSS_UTILS_COLORRGB(29, 154, 72) 20 | // DateLabel选中后文字颜色 21 | #define MSS_SelectTextColor [UIColor whiteColor] 22 | // SubLabel文字颜色 23 | #define MSS_SelectSubLabelTextColor MSS_UTILS_COLORRGB(29, 154, 180); 24 | // SubLabel选中开始文字 25 | #define MSS_SelectBeginText @"开始" 26 | // SubLabel选中结束文字 27 | #define MSS_SelectEndText @"结束" 28 | // 节日颜色 29 | #define MSS_HolidayTextColor [UIColor purpleColor] 30 | // 周末颜色 31 | #define MSS_WeekEndTextColor [UIColor redColor] 32 | // 不可点击文字颜色 33 | #define MSS_TouchUnableTextColor MSS_UTILS_COLORRGB(150, 150, 150) 34 | // 周视图高度 35 | #define MSS_WeekViewHeight 40 36 | // headerView线颜色 37 | #define MSS_HeaderViewLineColor [UIColor lightGrayColor] 38 | // headerView文字颜色 39 | #define MSS_HeaderViewTextColor [UIColor blackColor] 40 | // headerView高度 41 | #define MSS_HeaderViewHeight 50 42 | // 弹出层文字颜色 43 | #define MSS_CalendarPopViewTextColor [UIColor whiteColor] 44 | // 弹出层背景颜色 45 | #define MSS_CalendarPopViewBackgroundColor [UIColor blackColor] 46 | 47 | 48 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCalendarHeaderModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCalendarHeaderModel.h 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/4. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MSSCalendarHeaderModel : NSObject 12 | @property (nonatomic,copy)NSString *headerText; 13 | @property (nonatomic,strong)NSArray *calendarItemArray; 14 | @end 15 | 16 | typedef NS_ENUM(NSInteger, MSSCalendarType) 17 | { 18 | MSSCalendarTodayType = 0, 19 | MSSCalendarLastType, 20 | MSSCalendarNextType 21 | }; 22 | 23 | @interface MSSCalendarModel : NSObject 24 | 25 | @property (nonatomic,assign)NSInteger year; 26 | @property (nonatomic,assign)NSInteger month; 27 | @property (nonatomic,assign)NSInteger day; 28 | @property (nonatomic,copy)NSString *chineseCalendar;// 农历 29 | @property (nonatomic,copy)NSString *holiday;// 节日 30 | @property (nonatomic,assign)MSSCalendarType type; 31 | @property (nonatomic,assign)NSInteger dateInterval;// 日期的时间戳 32 | @property (nonatomic,assign)NSInteger week;// 星期 33 | 34 | @end -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCalendarHeaderModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCalendarHeaderModel.m 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/4. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import "MSSCalendarHeaderModel.h" 10 | 11 | @implementation MSSCalendarHeaderModel 12 | 13 | @end 14 | 15 | @implementation MSSCalendarModel 16 | 17 | @end -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCalendarManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCalendarManager.h 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/3. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MSSCalendarViewController.h" 11 | @interface MSSCalendarManager : NSObject 12 | 13 | - (instancetype)initWithShowChineseHoliday:(BOOL)showChineseHoliday showChineseCalendar:(BOOL)showChineseCalendar startDate:(NSInteger)startDate; 14 | // 获取数据源 15 | - (NSArray *)getCalendarDataSoruceWithLimitMonth:(NSInteger)limitMonth type:(MSSCalendarViewControllerType)type; 16 | 17 | @property (nonatomic,strong)NSIndexPath *startIndexPath; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCalendarManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCalendarManager.m 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/3. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import "MSSCalendarManager.h" 10 | #import "MSSChineseCalendarManager.h" 11 | 12 | @interface MSSCalendarManager () 13 | 14 | @property (nonatomic,strong)NSDate *todayDate; 15 | @property (nonatomic,strong)NSDateComponents *todayCompontents; 16 | @property (nonatomic,strong)NSCalendar *greCalendar; 17 | @property (nonatomic,strong)NSDateFormatter *dateFormatter; 18 | @property (nonatomic,strong)MSSChineseCalendarManager *chineseCalendarManager; 19 | @property (nonatomic,assign)BOOL showChineseHoliday;// 是否展示农历节日 20 | @property (nonatomic,assign)BOOL showChineseCalendar;// 是否展示农历 21 | @property (nonatomic,assign)NSInteger startDate; 22 | 23 | @end 24 | 25 | @implementation MSSCalendarManager 26 | 27 | - (instancetype)initWithShowChineseHoliday:(BOOL)showChineseHoliday showChineseCalendar:(BOOL)showChineseCalendar startDate:(NSInteger)startDate 28 | { 29 | self = [super init]; 30 | { 31 | _greCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar]; 32 | _todayDate = [NSDate date]; 33 | _todayCompontents = [self dateToComponents:_todayDate]; 34 | _dateFormatter = [[NSDateFormatter alloc]init]; 35 | _chineseCalendarManager = [[MSSChineseCalendarManager alloc]init]; 36 | _showChineseCalendar = showChineseCalendar; 37 | _showChineseHoliday = showChineseHoliday; 38 | _startDate = startDate; 39 | } 40 | return self; 41 | } 42 | 43 | - (NSArray *)getCalendarDataSoruceWithLimitMonth:(NSInteger)limitMonth type:(MSSCalendarViewControllerType)type 44 | { 45 | NSMutableArray *resultArray = [[NSMutableArray alloc]init]; 46 | 47 | NSDateComponents *components = [self dateToComponents:_todayDate]; 48 | components.day = 1; 49 | if(type == MSSCalendarViewControllerNextType) 50 | { 51 | components.month -= 1; 52 | } 53 | else if(type == MSSCalendarViewControllerLastType) 54 | { 55 | components.month -= limitMonth; 56 | } 57 | else 58 | { 59 | components.month -= (limitMonth + 1) / 2; 60 | } 61 | NSInteger i = 0; 62 | for(i = 0;i < limitMonth;i++) 63 | { 64 | components.month++; 65 | MSSCalendarHeaderModel *headerItem = [[MSSCalendarHeaderModel alloc]init]; 66 | NSDate *date = [self componentsToDate:components]; 67 | [_dateFormatter setDateFormat: @"yyyy年MM月"]; 68 | NSString *dateString = [_dateFormatter stringFromDate:date]; 69 | headerItem.headerText = dateString; 70 | headerItem.calendarItemArray = [self getCalendarItemArrayWithDate:date section:i]; 71 | [resultArray addObject:headerItem]; 72 | } 73 | return resultArray; 74 | } 75 | 76 | // 得到每一天的数据源 77 | - (NSArray *)getCalendarItemArrayWithDate:(NSDate *)date section:(NSInteger)section 78 | { 79 | NSMutableArray *resultArray = [[NSMutableArray alloc]init]; 80 | NSInteger tatalDay = [self numberOfDaysInCurrentMonth:date]; 81 | NSInteger firstDay = [self startDayOfWeek:date]; 82 | 83 | NSDateComponents *components = [self dateToComponents:date]; 84 | 85 | // 判断日历有多少列 86 | NSInteger tempDay = tatalDay + (firstDay - 1); 87 | NSInteger column = 0; 88 | if(tempDay % 7 == 0) 89 | { 90 | column = tempDay / 7; 91 | } 92 | else 93 | { 94 | column = tempDay / 7 + 1; 95 | } 96 | 97 | NSInteger i = 0; 98 | NSInteger j = 0; 99 | components.day = 0; 100 | for(i = 0;i < column;i++) 101 | { 102 | for(j = 0;j < 7;j++) 103 | { 104 | if(i == 0 && j < firstDay - 1) 105 | { 106 | MSSCalendarModel *calendarItem = [[MSSCalendarModel alloc]init]; 107 | calendarItem.year = 0; 108 | calendarItem.month = 0; 109 | calendarItem.day = 0; 110 | calendarItem.chineseCalendar = @""; 111 | calendarItem.holiday = @""; 112 | calendarItem.week = -1; 113 | calendarItem.dateInterval = -1; 114 | [resultArray addObject:calendarItem]; 115 | continue; 116 | } 117 | components.day += 1; 118 | if(components.day == tatalDay + 1) 119 | { 120 | i = column;// 结束外层循环 121 | break; 122 | } 123 | MSSCalendarModel *calendarItem = [[MSSCalendarModel alloc]init]; 124 | calendarItem.year = components.year; 125 | calendarItem.month = components.month; 126 | calendarItem.day = components.day; 127 | calendarItem.week = j; 128 | NSDate *date = [self componentsToDate:components]; 129 | // 时间戳 130 | calendarItem.dateInterval = [self dateToInterval:date]; 131 | if(_startDate == calendarItem.dateInterval) 132 | { 133 | _startIndexPath = [NSIndexPath indexPathForRow:0 inSection:section]; 134 | } 135 | [self setChineseCalendarAndHolidayWithDate:components date:date calendarItem:calendarItem]; 136 | 137 | [resultArray addObject:calendarItem]; 138 | } 139 | } 140 | return resultArray; 141 | } 142 | 143 | // 一个月有多少天 144 | - (NSUInteger)numberOfDaysInCurrentMonth:(NSDate *)date 145 | { 146 | return [_greCalendar rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date].length; 147 | } 148 | 149 | // 确定这个月的第一天是星期几 150 | - (NSUInteger)startDayOfWeek:(NSDate *)date 151 | { 152 | NSDate *startDate = nil; 153 | BOOL result = [_greCalendar rangeOfUnit:NSMonthCalendarUnit startDate:&startDate interval:NULL forDate:date]; 154 | if(result) 155 | { 156 | return [_greCalendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSWeekCalendarUnit forDate:startDate]; 157 | } 158 | return 0; 159 | } 160 | 161 | // 日期转时间戳 162 | - (NSInteger)dateToInterval:(NSDate *)date 163 | { 164 | return (long)[date timeIntervalSince1970]; 165 | } 166 | 167 | #pragma mark 农历和节假日 168 | - (void)setChineseCalendarAndHolidayWithDate:(NSDateComponents *)components date:(NSDate *)date calendarItem:(MSSCalendarModel *)calendarItem 169 | { 170 | if (components.year == _todayCompontents.year && components.month == _todayCompontents.month && components.day == _todayCompontents.day) 171 | { 172 | calendarItem.type = MSSCalendarTodayType; 173 | calendarItem.holiday = @"今天"; 174 | } 175 | else 176 | { 177 | if([date compare:_todayDate] == 1) 178 | { 179 | calendarItem.type = MSSCalendarNextType; 180 | } 181 | else 182 | { 183 | calendarItem.type = MSSCalendarLastType; 184 | } 185 | } 186 | // if (components.year == _todayCompontents.year && components.month == _todayCompontents.month && components.day == _todayCompontents.day - 1) 187 | // { 188 | // calendarItem.holiday = @"昨天"; 189 | // } 190 | // else if (components.year == _todayCompontents.year && components.month == _todayCompontents.month && components.day == _todayCompontents.day + 1) 191 | // { 192 | // calendarItem.holiday = @"明天"; 193 | // } 194 | 195 | if(components.month == 1 && components.day == 1) 196 | { 197 | calendarItem.holiday = @"元旦"; 198 | } 199 | else if(components.month == 2 && components.day == 14) 200 | { 201 | calendarItem.holiday = @"情人节"; 202 | } 203 | else if(components.month == 3 && components.day == 8) 204 | { 205 | calendarItem.holiday = @"妇女节"; 206 | } 207 | else if(components.month == 4 && components.day == 1) 208 | { 209 | calendarItem.holiday = @"愚人节"; 210 | } 211 | else if(components.month == 4 && (components.day == 4 || components.day == 5 || components.day == 6)) 212 | { 213 | if([_chineseCalendarManager isQingMingholidayWithYear:components.year month:components.month day:components.day]) 214 | { 215 | calendarItem.holiday = @"清明节"; 216 | } 217 | } 218 | else if(components.month == 5 && components.day == 1) 219 | { 220 | calendarItem.holiday = @"劳动节"; 221 | } 222 | else if(components.month == 5 && components.day == 4) 223 | { 224 | calendarItem.holiday = @"青年节"; 225 | } 226 | else if(components.month == 6 && components.day == 1) 227 | { 228 | calendarItem.holiday = @"儿童节"; 229 | } 230 | else if(components.month == 8 && components.day == 1) 231 | { 232 | calendarItem.holiday = @"建军节"; 233 | } 234 | else if(components.month == 9 && components.day == 10) 235 | { 236 | calendarItem.holiday = @"教师节"; 237 | } 238 | else if(components.month == 10 && components.day == 1) 239 | { 240 | calendarItem.holiday = @"国庆节"; 241 | } 242 | else if(components.month == 1 && components.day == 1) 243 | { 244 | calendarItem.holiday = @"元旦"; 245 | } 246 | else if(components.month == 11 && components.day == 11) 247 | { 248 | calendarItem.holiday = @"光棍节"; 249 | } 250 | else if(components.month == 12 && components.day == 25) 251 | { 252 | calendarItem.holiday = @"圣诞节"; 253 | } 254 | // 计算农历耗性能 255 | if(_showChineseCalendar || _showChineseHoliday) 256 | { 257 | [_chineseCalendarManager getChineseCalendarWithDate:date calendarItem:calendarItem]; 258 | } 259 | } 260 | 261 | #pragma mark NSDate和NSCompontents转换 262 | - (NSDateComponents *)dateToComponents:(NSDate *)date 263 | { 264 | NSDateComponents *components = [_greCalendar components:(NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:date]; 265 | return components; 266 | } 267 | 268 | - (NSDate *)componentsToDate:(NSDateComponents *)components 269 | { 270 | // 不区分时分秒 271 | components.hour = 0; 272 | components.minute = 0; 273 | components.second = 0; 274 | NSDate *date = [_greCalendar dateFromComponents:components]; 275 | return date; 276 | } 277 | 278 | @end 279 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCalendarPopView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCalendarPopView.h 3 | // Test 4 | // 5 | // Created by 于威 on 16/4/16. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger, MSSCalendarPopViewArrowPosition) 12 | { 13 | MSSCalendarPopViewArrowPositionLeft = 0, 14 | MSSCalendarPopViewArrowPositionMiddle, 15 | MSSCalendarPopViewArrowPositionRight 16 | }; 17 | 18 | @interface MSSCalendarPopView : UIView 19 | 20 | @property (nonatomic,copy)NSString *topLabelText; 21 | @property (nonatomic,copy)NSString *bottomLabelText; 22 | 23 | - (instancetype)initWithSideView:(UIView *)sideView arrowPosition:(MSSCalendarPopViewArrowPosition)arrowPosition; 24 | 25 | - (void)showWithAnimation; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCalendarPopView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCalendarPopView.m 3 | // Test 4 | // 5 | // Created by 于威 on 16/4/16. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import "MSSCalendarPopView.h" 10 | #import "MSSCalendarDefine.h" 11 | 12 | static const CGFloat CalendarPopViewArrowHeight = 7.0f; 13 | static const CGFloat CalendarPopViewAlpha = 0.5f; 14 | 15 | @interface MSSCalendarPopView () 16 | 17 | @property (nonatomic,assign)MSSCalendarPopViewArrowPosition arrowPosition; 18 | @property (nonatomic,assign)CGRect sideViewInWindowRect; 19 | @property (nonatomic,assign)CGFloat drawArrowStartX; 20 | @property (nonatomic,strong)UIView *backgroundView; 21 | @property (nonatomic,strong)UILabel *topLabel; 22 | @property (nonatomic,strong)UILabel *bottomLabel; 23 | 24 | @end 25 | 26 | @implementation MSSCalendarPopView 27 | 28 | - (instancetype)initWithSideView:(UIView *)sideView arrowPosition:(MSSCalendarPopViewArrowPosition)arrowPosition 29 | { 30 | self = [super initWithFrame:CGRectZero]; 31 | if(self) 32 | { 33 | _arrowPosition = arrowPosition; 34 | _sideViewInWindowRect = [self getFrameInWindow:sideView]; 35 | [self createUI]; 36 | } 37 | return self; 38 | } 39 | 40 | - (void)createUI 41 | { 42 | self.backgroundColor = [UIColor clearColor]; 43 | _backgroundView = [[UIView alloc]init]; 44 | _backgroundView.backgroundColor = [MSS_CalendarPopViewBackgroundColor colorWithAlphaComponent:CalendarPopViewAlpha]; 45 | _backgroundView.layer.cornerRadius = 5.0f; 46 | [self addSubview:_backgroundView]; 47 | 48 | _topLabel = [[UILabel alloc]init]; 49 | _topLabel.textColor = MSS_CalendarPopViewTextColor; 50 | _topLabel.font = [UIFont boldSystemFontOfSize:12.0f]; 51 | _topLabel.textAlignment = NSTextAlignmentCenter; 52 | [_backgroundView addSubview:_topLabel]; 53 | 54 | _bottomLabel = [[UILabel alloc]init]; 55 | _bottomLabel.textColor = MSS_CalendarPopViewTextColor; 56 | _bottomLabel.font = [UIFont boldSystemFontOfSize:10.0f]; 57 | _bottomLabel.textAlignment = NSTextAlignmentCenter; 58 | [_backgroundView addSubview:_bottomLabel]; 59 | } 60 | 61 | - (void)showWithAnimation 62 | { 63 | if(!self.superview) 64 | { 65 | [[UIApplication sharedApplication].keyWindow addSubview:self]; 66 | } 67 | self.transform = CGAffineTransformMakeScale(0.1, 0.1); 68 | [UIView animateWithDuration:0.2 animations:^{ 69 | self.transform = CGAffineTransformMakeScale(1.0, 1.0); 70 | }]; 71 | } 72 | 73 | // 获取指定视图在window中的位置 74 | - (CGRect)getFrameInWindow:(UIView *)view 75 | { 76 | return [view.superview convertRect:view.frame toView:[UIApplication sharedApplication].keyWindow]; 77 | } 78 | 79 | - (void)drawRect:(CGRect)rect 80 | { 81 | // 画三角 82 | UIBezierPath *path = [UIBezierPath bezierPath]; 83 | [path moveToPoint:CGPointMake(_drawArrowStartX, rect.size.height)]; 84 | [path addLineToPoint:CGPointMake(_drawArrowStartX - CalendarPopViewArrowHeight, rect.size.height - CalendarPopViewArrowHeight)]; 85 | [path addLineToPoint:CGPointMake(_drawArrowStartX + CalendarPopViewArrowHeight, rect.size.height - CalendarPopViewArrowHeight)]; 86 | [path closePath]; 87 | [[MSS_CalendarPopViewBackgroundColor colorWithAlphaComponent:CalendarPopViewAlpha]setFill]; 88 | [path fill]; 89 | } 90 | 91 | - (void)setLayerAnchorPoint 92 | { 93 | if(_arrowPosition == MSSCalendarPopViewArrowPositionLeft) 94 | { 95 | _drawArrowStartX = _sideViewInWindowRect.size.width / 2 - 10; 96 | } 97 | else if(_arrowPosition == MSSCalendarPopViewArrowPositionMiddle) 98 | { 99 | _drawArrowStartX = self.frame.size.width / 2; 100 | } 101 | else 102 | { 103 | _drawArrowStartX = self.frame.size.width - _sideViewInWindowRect.size.width / 2 + 10; 104 | } 105 | CGRect oldRect = self.frame; 106 | self.layer.anchorPoint = CGPointMake(_drawArrowStartX / self.frame.size.width, 1.0); 107 | self.frame = oldRect; 108 | } 109 | 110 | - (void)setTopLabelText:(NSString *)topLabelText 111 | { 112 | _topLabelText = topLabelText; 113 | _topLabel.text = _topLabelText; 114 | [self updateUI]; 115 | } 116 | 117 | - (void)setBottomLabelText:(NSString *)bottomLabelText 118 | { 119 | _bottomLabelText = bottomLabelText; 120 | _bottomLabel.text = _bottomLabelText; 121 | [self updateUI]; 122 | } 123 | 124 | - (void)updateUI 125 | { 126 | CGRect topTextRect = [_topLabelText boundingRectWithSize:CGSizeMake(MAXFLOAT,MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:_topLabel.font} context:nil]; 127 | CGRect bottomTextRect = [_bottomLabelText boundingRectWithSize:CGSizeMake(MAXFLOAT,MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:_bottomLabel.font} context:nil]; 128 | CGFloat width = MAX(topTextRect.size.width, bottomTextRect.size.width) + 20; 129 | 130 | CGFloat x = 0.0f; 131 | if(_arrowPosition == MSSCalendarPopViewArrowPositionLeft) 132 | { 133 | x = _sideViewInWindowRect.origin.x + 10; 134 | } 135 | else if(_arrowPosition == MSSCalendarPopViewArrowPositionMiddle) 136 | { 137 | x = CGRectGetMidX(_sideViewInWindowRect) - width / 2; 138 | } 139 | else 140 | { 141 | x = _sideViewInWindowRect.origin.x + _sideViewInWindowRect.size.width - width - 10; 142 | } 143 | CGFloat height = 50.0f; 144 | self.frame = CGRectMake(x, _sideViewInWindowRect.origin.y - height - CalendarPopViewArrowHeight, width, height + CalendarPopViewArrowHeight); 145 | _backgroundView.frame = CGRectMake(0, 0, width, height); 146 | _topLabel.frame = CGRectMake(0, 13, width, 12); 147 | _bottomLabel.frame = CGRectMake(0, 28, width, 10); 148 | [self setLayerAnchorPoint]; 149 | } 150 | 151 | @end 152 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCalendarViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCalendarViewController.h 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/3. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol MSSCalendarViewControllerDelegate 12 | - (void)calendarViewConfirmClickWithStartDate:(NSInteger)startDate endDate:(NSInteger)endDate; 13 | @end 14 | 15 | typedef NS_ENUM(NSInteger, MSSCalendarViewControllerType) 16 | { 17 | MSSCalendarViewControllerLastType = 0,// 只显示当前月之前 18 | MSSCalendarViewControllerMiddleType,// 前后各显示一半 19 | MSSCalendarViewControllerNextType// 只显示当前月之后 20 | }; 21 | 22 | @interface MSSCalendarViewController : UIViewController 23 | @property (nonatomic,weak)id delegate; 24 | @property (nonatomic,assign)NSInteger startDate;// 选中开始时间 25 | @property (nonatomic,assign)NSInteger endDate;// 选中结束时间 26 | 27 | @property (nonatomic,assign)NSInteger limitMonth;// 显示几个月的数据 28 | @property (nonatomic,assign)MSSCalendarViewControllerType type; 29 | @property (nonatomic,assign)BOOL afterTodayCanTouch;// 今天之后的日期是否可以点击 30 | @property (nonatomic,assign)BOOL beforeTodayCanTouch;// 今天之前的日期是否可以点击 31 | 32 | /*以下两个属性设为YES,计算中国农历非常耗性能(在5S加载15年以内的数据没有影响)*/ 33 | @property (nonatomic,assign)BOOL showChineseHoliday;// 是否展示农历节日 34 | @property (nonatomic,assign)BOOL showChineseCalendar;// 是否展示农历 35 | @property (nonatomic,assign)BOOL showHolidayDifferentColor;// 节假日是否宣示不同的颜色 36 | 37 | @property (nonatomic,assign)BOOL showAlertView;// 是否显示提示弹窗 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCalendarViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCalendarViewController.m 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/3. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import "MSSCalendarViewController.h" 10 | #import "MSSCalendarCollectionViewCell.h" 11 | #import "MSSCalendarHeaderModel.h" 12 | #import "MSSCalendarManager.h" 13 | #import "MSSCalendarCollectionReusableView.h" 14 | #import "MSSCalendarPopView.h" 15 | #import "MSSCalendarDefine.h" 16 | 17 | @interface MSSCalendarViewController () 18 | @property (nonatomic,strong)UICollectionView *collectionView; 19 | @property (nonatomic,strong)NSMutableArray *dataArray; 20 | @property (nonatomic,strong)MSSCalendarPopView *popView; 21 | @end 22 | 23 | @implementation MSSCalendarViewController 24 | 25 | - (instancetype)init 26 | { 27 | self = [super init]; 28 | if(self) 29 | { 30 | _afterTodayCanTouch = YES; 31 | _beforeTodayCanTouch = YES; 32 | _dataArray = [[NSMutableArray alloc]init]; 33 | _showChineseCalendar = NO; 34 | _showChineseHoliday = NO; 35 | _showHolidayDifferentColor = NO; 36 | _showAlertView = NO; 37 | } 38 | return self; 39 | } 40 | 41 | - (void)viewDidLoad 42 | { 43 | [super viewDidLoad]; 44 | [self initDataSource]; 45 | [self createUI]; 46 | } 47 | 48 | - (void)viewWillDisappear:(BOOL)animated 49 | { 50 | [super viewWillDisappear:animated]; 51 | if(_popView) 52 | { 53 | [_popView removeFromSuperview]; 54 | _popView = nil; 55 | } 56 | } 57 | 58 | - (void)initDataSource 59 | { 60 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 61 | MSSCalendarManager *manager = [[MSSCalendarManager alloc]initWithShowChineseHoliday:_showChineseHoliday showChineseCalendar:_showChineseCalendar startDate:_startDate]; 62 | NSArray *tempDataArray = [manager getCalendarDataSoruceWithLimitMonth:_limitMonth type:_type]; 63 | dispatch_async(dispatch_get_main_queue(), ^{ 64 | [_dataArray addObjectsFromArray:tempDataArray]; 65 | [self showCollectionViewWithStartIndexPath:manager.startIndexPath]; 66 | }); 67 | }); 68 | } 69 | 70 | - (void)addWeakView 71 | { 72 | UIView *weekView = [[UIView alloc]initWithFrame:CGRectMake(0, 64, MSS_SCREEN_WIDTH, MSS_WeekViewHeight)]; 73 | weekView.backgroundColor = MSS_SelectBackgroundColor; 74 | [self.view addSubview:weekView]; 75 | 76 | NSArray *weekArray = @[@"日",@"一",@"二",@"三",@"四",@"五",@"六"]; 77 | int i = 0; 78 | NSInteger width = MSS_Iphone6Scale(54); 79 | for(i = 0; i < 7;i++) 80 | { 81 | UILabel *weekLabel = [[UILabel alloc]initWithFrame:CGRectMake(i * width, 0, width, MSS_WeekViewHeight)]; 82 | weekLabel.backgroundColor = [UIColor clearColor]; 83 | weekLabel.text = weekArray[i]; 84 | weekLabel.font = [UIFont boldSystemFontOfSize:16.0f]; 85 | weekLabel.textAlignment = NSTextAlignmentCenter; 86 | if(i == 0 || i == 6) 87 | { 88 | weekLabel.textColor = MSS_WeekEndTextColor; 89 | } 90 | else 91 | { 92 | weekLabel.textColor = MSS_SelectTextColor; 93 | } 94 | [weekView addSubview:weekLabel]; 95 | } 96 | } 97 | 98 | - (void)showCollectionViewWithStartIndexPath:(NSIndexPath *)startIndexPath 99 | { 100 | [self addWeakView]; 101 | [_collectionView reloadData]; 102 | // 滚动到上次选中的位置 103 | if(startIndexPath) 104 | { 105 | [_collectionView scrollToItemAtIndexPath:startIndexPath atScrollPosition:UICollectionViewScrollPositionTop animated:NO]; 106 | _collectionView.contentOffset = CGPointMake(0, _collectionView.contentOffset.y - MSS_HeaderViewHeight); 107 | } 108 | else 109 | { 110 | if(_type == MSSCalendarViewControllerLastType) 111 | { 112 | if([_dataArray count] > 0) 113 | { 114 | [_collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:_dataArray.count - 1] atScrollPosition:UICollectionViewScrollPositionTop animated:NO]; 115 | } 116 | } 117 | else if(_type == MSSCalendarViewControllerMiddleType) 118 | { 119 | if([_dataArray count] > 0) 120 | { 121 | [_collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:(_dataArray.count - 1) / 2] atScrollPosition:UICollectionViewScrollPositionTop animated:NO]; 122 | _collectionView.contentOffset = CGPointMake(0, _collectionView.contentOffset.y - MSS_HeaderViewHeight); 123 | } 124 | } 125 | } 126 | } 127 | 128 | - (void)createUI 129 | { 130 | NSInteger width = MSS_Iphone6Scale(54); 131 | NSInteger height = MSS_Iphone6Scale(60); 132 | 133 | UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init]; 134 | flowLayout.itemSize = CGSizeMake(width, height); 135 | flowLayout.headerReferenceSize = CGSizeMake(MSS_SCREEN_WIDTH, MSS_HeaderViewHeight); 136 | flowLayout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0); 137 | flowLayout.minimumInteritemSpacing = 0; 138 | flowLayout.minimumLineSpacing = 0; 139 | 140 | _collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 64 + MSS_WeekViewHeight, width * 7, MSS_SCREEN_HEIGHT - 64 - MSS_WeekViewHeight) collectionViewLayout:flowLayout]; 141 | _collectionView.delegate = self; 142 | _collectionView.dataSource = self; 143 | _collectionView.backgroundColor = [UIColor whiteColor]; 144 | [self.view addSubview:_collectionView]; 145 | 146 | [_collectionView registerClass:[MSSCalendarCollectionViewCell class] forCellWithReuseIdentifier:@"MSSCalendarCollectionViewCell"]; 147 | [_collectionView registerClass:[MSSCalendarCollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"MSSCalendarCollectionReusableView"]; 148 | } 149 | 150 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView 151 | { 152 | return [_dataArray count]; 153 | } 154 | 155 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 156 | { 157 | MSSCalendarHeaderModel *headerItem = _dataArray[section]; 158 | return headerItem.calendarItemArray.count; 159 | } 160 | 161 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 162 | { 163 | MSSCalendarCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MSSCalendarCollectionViewCell" forIndexPath:indexPath]; 164 | if(cell) 165 | { 166 | MSSCalendarHeaderModel *headerItem = _dataArray[indexPath.section]; 167 | MSSCalendarModel *calendarItem = headerItem.calendarItemArray[indexPath.row]; 168 | cell.dateLabel.text = @""; 169 | cell.dateLabel.textColor = MSS_TextColor; 170 | cell.subLabel.text = @""; 171 | cell.subLabel.textColor = MSS_SelectSubLabelTextColor; 172 | cell.isSelected = NO; 173 | cell.userInteractionEnabled = NO; 174 | if(calendarItem.day > 0) 175 | { 176 | cell.dateLabel.text = [NSString stringWithFormat:@"%ld",(long)calendarItem.day]; 177 | cell.userInteractionEnabled = YES; 178 | } 179 | if(_showChineseCalendar) 180 | { 181 | cell.subLabel.text = calendarItem.chineseCalendar; 182 | } 183 | 184 | // 开始日期 185 | if(calendarItem.dateInterval == _startDate) 186 | { 187 | cell.isSelected = YES; 188 | cell.dateLabel.textColor = MSS_SelectTextColor; 189 | cell.subLabel.text = MSS_SelectBeginText; 190 | 191 | } 192 | // 结束日期 193 | else if (calendarItem.dateInterval == _endDate) 194 | { 195 | cell.isSelected = YES; 196 | cell.dateLabel.textColor = MSS_SelectTextColor; 197 | cell.subLabel.text = MSS_SelectEndText; 198 | } 199 | // 开始和结束之间的日期 200 | else if(calendarItem.dateInterval > _startDate && calendarItem.dateInterval < _endDate) 201 | { 202 | cell.isSelected = YES; 203 | cell.dateLabel.textColor = MSS_SelectTextColor; 204 | } 205 | else 206 | { 207 | if(calendarItem.week == 0 || calendarItem.week == 6) 208 | { 209 | cell.dateLabel.textColor = MSS_WeekEndTextColor; 210 | cell.subLabel.textColor = MSS_WeekEndTextColor; 211 | } 212 | if(calendarItem.holiday.length > 0) 213 | { 214 | cell.dateLabel.text = calendarItem.holiday; 215 | if(_showHolidayDifferentColor) 216 | { 217 | cell.dateLabel.textColor = MSS_HolidayTextColor; 218 | cell.subLabel.textColor = MSS_HolidayTextColor; 219 | } 220 | } 221 | } 222 | 223 | if(!_afterTodayCanTouch) 224 | { 225 | if(calendarItem.type == MSSCalendarNextType) 226 | { 227 | cell.dateLabel.textColor = MSS_TouchUnableTextColor; 228 | cell.subLabel.textColor = MSS_TouchUnableTextColor; 229 | cell.userInteractionEnabled = NO; 230 | } 231 | } 232 | if(!_beforeTodayCanTouch) 233 | { 234 | if(calendarItem.type == MSSCalendarLastType) 235 | { 236 | cell.dateLabel.textColor = MSS_TouchUnableTextColor; 237 | cell.subLabel.textColor = MSS_TouchUnableTextColor; 238 | cell.userInteractionEnabled = NO; 239 | } 240 | } 241 | } 242 | return cell; 243 | } 244 | 245 | // 添加header 246 | - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath 247 | { 248 | if ([kind isEqualToString:UICollectionElementKindSectionHeader]) { 249 | MSSCalendarCollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"MSSCalendarCollectionReusableView" forIndexPath:indexPath]; 250 | MSSCalendarHeaderModel *headerItem = _dataArray[indexPath.section]; 251 | headerView.headerLabel.text = headerItem.headerText; 252 | return headerView; 253 | } 254 | return nil; 255 | } 256 | 257 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 258 | { 259 | MSSCalendarHeaderModel *headerItem = _dataArray[indexPath.section]; 260 | MSSCalendarModel *calendaItem = headerItem.calendarItemArray[indexPath.row]; 261 | // 当开始日期为空时 262 | if(_startDate == 0) 263 | { 264 | _startDate = calendaItem.dateInterval; 265 | [self showPopViewWithIndexPath:indexPath]; 266 | } 267 | // 当开始日期和结束日期同时存在时(点击为重新选时间段) 268 | else if(_startDate > 0 && _endDate > 0) 269 | { 270 | _startDate = calendaItem.dateInterval; 271 | _endDate = 0; 272 | [self showPopViewWithIndexPath:indexPath]; 273 | } 274 | else 275 | { 276 | // 判断第二个选择日期是否比现在开始日期大 277 | if(_startDate < calendaItem.dateInterval) 278 | { 279 | _endDate = calendaItem.dateInterval; 280 | if([_delegate respondsToSelector:@selector(calendarViewConfirmClickWithStartDate:endDate:)]) 281 | { 282 | [_delegate calendarViewConfirmClickWithStartDate:_startDate endDate:_endDate]; 283 | } 284 | [self dismissViewControllerAnimated:YES completion:nil]; 285 | } 286 | else 287 | { 288 | _startDate = calendaItem.dateInterval; 289 | [self showPopViewWithIndexPath:indexPath]; 290 | } 291 | } 292 | [_collectionView reloadData]; 293 | } 294 | 295 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView 296 | { 297 | if(_popView) 298 | { 299 | [_popView removeFromSuperview]; 300 | _popView = nil; 301 | } 302 | } 303 | 304 | - (void)showPopViewWithIndexPath:(NSIndexPath *)indexPath; 305 | { 306 | if(_showAlertView) 307 | { 308 | [_popView removeFromSuperview]; 309 | _popView = nil; 310 | 311 | MSSCalendarPopViewArrowPosition arrowPostion = MSSCalendarPopViewArrowPositionMiddle; 312 | NSInteger position = indexPath.row % 7; 313 | if(position == 0) 314 | { 315 | arrowPostion = MSSCalendarPopViewArrowPositionLeft; 316 | } 317 | else if(position == 6) 318 | { 319 | arrowPostion = MSSCalendarPopViewArrowPositionRight; 320 | } 321 | 322 | MSSCalendarCollectionViewCell *cell = (MSSCalendarCollectionViewCell *)[_collectionView cellForItemAtIndexPath:indexPath]; 323 | _popView = [[MSSCalendarPopView alloc]initWithSideView:cell.dateLabel arrowPosition:arrowPostion]; 324 | _popView.topLabelText = [NSString stringWithFormat:@"请选择%@日期",MSS_SelectEndText]; 325 | 326 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; 327 | [dateFormatter setDateFormat:@"MM月dd日"MSS_SelectBeginText]; 328 | NSString *startDateString = [dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:_startDate]]; 329 | _popView.bottomLabelText = startDateString; 330 | [_popView showWithAnimation]; 331 | } 332 | } 333 | 334 | @end 335 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSChineseCalendarManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSSChineseCalendarManager.h 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/4. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MSSCalendarHeaderModel.h" 11 | 12 | @interface MSSChineseCalendarManager : NSObject 13 | 14 | - (void)getChineseCalendarWithDate:(NSDate *)date calendarItem:(MSSCalendarModel *)calendarItem; 15 | 16 | - (BOOL)isQingMingholidayWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSChineseCalendarManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSSChineseCalendarManager.m 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/4. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import "MSSChineseCalendarManager.h" 10 | 11 | @interface MSSChineseCalendarManager () 12 | @property (nonatomic,strong)NSCalendar *chineseCalendar; 13 | @property (nonatomic,strong)NSArray *chineseYearArray; 14 | @property (nonatomic,strong)NSArray *chineseMonthArray; 15 | @property (nonatomic,strong)NSArray *chineseDayArray; 16 | @end 17 | 18 | @implementation MSSChineseCalendarManager 19 | 20 | - (instancetype)init 21 | { 22 | self = [super init]; 23 | if(self) 24 | { 25 | _chineseCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSChineseCalendar]; 26 | // _chineseYearArray = [NSArray arrayWithObjects: 27 | // @"甲子", @"乙丑", @"丙寅", @"丁卯", @"戊辰", @"己巳", @"庚午", @"辛未", @"壬申", @"癸酉", 28 | // @"甲戌", @"乙亥", @"丙子", @"丁丑", @"戊寅", @"己卯", @"庚辰", @"辛己", @"壬午", @"癸未", 29 | // @"甲申", @"乙酉", @"丙戌", @"丁亥", @"戊子", @"己丑", @"庚寅", @"辛卯", @"壬辰", @"癸巳", 30 | // @"甲午", @"乙未", @"丙申", @"丁酉", @"戊戌", @"己亥", @"庚子", @"辛丑", @"壬寅", @"癸丑", 31 | // @"甲辰", @"乙巳", @"丙午", @"丁未", @"戊申", @"己酉", @"庚戌", @"辛亥", @"壬子", @"癸丑", 32 | // @"甲寅", @"乙卯", @"丙辰", @"丁巳", @"戊午", @"己未", @"庚申", @"辛酉", @"壬戌", @"癸亥", nil]; 33 | _chineseMonthArray = [NSArray arrayWithObjects: 34 | @"正月", @"二月", @"三月", @"四月", @"五月", @"六月", @"七月", @"八月", 35 | @"九月", @"十月", @"冬月", @"腊月", nil]; 36 | _chineseDayArray = [NSArray arrayWithObjects: 37 | @"初一", @"初二", @"初三", @"初四", @"初五", @"初六", @"初七", @"初八", @"初九", @"初十", 38 | @"十一", @"十二", @"十三", @"十四", @"十五", @"十六", @"十七", @"十八", @"十九", @"二十", 39 | @"廿一", @"廿二", @"廿三", @"廿四", @"廿五", @"廿六", @"廿七", @"廿八", @"廿九", @"三十", nil]; 40 | } 41 | return self; 42 | } 43 | 44 | - (void)getChineseCalendarWithDate:(NSDate *)date calendarItem:(MSSCalendarModel *)calendarItem 45 | { 46 | unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; 47 | 48 | NSDateComponents *localeComp = [_chineseCalendar components:unitFlags fromDate:date]; 49 | // NSString *chineseYear = [_chineseYearArray objectAtIndex:localeComp.year - 1]; 50 | NSInteger tempDay = localeComp.day; 51 | // 系统日历类在2057-09-28计算有bug结果为0(应该为30) 52 | if(tempDay == 0) 53 | { 54 | tempDay = 30; 55 | } 56 | NSString *chineseMonth = [_chineseMonthArray objectAtIndex:localeComp.month - 1]; 57 | NSString *chineseDay = [_chineseDayArray objectAtIndex:tempDay - 1]; 58 | 59 | calendarItem.chineseCalendar = chineseDay; 60 | 61 | if([@"正月" isEqualToString:chineseMonth] && 62 | [@"初一" isEqualToString:chineseDay]) 63 | { 64 | calendarItem.holiday = @"春节"; 65 | } 66 | else if([@"正月" isEqualToString:chineseMonth] && 67 | [@"十五" isEqualToString:chineseDay]) 68 | { 69 | calendarItem.holiday = @"元宵节"; 70 | } 71 | else if([@"二月" isEqualToString:chineseMonth] && 72 | [@"初二" isEqualToString:chineseDay]) 73 | { 74 | calendarItem.holiday = @"龙抬头"; 75 | } 76 | else if([@"五月" isEqualToString:chineseMonth] && 77 | [@"初五" isEqualToString:chineseDay]) 78 | { 79 | calendarItem.holiday = @"端午节"; 80 | } 81 | else if([@"七月" isEqualToString:chineseMonth] && 82 | [@"初七" isEqualToString:chineseDay]) 83 | { 84 | calendarItem.holiday = @"七夕"; 85 | } 86 | else if([@"八月" isEqualToString:chineseMonth] && 87 | [@"十五" isEqualToString:chineseDay]) 88 | { 89 | calendarItem.holiday = @"中秋节"; 90 | } 91 | else if([@"九月" isEqualToString:chineseMonth] && 92 | [@"初九" isEqualToString:chineseDay]) 93 | { 94 | calendarItem.holiday = @"重阳节"; 95 | } 96 | else if([@"腊月" isEqualToString:chineseMonth] && 97 | [@"初八" isEqualToString:chineseDay]) 98 | { 99 | calendarItem.holiday = @"腊八"; 100 | } 101 | else if([@"腊月" isEqualToString:chineseMonth] && 102 | [@"二四" isEqualToString:chineseDay]) 103 | { 104 | calendarItem.holiday = @"小年"; 105 | } 106 | else if([@"腊月" isEqualToString:chineseMonth] && 107 | [@"三十" isEqualToString:chineseDay]) 108 | { 109 | calendarItem.holiday = @"除夕"; 110 | } 111 | } 112 | 113 | /* 114 | 清明节日期的计算 [Y*D+C]-L 115 | 公式解读:Y=年数后2位,D=0.2422,L=闰年数,21世纪C=4.81,20世纪=5.59。 116 | */ 117 | - (BOOL)isQingMingholidayWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day 118 | { 119 | if(month == 4) 120 | { 121 | NSInteger pre = year / 100; 122 | float c = 4.81; 123 | if(pre == 19) 124 | { 125 | c = 5.59; 126 | } 127 | NSInteger y = year % 100; 128 | NSInteger qingMingDay = (y * 0.2422 + c) - y / 4; 129 | if(day == qingMingDay) 130 | { 131 | return YES; 132 | } 133 | } 134 | return NO; 135 | } 136 | 137 | 138 | 139 | @end 140 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCircleLabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCircleLabel.h 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/4. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MSSCircleLabel : UILabel 12 | @property (nonatomic,assign)BOOL isSelected; 13 | @end 14 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/MSSCalendar/MSSCircleLabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSSCircleLabel.m 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/4. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import "MSSCircleLabel.h" 10 | #import "MSSCalendarDefine.h" 11 | 12 | @implementation MSSCircleLabel 13 | 14 | - (void)drawRect:(CGRect)rect 15 | { 16 | if(_isSelected) 17 | { 18 | [MSS_SelectBackgroundColor setFill]; 19 | UIBezierPath *path = [UIBezierPath bezierPath]; 20 | [path addArcWithCenter:CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2) radius:self.frame.size.height / 2 startAngle:0.0 endAngle:180.0 clockwise:YES]; 21 | [path fill]; 22 | } 23 | [super drawRect:rect]; 24 | } 25 | 26 | - (void)setIsSelected:(BOOL)isSelected 27 | { 28 | _isSelected = isSelected; 29 | [self setNeedsDisplay]; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/3. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/3. 6 | // Copyright © 2016年 于威. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "MSSCalendarViewController.h" 11 | #import "MSSCalendarDefine.h" 12 | 13 | @interface ViewController () 14 | @property (nonatomic,strong)UILabel *startLabel; 15 | @property (nonatomic,strong)UILabel *endLabel; 16 | @property (nonatomic,assign)NSInteger startDate; 17 | @property (nonatomic,assign)NSInteger endDate; 18 | @end 19 | 20 | @implementation ViewController 21 | 22 | - (void)viewDidLoad 23 | { 24 | [super viewDidLoad]; 25 | [self createUI]; 26 | } 27 | 28 | - (void)createUI 29 | { 30 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 31 | btn.frame = CGRectMake((MSS_SCREEN_WIDTH - 110) / 2, 80, 110, 50); 32 | [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 33 | btn.titleLabel.font = [UIFont boldSystemFontOfSize:16.0f]; 34 | btn.layer.cornerRadius = 5.0f; 35 | btn.layer.borderWidth = 1.0f; 36 | btn.layer.borderColor = [[UIColor lightGrayColor]CGColor]; 37 | [btn setTitle:@"打开日历" forState:UIControlStateNormal]; 38 | [btn addTarget:self action:@selector(calendarClick:) forControlEvents:UIControlEventTouchUpInside]; 39 | [self.view addSubview:btn]; 40 | 41 | _startLabel = [[UILabel alloc]init]; 42 | _startLabel.backgroundColor = MSS_SelectBackgroundColor; 43 | _startLabel.textColor = MSS_SelectTextColor; 44 | _startLabel.textAlignment = NSTextAlignmentCenter; 45 | _startLabel.font = [UIFont boldSystemFontOfSize:16.0f]; 46 | _startLabel.frame = CGRectMake(20, CGRectGetMaxY(btn.frame) + 20, MSS_SCREEN_WIDTH - 20 * 2, 50); 47 | _startLabel.text = @"开始日期"; 48 | [self.view addSubview:_startLabel]; 49 | 50 | _endLabel = [[UILabel alloc]init]; 51 | _endLabel.backgroundColor = MSS_SelectBackgroundColor; 52 | _endLabel.textColor = MSS_SelectTextColor; 53 | _endLabel.textAlignment = NSTextAlignmentCenter; 54 | _endLabel.font = [UIFont boldSystemFontOfSize:16.0f]; 55 | _endLabel.frame = CGRectMake(20, CGRectGetMaxY(_startLabel.frame) + 20, MSS_SCREEN_WIDTH - 20 * 2, 50); 56 | _endLabel.text = @"开始日期"; 57 | _endLabel.text = @"结束日期"; 58 | [self.view addSubview:_endLabel]; 59 | } 60 | 61 | - (void)calendarClick:(UIButton *)btn 62 | { 63 | MSSCalendarViewController *cvc = [[MSSCalendarViewController alloc]init]; 64 | cvc.limitMonth = 12 * 15;// 显示几个月的日历 65 | /* 66 | MSSCalendarViewControllerLastType 只显示当前月之前 67 | MSSCalendarViewControllerMiddleType 前后各显示一半 68 | MSSCalendarViewControllerNextType 只显示当前月之后 69 | */ 70 | cvc.type = MSSCalendarViewControllerLastType; 71 | cvc.beforeTodayCanTouch = YES;// 今天之后的日期是否可以点击 72 | cvc.afterTodayCanTouch = NO;// 今天之前的日期是否可以点击 73 | cvc.startDate = _startDate;// 选中开始时间 74 | cvc.endDate = _endDate;// 选中结束时间 75 | /*以下两个属性设为YES,计算中国农历非常耗性能(在5s加载15年以内的数据没有影响)*/ 76 | cvc.showChineseHoliday = YES;// 是否展示农历节日 77 | cvc.showChineseCalendar = YES;// 是否展示农历 78 | cvc.showHolidayDifferentColor = YES;// 节假日是否显示不同的颜色 79 | cvc.showAlertView = YES;// 是否显示提示弹窗 80 | cvc.delegate = self; 81 | [self presentViewController:cvc animated:YES completion:nil]; 82 | } 83 | 84 | - (void)calendarViewConfirmClickWithStartDate:(NSInteger)startDate endDate:(NSInteger)endDate 85 | { 86 | _startDate = startDate; 87 | _endDate = endDate; 88 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; 89 | [dateFormatter setDateFormat: @"yyyy-MM-dd"]; 90 | NSString *startDateString = [dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:_startDate]]; 91 | NSString *endDateString = [dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:_endDate]]; 92 | _startLabel.text = [NSString stringWithFormat:@"开始日期:%@",startDateString]; 93 | _endLabel.text = [NSString stringWithFormat:@"结束日期:%@",endDateString]; 94 | } 95 | 96 | - (void)didReceiveMemoryWarning { 97 | [super didReceiveMemoryWarning]; 98 | // Dispose of any resources that can be recreated. 99 | } 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /MSSCalendar/MSSCalendar/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MSSCalendar 4 | // 5 | // Created by 于威 on 16/4/3. 6 | // Copyright © 2016年 于威. 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MSSCalendar 2 | A simple iOS Calendar 一款简单高性能的日历(类似去哪网) 3 | 4 | ![效果图](https://raw.githubusercontent.com/MSS0306/MSSCalendar/master/calendar.gif) 5 | 6 | # 说明 7 | 一款高性能的日历控件
8 | MSSCalendarDefine.h中可设置相应文字和颜色
9 | DateLabel默认文字颜色:MSS_TextColor
10 | DateLabel选中时的背景色:MSS_SelectBackgroundColor
11 | DateLabel选中后文字颜色:MSS_SelectTextColor
12 | SubLabel文字颜色:MSS_SelectSubLabelTextColor
13 | SubLabel选中开始文字:MSS_SelectBeginText
14 | SubLabel选中结束文字:MSS_SelectEndText
15 | 节日颜色:MSS_HolidayTextColor
16 | 周末颜色:MSS_WeekEndTextColor
17 | 不可点击文字颜色:MSS_TouchUnableTextColor
18 | 周视图高度:MSS_WeekViewHeight
19 | headerView线颜色:MSS_HeaderViewLineColor
20 | headerView文字颜色:MSS_HeaderViewTextColor
21 | headerView高度:MSS_HeaderViewHeight
22 | 弹出层文字颜色 MSS_CalendarPopViewTextColor
23 | 弹出层背景颜色 MSS_CalendarPopViewBackgroundColor
24 | 25 | # 版本1.0 26 | 1.可设置日历显示多少个月
27 | 2.可设置日历显示方式(当前月以前,当前月以后,当前月中间)
28 | 3.可设置今天以前的日子和今天以后的日子是否可以点击
29 | 30 | # 版本1.1 31 | 1.可设置是否显示农历及其节假日
32 | 2.直接滚动到当前选中日期
33 | 3.宏定义更多属性进行修改值
34 | 35 | # 版本1.2 36 | 1.添加提示弹窗
37 | 38 | #Example 39 | ```Objective-c 40 | MSSCalendarViewController *cvc = [[MSSCalendarViewController alloc]init]; 41 | cvc.limitMonth = 12 * 15;// 显示几个月的日历 42 | /* 43 | MSSCalendarViewControllerLastType 只显示当前月之前 44 | MSSCalendarViewControllerMiddleType 前后各显示一半 45 | MSSCalendarViewControllerNextType 只显示当前月之后 46 | */ 47 | cvc.type = MSSCalendarViewControllerLastType; 48 | cvc.beforeTodayCanTouch = YES;// 今天之后的日期是否可以点击 49 | cvc.afterTodayCanTouch = NO;// 今天之前的日期是否可以点击 50 | cvc.startDate = _startDate;// 选中开始时间 51 | cvc.endDate = _endDate;// 选中结束时间 52 | /*以下两个属性设为YES,计算中国农历非常耗性能(在5s加载15年以内的数据没有影响)*/ 53 | cvc.showChineseHoliday = YES;// 是否展示农历节日 54 | cvc.showChineseCalendar = YES;// 是否展示农历 55 | cvc.showHolidayDifferentColor = YES;// 节假日是否显示不同的颜色 56 | cvc.showAlertView = YES;// 是否显示提示弹窗 57 | cvc.delegate = self; 58 | [self presentViewController:cvc animated:YES completion:nil]; 59 | ``` 60 | -------------------------------------------------------------------------------- /calendar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MSS0306/MSSCalendar/b66bebf40dc25cc26bae047fecc08bb9cd71850c/calendar.gif --------------------------------------------------------------------------------