├── .DS_Store ├── .gitignore ├── README.md ├── Vurig Calendar.xcodeproj └── project.pbxproj └── Vurig Calendar ├── .DS_Store ├── NSDate+convenience.h ├── NSDate+convenience.m ├── NSMutableArray+convenience.h ├── NSMutableArray+convenience.m ├── UIColor+expanded.h ├── UIColor+expanded.m ├── UIView+convenience.h ├── UIView+convenience.m ├── VRGAppDelegate.h ├── VRGAppDelegate.m ├── VRGCalendarView.h ├── VRGCalendarView.m ├── VRGViewController.h ├── VRGViewController.m ├── Vurig Calendar-Info.plist ├── Vurig Calendar-Prefix.pch ├── en.lproj ├── InfoPlist.strings └── VRGViewController.xib └── main.m /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjeerdintveen/Vurig-Calendar/fcb856fcc415c73f1698d19d9cb3426b419ced8d/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | build/* 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | *.xcworkspace 12 | !default.xcworkspace 13 | xcuserdata 14 | profile 15 | *.moved-aside 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | VURIG Calendar 2 | ===================== 3 | 4 | #### A calendar view for iOS. 5 | Easy to use, simple, clean. 6 | 7 | Also animated :-) 8 | 9 | ### Installation 10 | Copy the files from the calendar group to your own project. 11 | 12 | ### Usage 13 |
14 | VRGCalendarView *calendar = [[VRGCalendarView alloc] init];
15 | calendar.delegate=self;
16 | [self.view addSubview:calendar];
17 | 
18 | 19 | ##Delegate methods 20 | ####Selecting days 21 | Whenever a user selects a date, the following method will be called: 22 |
23 | -(void)calendarView:(VRGCalendarView *)calendarView dateSelected:(NSDate *)date;
24 | 
25 | ####Switching months 26 | This delegate method will be called whenever a user switches to the next or previous month. 27 |
28 | -(void)calendarView:(VRGCalendarView *)calendarView switchedToMonth:(int)month targetHeight:(float)targetHeight animated:(BOOL)animated;
29 | 
30 | With the way the calendar layouts work, the number of rows (and thus the height) can vary. You can react to this change by using the targetHeight parameter. 31 | 32 | Mark the dates of that month by sending an array with NSDate or NSNumber objects. Like so: 33 |
34 | NSArray *dates = [NSArray arrayWithObjects:[NSNumber numberWithInt:1],[NSNumber numberWithInt:5], nil];
35 | [calendarView markDates:dates];
36 | 
37 | Or 38 |
39 | NSArray *date = [NSArray arrayWithObjects:[NSDate date], nil];
40 | NSArray *color = [NSArray arrayWithObjects:[UIColor redColor],nil];
41 | [calendarView markDates:date withColors:color];
42 | 
43 | 44 | ##License 45 | Vurig Calendar is released under the MIT License 46 | http://opensource.org/licenses/MIT 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Vurig Calendar.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 93597E58157523D0004AE766 /* NSDate+convenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 93597E57157523D0004AE766 /* NSDate+convenience.m */; }; 11 | 93597E5C157523EF004AE766 /* NSMutableArray+convenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 93597E5B157523EF004AE766 /* NSMutableArray+convenience.m */; }; 12 | 93597E5F15752414004AE766 /* UIView+convenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 93597E5E15752414004AE766 /* UIView+convenience.m */; }; 13 | 93597E6015752447004AE766 /* UIColor+expanded.m in Sources */ = {isa = PBXBuildFile; fileRef = 93664B0915752385004EBE25 /* UIColor+expanded.m */; }; 14 | 93664AE5157522C0004EBE25 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93664AE4157522C0004EBE25 /* UIKit.framework */; }; 15 | 93664AE7157522C0004EBE25 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93664AE6157522C0004EBE25 /* Foundation.framework */; }; 16 | 93664AE9157522C0004EBE25 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93664AE8157522C0004EBE25 /* CoreGraphics.framework */; }; 17 | 93664AEF157522C0004EBE25 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 93664AED157522C0004EBE25 /* InfoPlist.strings */; }; 18 | 93664AF1157522C0004EBE25 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 93664AF0157522C0004EBE25 /* main.m */; }; 19 | 93664AF5157522C0004EBE25 /* VRGAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 93664AF4157522C0004EBE25 /* VRGAppDelegate.m */; }; 20 | 93664AF8157522C0004EBE25 /* VRGViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93664AF7157522C0004EBE25 /* VRGViewController.m */; }; 21 | 93664AFB157522C0004EBE25 /* VRGViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93664AF9157522C0004EBE25 /* VRGViewController.xib */; }; 22 | 93664B05157522F1004EBE25 /* VRGCalendarView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93664B04157522F1004EBE25 /* VRGCalendarView.m */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 93597E56157523D0004AE766 /* NSDate+convenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+convenience.h"; sourceTree = ""; }; 27 | 93597E57157523D0004AE766 /* NSDate+convenience.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+convenience.m"; sourceTree = ""; }; 28 | 93597E5A157523EF004AE766 /* NSMutableArray+convenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray+convenience.h"; sourceTree = ""; }; 29 | 93597E5B157523EF004AE766 /* NSMutableArray+convenience.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableArray+convenience.m"; sourceTree = ""; }; 30 | 93597E5D15752414004AE766 /* UIView+convenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+convenience.h"; sourceTree = ""; }; 31 | 93597E5E15752414004AE766 /* UIView+convenience.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+convenience.m"; sourceTree = ""; }; 32 | 93664AE0157522BF004EBE25 /* Vurig Calendar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Vurig Calendar.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | 93664AE4157522C0004EBE25 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 34 | 93664AE6157522C0004EBE25 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 35 | 93664AE8157522C0004EBE25 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 36 | 93664AEC157522C0004EBE25 /* Vurig Calendar-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Vurig Calendar-Info.plist"; sourceTree = ""; }; 37 | 93664AEE157522C0004EBE25 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 38 | 93664AF0157522C0004EBE25 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 39 | 93664AF2157522C0004EBE25 /* Vurig Calendar-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Vurig Calendar-Prefix.pch"; sourceTree = ""; }; 40 | 93664AF3157522C0004EBE25 /* VRGAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VRGAppDelegate.h; sourceTree = ""; }; 41 | 93664AF4157522C0004EBE25 /* VRGAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VRGAppDelegate.m; sourceTree = ""; }; 42 | 93664AF6157522C0004EBE25 /* VRGViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VRGViewController.h; sourceTree = ""; }; 43 | 93664AF7157522C0004EBE25 /* VRGViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VRGViewController.m; sourceTree = ""; }; 44 | 93664AFA157522C0004EBE25 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/VRGViewController.xib; sourceTree = ""; }; 45 | 93664B03157522F1004EBE25 /* VRGCalendarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VRGCalendarView.h; sourceTree = ""; }; 46 | 93664B04157522F1004EBE25 /* VRGCalendarView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VRGCalendarView.m; sourceTree = ""; }; 47 | 93664B071575237F004EBE25 /* UIColor+expanded.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIColor+expanded.h"; sourceTree = ""; }; 48 | 93664B0915752385004EBE25 /* UIColor+expanded.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIColor+expanded.m"; sourceTree = ""; }; 49 | /* End PBXFileReference section */ 50 | 51 | /* Begin PBXFrameworksBuildPhase section */ 52 | 93664ADD157522BF004EBE25 /* Frameworks */ = { 53 | isa = PBXFrameworksBuildPhase; 54 | buildActionMask = 2147483647; 55 | files = ( 56 | 93664AE5157522C0004EBE25 /* UIKit.framework in Frameworks */, 57 | 93664AE7157522C0004EBE25 /* Foundation.framework in Frameworks */, 58 | 93664AE9157522C0004EBE25 /* CoreGraphics.framework in Frameworks */, 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | /* End PBXFrameworksBuildPhase section */ 63 | 64 | /* Begin PBXGroup section */ 65 | 93664AD5157522BF004EBE25 = { 66 | isa = PBXGroup; 67 | children = ( 68 | 93664AEA157522C0004EBE25 /* Vurig Calendar */, 69 | 93664AE3157522BF004EBE25 /* Frameworks */, 70 | 93664AE1157522BF004EBE25 /* Products */, 71 | ); 72 | sourceTree = ""; 73 | }; 74 | 93664AE1157522BF004EBE25 /* Products */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 93664AE0157522BF004EBE25 /* Vurig Calendar.app */, 78 | ); 79 | name = Products; 80 | sourceTree = ""; 81 | }; 82 | 93664AE3157522BF004EBE25 /* Frameworks */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | 93664AE4157522C0004EBE25 /* UIKit.framework */, 86 | 93664AE6157522C0004EBE25 /* Foundation.framework */, 87 | 93664AE8157522C0004EBE25 /* CoreGraphics.framework */, 88 | ); 89 | name = Frameworks; 90 | sourceTree = ""; 91 | }; 92 | 93664AEA157522C0004EBE25 /* Vurig Calendar */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 93664B06157522F2004EBE25 /* calendar */, 96 | 93664AF3157522C0004EBE25 /* VRGAppDelegate.h */, 97 | 93664AF4157522C0004EBE25 /* VRGAppDelegate.m */, 98 | 93664AF6157522C0004EBE25 /* VRGViewController.h */, 99 | 93664AF7157522C0004EBE25 /* VRGViewController.m */, 100 | 93664AF9157522C0004EBE25 /* VRGViewController.xib */, 101 | 93664AEB157522C0004EBE25 /* Supporting Files */, 102 | ); 103 | path = "Vurig Calendar"; 104 | sourceTree = ""; 105 | }; 106 | 93664AEB157522C0004EBE25 /* Supporting Files */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 93664AEC157522C0004EBE25 /* Vurig Calendar-Info.plist */, 110 | 93664AED157522C0004EBE25 /* InfoPlist.strings */, 111 | 93664AF0157522C0004EBE25 /* main.m */, 112 | 93664AF2157522C0004EBE25 /* Vurig Calendar-Prefix.pch */, 113 | ); 114 | name = "Supporting Files"; 115 | sourceTree = ""; 116 | }; 117 | 93664B06157522F2004EBE25 /* calendar */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 93664B03157522F1004EBE25 /* VRGCalendarView.h */, 121 | 93664B04157522F1004EBE25 /* VRGCalendarView.m */, 122 | 93597E5D15752414004AE766 /* UIView+convenience.h */, 123 | 93597E5E15752414004AE766 /* UIView+convenience.m */, 124 | 93597E5A157523EF004AE766 /* NSMutableArray+convenience.h */, 125 | 93597E5B157523EF004AE766 /* NSMutableArray+convenience.m */, 126 | 93597E56157523D0004AE766 /* NSDate+convenience.h */, 127 | 93597E57157523D0004AE766 /* NSDate+convenience.m */, 128 | 93664B071575237F004EBE25 /* UIColor+expanded.h */, 129 | 93664B0915752385004EBE25 /* UIColor+expanded.m */, 130 | ); 131 | name = calendar; 132 | sourceTree = ""; 133 | }; 134 | /* End PBXGroup section */ 135 | 136 | /* Begin PBXNativeTarget section */ 137 | 93664ADF157522BF004EBE25 /* Vurig Calendar */ = { 138 | isa = PBXNativeTarget; 139 | buildConfigurationList = 93664AFE157522C0004EBE25 /* Build configuration list for PBXNativeTarget "Vurig Calendar" */; 140 | buildPhases = ( 141 | 93664ADC157522BF004EBE25 /* Sources */, 142 | 93664ADD157522BF004EBE25 /* Frameworks */, 143 | 93664ADE157522BF004EBE25 /* Resources */, 144 | ); 145 | buildRules = ( 146 | ); 147 | dependencies = ( 148 | ); 149 | name = "Vurig Calendar"; 150 | productName = "Vurig Calendar"; 151 | productReference = 93664AE0157522BF004EBE25 /* Vurig Calendar.app */; 152 | productType = "com.apple.product-type.application"; 153 | }; 154 | /* End PBXNativeTarget section */ 155 | 156 | /* Begin PBXProject section */ 157 | 93664AD7157522BF004EBE25 /* Project object */ = { 158 | isa = PBXProject; 159 | attributes = { 160 | CLASSPREFIX = VRG; 161 | LastUpgradeCheck = 0430; 162 | ORGANIZATIONNAME = Vurig; 163 | }; 164 | buildConfigurationList = 93664ADA157522BF004EBE25 /* Build configuration list for PBXProject "Vurig Calendar" */; 165 | compatibilityVersion = "Xcode 3.2"; 166 | developmentRegion = English; 167 | hasScannedForEncodings = 0; 168 | knownRegions = ( 169 | en, 170 | ); 171 | mainGroup = 93664AD5157522BF004EBE25; 172 | productRefGroup = 93664AE1157522BF004EBE25 /* Products */; 173 | projectDirPath = ""; 174 | projectRoot = ""; 175 | targets = ( 176 | 93664ADF157522BF004EBE25 /* Vurig Calendar */, 177 | ); 178 | }; 179 | /* End PBXProject section */ 180 | 181 | /* Begin PBXResourcesBuildPhase section */ 182 | 93664ADE157522BF004EBE25 /* Resources */ = { 183 | isa = PBXResourcesBuildPhase; 184 | buildActionMask = 2147483647; 185 | files = ( 186 | 93664AEF157522C0004EBE25 /* InfoPlist.strings in Resources */, 187 | 93664AFB157522C0004EBE25 /* VRGViewController.xib in Resources */, 188 | ); 189 | runOnlyForDeploymentPostprocessing = 0; 190 | }; 191 | /* End PBXResourcesBuildPhase section */ 192 | 193 | /* Begin PBXSourcesBuildPhase section */ 194 | 93664ADC157522BF004EBE25 /* Sources */ = { 195 | isa = PBXSourcesBuildPhase; 196 | buildActionMask = 2147483647; 197 | files = ( 198 | 93664AF1157522C0004EBE25 /* main.m in Sources */, 199 | 93664AF5157522C0004EBE25 /* VRGAppDelegate.m in Sources */, 200 | 93664AF8157522C0004EBE25 /* VRGViewController.m in Sources */, 201 | 93664B05157522F1004EBE25 /* VRGCalendarView.m in Sources */, 202 | 93597E58157523D0004AE766 /* NSDate+convenience.m in Sources */, 203 | 93597E5C157523EF004AE766 /* NSMutableArray+convenience.m in Sources */, 204 | 93597E5F15752414004AE766 /* UIView+convenience.m in Sources */, 205 | 93597E6015752447004AE766 /* UIColor+expanded.m in Sources */, 206 | ); 207 | runOnlyForDeploymentPostprocessing = 0; 208 | }; 209 | /* End PBXSourcesBuildPhase section */ 210 | 211 | /* Begin PBXVariantGroup section */ 212 | 93664AED157522C0004EBE25 /* InfoPlist.strings */ = { 213 | isa = PBXVariantGroup; 214 | children = ( 215 | 93664AEE157522C0004EBE25 /* en */, 216 | ); 217 | name = InfoPlist.strings; 218 | sourceTree = ""; 219 | }; 220 | 93664AF9157522C0004EBE25 /* VRGViewController.xib */ = { 221 | isa = PBXVariantGroup; 222 | children = ( 223 | 93664AFA157522C0004EBE25 /* en */, 224 | ); 225 | name = VRGViewController.xib; 226 | sourceTree = ""; 227 | }; 228 | /* End PBXVariantGroup section */ 229 | 230 | /* Begin XCBuildConfiguration section */ 231 | 93664AFC157522C0004EBE25 /* Debug */ = { 232 | isa = XCBuildConfiguration; 233 | buildSettings = { 234 | ALWAYS_SEARCH_USER_PATHS = NO; 235 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 236 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 237 | COPY_PHASE_STRIP = NO; 238 | GCC_C_LANGUAGE_STANDARD = gnu99; 239 | GCC_DYNAMIC_NO_PIC = NO; 240 | GCC_OPTIMIZATION_LEVEL = 0; 241 | GCC_PREPROCESSOR_DEFINITIONS = ( 242 | "DEBUG=1", 243 | "$(inherited)", 244 | ); 245 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 246 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 247 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 248 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 249 | GCC_WARN_UNUSED_VARIABLE = YES; 250 | IPHONEOS_DEPLOYMENT_TARGET = 5.1; 251 | SDKROOT = iphoneos; 252 | }; 253 | name = Debug; 254 | }; 255 | 93664AFD157522C0004EBE25 /* Release */ = { 256 | isa = XCBuildConfiguration; 257 | buildSettings = { 258 | ALWAYS_SEARCH_USER_PATHS = NO; 259 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 260 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 261 | COPY_PHASE_STRIP = YES; 262 | GCC_C_LANGUAGE_STANDARD = gnu99; 263 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 264 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 265 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 266 | GCC_WARN_UNUSED_VARIABLE = YES; 267 | IPHONEOS_DEPLOYMENT_TARGET = 5.1; 268 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 269 | SDKROOT = iphoneos; 270 | VALIDATE_PRODUCT = YES; 271 | }; 272 | name = Release; 273 | }; 274 | 93664AFF157522C0004EBE25 /* Debug */ = { 275 | isa = XCBuildConfiguration; 276 | buildSettings = { 277 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 278 | GCC_PREFIX_HEADER = "Vurig Calendar/Vurig Calendar-Prefix.pch"; 279 | INFOPLIST_FILE = "Vurig Calendar/Vurig Calendar-Info.plist"; 280 | PRODUCT_NAME = "$(TARGET_NAME)"; 281 | WRAPPER_EXTENSION = app; 282 | }; 283 | name = Debug; 284 | }; 285 | 93664B00157522C0004EBE25 /* Release */ = { 286 | isa = XCBuildConfiguration; 287 | buildSettings = { 288 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 289 | GCC_PREFIX_HEADER = "Vurig Calendar/Vurig Calendar-Prefix.pch"; 290 | INFOPLIST_FILE = "Vurig Calendar/Vurig Calendar-Info.plist"; 291 | PRODUCT_NAME = "$(TARGET_NAME)"; 292 | WRAPPER_EXTENSION = app; 293 | }; 294 | name = Release; 295 | }; 296 | /* End XCBuildConfiguration section */ 297 | 298 | /* Begin XCConfigurationList section */ 299 | 93664ADA157522BF004EBE25 /* Build configuration list for PBXProject "Vurig Calendar" */ = { 300 | isa = XCConfigurationList; 301 | buildConfigurations = ( 302 | 93664AFC157522C0004EBE25 /* Debug */, 303 | 93664AFD157522C0004EBE25 /* Release */, 304 | ); 305 | defaultConfigurationIsVisible = 0; 306 | defaultConfigurationName = Release; 307 | }; 308 | 93664AFE157522C0004EBE25 /* Build configuration list for PBXNativeTarget "Vurig Calendar" */ = { 309 | isa = XCConfigurationList; 310 | buildConfigurations = ( 311 | 93664AFF157522C0004EBE25 /* Debug */, 312 | 93664B00157522C0004EBE25 /* Release */, 313 | ); 314 | defaultConfigurationIsVisible = 0; 315 | defaultConfigurationName = Release; 316 | }; 317 | /* End XCConfigurationList section */ 318 | }; 319 | rootObject = 93664AD7157522BF004EBE25 /* Project object */; 320 | } 321 | -------------------------------------------------------------------------------- /Vurig Calendar/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjeerdintveen/Vurig-Calendar/fcb856fcc415c73f1698d19d9cb3426b419ced8d/Vurig Calendar/.DS_Store -------------------------------------------------------------------------------- /Vurig Calendar/NSDate+convenience.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+convenience.h 3 | // 4 | // Created by in 't Veen Tjeerd on 4/23/12. 5 | // Copyright (c) 2012 Vurig Media. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface NSDate (Convenience) 11 | 12 | -(NSDate *)offsetMonth:(int)numMonths; 13 | -(NSDate *)offsetDay:(int)numDays; 14 | -(NSDate *)offsetHours:(int)hours; 15 | -(int)numDaysInMonth; 16 | -(int)firstWeekDayInMonth; 17 | -(int)year; 18 | -(int)month; 19 | -(int)day; 20 | 21 | +(NSDate *)dateStartOfDay:(NSDate *)date; 22 | +(NSDate *)dateStartOfWeek; 23 | +(NSDate *)dateEndOfWeek; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Vurig Calendar/NSDate+convenience.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+convenience.m 3 | // 4 | // Created by in 't Veen Tjeerd on 4/23/12. 5 | // Copyright (c) 2012 Vurig Media. All rights reserved. 6 | // 7 | 8 | #import "NSDate+convenience.h" 9 | 10 | @implementation NSDate (Convenience) 11 | 12 | -(int)year { 13 | NSCalendar *gregorian = [[NSCalendar alloc] 14 | initWithCalendarIdentifier:NSGregorianCalendar]; 15 | NSDateComponents *components = [gregorian components:NSYearCalendarUnit fromDate:self]; 16 | return [components year]; 17 | } 18 | 19 | 20 | -(int)month { 21 | NSCalendar *gregorian = [[NSCalendar alloc] 22 | initWithCalendarIdentifier:NSGregorianCalendar]; 23 | NSDateComponents *components = [gregorian components:NSMonthCalendarUnit fromDate:self]; 24 | return [components month]; 25 | } 26 | 27 | -(int)day { 28 | NSCalendar *gregorian = [[NSCalendar alloc] 29 | initWithCalendarIdentifier:NSGregorianCalendar]; 30 | NSDateComponents *components = [gregorian components:NSDayCalendarUnit fromDate:self]; 31 | return [components day]; 32 | } 33 | 34 | -(int)firstWeekDayInMonth { 35 | NSCalendar *gregorian = [[NSCalendar alloc] 36 | initWithCalendarIdentifier:NSGregorianCalendar]; 37 | [gregorian setFirstWeekday:2]; //monday is first day 38 | //[gregorian setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"nl_NL"]]; 39 | 40 | //Set date to first of month 41 | NSDateComponents *comps = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:self]; 42 | [comps setDay:1]; 43 | NSDate *newDate = [gregorian dateFromComponents:comps]; 44 | 45 | return [gregorian ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:newDate]; 46 | } 47 | 48 | -(NSDate *)offsetMonth:(int)numMonths { 49 | NSCalendar *gregorian = [[NSCalendar alloc] 50 | initWithCalendarIdentifier:NSGregorianCalendar]; 51 | [gregorian setFirstWeekday:2]; //monday is first day 52 | 53 | NSDateComponents *offsetComponents = [[NSDateComponents alloc] init]; 54 | [offsetComponents setMonth:numMonths]; 55 | //[offsetComponents setHour:1]; 56 | //[offsetComponents setMinute:30]; 57 | return [gregorian dateByAddingComponents:offsetComponents 58 | toDate:self options:0]; 59 | } 60 | 61 | -(NSDate *)offsetHours:(int)hours { 62 | NSCalendar *gregorian = [[NSCalendar alloc] 63 | initWithCalendarIdentifier:NSGregorianCalendar]; 64 | [gregorian setFirstWeekday:2]; //monday is first day 65 | 66 | NSDateComponents *offsetComponents = [[NSDateComponents alloc] init]; 67 | //[offsetComponents setMonth:numMonths]; 68 | [offsetComponents setHour:hours]; 69 | //[offsetComponents setMinute:30]; 70 | return [gregorian dateByAddingComponents:offsetComponents 71 | toDate:self options:0]; 72 | } 73 | 74 | -(NSDate *)offsetDay:(int)numDays { 75 | NSCalendar *gregorian = [[NSCalendar alloc] 76 | initWithCalendarIdentifier:NSGregorianCalendar]; 77 | [gregorian setFirstWeekday:2]; //monday is first day 78 | 79 | NSDateComponents *offsetComponents = [[NSDateComponents alloc] init]; 80 | [offsetComponents setDay:numDays]; 81 | //[offsetComponents setHour:1]; 82 | //[offsetComponents setMinute:30]; 83 | 84 | return [gregorian dateByAddingComponents:offsetComponents 85 | toDate:self options:0]; 86 | } 87 | 88 | 89 | 90 | -(int)numDaysInMonth { 91 | NSCalendar *cal = [NSCalendar currentCalendar]; 92 | NSRange rng = [cal rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:self]; 93 | NSUInteger numberOfDaysInMonth = rng.length; 94 | return numberOfDaysInMonth; 95 | } 96 | 97 | +(NSDate *)dateStartOfDay:(NSDate *)date { 98 | NSCalendar *gregorian = [[NSCalendar alloc] 99 | initWithCalendarIdentifier:NSGregorianCalendar]; 100 | 101 | NSDateComponents *components = 102 | [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | 103 | NSDayCalendarUnit) fromDate: date]; 104 | return [gregorian dateFromComponents:components]; 105 | } 106 | 107 | +(NSDate *)dateStartOfWeek { 108 | NSCalendar *gregorian = [[NSCalendar alloc] 109 | initWithCalendarIdentifier:NSGregorianCalendar]; 110 | [gregorian setFirstWeekday:2]; //monday is first day 111 | 112 | NSDateComponents *components = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:[NSDate date]]; 113 | 114 | NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init]; 115 | [componentsToSubtract setDay: - ((([components weekday] - [gregorian firstWeekday]) 116 | + 7 ) % 7)]; 117 | NSDate *beginningOfWeek = [gregorian dateByAddingComponents:componentsToSubtract toDate:[NSDate date] options:0]; 118 | 119 | NSDateComponents *componentsStripped = [gregorian components: (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) 120 | fromDate: beginningOfWeek]; 121 | 122 | //gestript 123 | beginningOfWeek = [gregorian dateFromComponents: componentsStripped]; 124 | 125 | return beginningOfWeek; 126 | } 127 | 128 | +(NSDate *)dateEndOfWeek { 129 | NSCalendar *gregorian =[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 130 | 131 | NSDateComponents *components = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:[NSDate date]]; 132 | 133 | 134 | NSDateComponents *componentsToAdd = [[NSDateComponents alloc] init]; 135 | [componentsToAdd setDay: + (((([components weekday] - [gregorian firstWeekday]) 136 | + 7 ) % 7))+6]; 137 | NSDate *endOfWeek = [gregorian dateByAddingComponents:componentsToAdd toDate:[NSDate date] options:0]; 138 | 139 | NSDateComponents *componentsStripped = [gregorian components: (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) 140 | fromDate: endOfWeek]; 141 | 142 | //gestript 143 | endOfWeek = [gregorian dateFromComponents: componentsStripped]; 144 | return endOfWeek; 145 | } 146 | @end 147 | -------------------------------------------------------------------------------- /Vurig Calendar/NSMutableArray+convenience.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableArray+convenience.h 3 | // 4 | // Created by in 't Veen Tjeerd on 5/10/12. 5 | // Copyright (c) 2012 Vurig Media. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface NSMutableArray (Convenience) 11 | 12 | - (void)moveObjectFromIndex:(NSUInteger)from toIndex:(NSUInteger)to; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Vurig Calendar/NSMutableArray+convenience.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // NSMutableArray+convenience.m 4 | // 5 | // Created by in 't Veen Tjeerd on 5/10/12. 6 | // Copyright (c) 2012 Vurig Media. All rights reserved. 7 | // 8 | 9 | #import "NSMutableArray+convenience.h" 10 | 11 | 12 | 13 | @implementation NSMutableArray (Convenience) 14 | 15 | - (void)moveObjectFromIndex:(NSUInteger)from toIndex:(NSUInteger)to 16 | { 17 | if (to != from) { 18 | id obj = [self objectAtIndex:from]; 19 | [obj retain]; 20 | [self removeObjectAtIndex:from]; 21 | if (to >= [self count]) { 22 | [self addObject:obj]; 23 | } else { 24 | [self insertObject:obj atIndex:to]; 25 | } 26 | [obj release]; 27 | } 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Vurig Calendar/UIColor+expanded.h: -------------------------------------------------------------------------------- 1 | 2 | /**** 3 | VOORBEELDEN 4 | 5 | [UIColor colorWithRGBHex:0xff00ff]; 6 | [UIColor colorWithHexString:@"0xff00ff"] 7 | *******/ 8 | 9 | #import 10 | 11 | #define SUPPORTS_UNDOCUMENTED_API 0 12 | 13 | @interface UIColor (UIColor_Expanded) 14 | @property (nonatomic, readonly) CGColorSpaceModel colorSpaceModel; 15 | @property (nonatomic, readonly) BOOL canProvideRGBComponents; 16 | @property (nonatomic, readonly) CGFloat red; // Only valid if canProvideRGBComponents is YES 17 | @property (nonatomic, readonly) CGFloat green; // Only valid if canProvideRGBComponents is YES 18 | @property (nonatomic, readonly) CGFloat blue; // Only valid if canProvideRGBComponents is YES 19 | @property (nonatomic, readonly) CGFloat white; // Only valid if colorSpaceModel == kCGColorSpaceModelMonochrome 20 | @property (nonatomic, readonly) CGFloat alpha; 21 | @property (nonatomic, readonly) UInt32 rgbHex; 22 | 23 | - (NSString *)colorSpaceString; 24 | 25 | - (NSArray *)arrayFromRGBAComponents; 26 | 27 | - (BOOL)red:(CGFloat *)r green:(CGFloat *)g blue:(CGFloat *)b alpha:(CGFloat *)a; 28 | 29 | - (UIColor *)colorByLuminanceMapping; 30 | 31 | - (UIColor *)colorByMultiplyingByRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; 32 | - (UIColor *) colorByAddingRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; 33 | - (UIColor *) colorByLighteningToRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; 34 | - (UIColor *) colorByDarkeningToRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; 35 | 36 | - (UIColor *)colorByMultiplyingBy:(CGFloat)f; 37 | - (UIColor *) colorByAdding:(CGFloat)f; 38 | - (UIColor *) colorByLighteningTo:(CGFloat)f; 39 | - (UIColor *) colorByDarkeningTo:(CGFloat)f; 40 | 41 | - (UIColor *)colorByMultiplyingByColor:(UIColor *)color; 42 | - (UIColor *) colorByAddingColor:(UIColor *)color; 43 | - (UIColor *) colorByLighteningToColor:(UIColor *)color; 44 | - (UIColor *) colorByDarkeningToColor:(UIColor *)color; 45 | 46 | - (NSString *)stringFromColor; 47 | - (NSString *)hexStringFromColor; 48 | 49 | + (UIColor *)randomColor; 50 | + (UIColor *)colorWithString:(NSString *)stringToConvert; 51 | + (UIColor *)colorWithRGBHex:(UInt32)hex; 52 | + (UIColor *)colorWithHexString:(NSString *)stringToConvert; 53 | 54 | + (UIColor *)colorWithName:(NSString *)cssColorName; 55 | 56 | @end 57 | 58 | #if SUPPORTS_UNDOCUMENTED_API 59 | // UIColor_Undocumented_Expanded 60 | // Methods which rely on undocumented methods of UIColor 61 | @interface UIColor (UIColor_Undocumented_Expanded) 62 | - (NSString *)fetchStyleString; 63 | - (UIColor *)rgbColor; // Via Poltras 64 | @end 65 | #endif // SUPPORTS_UNDOCUMENTED_API 66 | -------------------------------------------------------------------------------- /Vurig Calendar/UIColor+expanded.m: -------------------------------------------------------------------------------- 1 | #import "UIColor+Expanded.h" 2 | 3 | /* 4 | 5 | Thanks to Poltras, Millenomi, Eridius, Nownot, WhatAHam, jberry, 6 | and everyone else who helped out but whose name is inadvertantly omitted 7 | 8 | */ 9 | 10 | /* 11 | Current outstanding request list: 12 | 13 | - PolarBearFarm - color descriptions ([UIColor warmGrayWithHintOfBlueTouchOfRedAndSplashOfYellowColor]) 14 | - Crayola color set 15 | - Eridius - UIColor needs a method that takes 2 colors and gives a third complementary one 16 | - Consider UIMutableColor that can be adjusted (brighter, cooler, warmer, thicker-alpha, etc) 17 | */ 18 | 19 | /* 20 | FOR REFERENCE: Color Space Models: enum CGColorSpaceModel { 21 | kCGColorSpaceModelUnknown = -1, 22 | kCGColorSpaceModelMonochrome, 23 | kCGColorSpaceModelRGB, 24 | kCGColorSpaceModelCMYK, 25 | kCGColorSpaceModelLab, 26 | kCGColorSpaceModelDeviceN, 27 | kCGColorSpaceModelIndexed, 28 | kCGColorSpaceModelPattern 29 | }; 30 | */ 31 | 32 | // Static cache of looked up color names. Used with +colorWithName: 33 | static NSMutableDictionary *colorNameCache = nil; 34 | 35 | #if SUPPORTS_UNDOCUMENTED_API 36 | // UIColor_Undocumented 37 | // Undocumented methods of UIColor 38 | @interface UIColor (UIColor_Undocumented) 39 | - (NSString *)styleString; 40 | @end 41 | #endif // SUPPORTS_UNDOCUMENTED_API 42 | 43 | @interface UIColor (UIColor_Expanded_Support) 44 | + (UIColor *)searchForColorByName:(NSString *)cssColorName; 45 | @end 46 | 47 | #pragma mark - 48 | 49 | @implementation UIColor (UIColor_Expanded) 50 | 51 | - (CGColorSpaceModel)colorSpaceModel { 52 | return CGColorSpaceGetModel(CGColorGetColorSpace(self.CGColor)); 53 | } 54 | 55 | - (NSString *)colorSpaceString { 56 | switch (self.colorSpaceModel) { 57 | case kCGColorSpaceModelUnknown: 58 | return @"kCGColorSpaceModelUnknown"; 59 | case kCGColorSpaceModelMonochrome: 60 | return @"kCGColorSpaceModelMonochrome"; 61 | case kCGColorSpaceModelRGB: 62 | return @"kCGColorSpaceModelRGB"; 63 | case kCGColorSpaceModelCMYK: 64 | return @"kCGColorSpaceModelCMYK"; 65 | case kCGColorSpaceModelLab: 66 | return @"kCGColorSpaceModelLab"; 67 | case kCGColorSpaceModelDeviceN: 68 | return @"kCGColorSpaceModelDeviceN"; 69 | case kCGColorSpaceModelIndexed: 70 | return @"kCGColorSpaceModelIndexed"; 71 | case kCGColorSpaceModelPattern: 72 | return @"kCGColorSpaceModelPattern"; 73 | default: 74 | return @"Not a valid color space"; 75 | } 76 | } 77 | 78 | - (BOOL)canProvideRGBComponents { 79 | switch (self.colorSpaceModel) { 80 | case kCGColorSpaceModelRGB: 81 | case kCGColorSpaceModelMonochrome: 82 | return YES; 83 | default: 84 | return NO; 85 | } 86 | } 87 | 88 | - (NSArray *)arrayFromRGBAComponents { 89 | NSAssert(self.canProvideRGBComponents, @"Must be an RGB color to use -arrayFromRGBAComponents"); 90 | 91 | CGFloat r,g,b,a; 92 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 93 | 94 | return [NSArray arrayWithObjects: 95 | [NSNumber numberWithFloat:r], 96 | [NSNumber numberWithFloat:g], 97 | [NSNumber numberWithFloat:b], 98 | [NSNumber numberWithFloat:a], 99 | nil]; 100 | } 101 | 102 | - (BOOL)red:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha { 103 | const CGFloat *components = CGColorGetComponents(self.CGColor); 104 | 105 | CGFloat r,g,b,a; 106 | 107 | switch (self.colorSpaceModel) { 108 | case kCGColorSpaceModelMonochrome: 109 | r = g = b = components[0]; 110 | a = components[1]; 111 | break; 112 | case kCGColorSpaceModelRGB: 113 | r = components[0]; 114 | g = components[1]; 115 | b = components[2]; 116 | a = components[3]; 117 | break; 118 | default: // We don't know how to handle this model 119 | return NO; 120 | } 121 | 122 | if (red) *red = r; 123 | if (green) *green = g; 124 | if (blue) *blue = b; 125 | if (alpha) *alpha = a; 126 | 127 | return YES; 128 | } 129 | 130 | - (CGFloat)red { 131 | NSAssert(self.canProvideRGBComponents, @"Must be an RGB color to use -red"); 132 | const CGFloat *c = CGColorGetComponents(self.CGColor); 133 | return c[0]; 134 | } 135 | 136 | - (CGFloat)green { 137 | NSAssert(self.canProvideRGBComponents, @"Must be an RGB color to use -green"); 138 | const CGFloat *c = CGColorGetComponents(self.CGColor); 139 | if (self.colorSpaceModel == kCGColorSpaceModelMonochrome) return c[0]; 140 | return c[1]; 141 | } 142 | 143 | - (CGFloat)blue { 144 | NSAssert(self.canProvideRGBComponents, @"Must be an RGB color to use -blue"); 145 | const CGFloat *c = CGColorGetComponents(self.CGColor); 146 | if (self.colorSpaceModel == kCGColorSpaceModelMonochrome) return c[0]; 147 | return c[2]; 148 | } 149 | 150 | - (CGFloat)white { 151 | NSAssert(self.colorSpaceModel == kCGColorSpaceModelMonochrome, @"Must be a Monochrome color to use -white"); 152 | const CGFloat *c = CGColorGetComponents(self.CGColor); 153 | return c[0]; 154 | } 155 | 156 | - (CGFloat)alpha { 157 | return CGColorGetAlpha(self.CGColor); 158 | } 159 | 160 | - (UInt32)rgbHex { 161 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use rgbHex"); 162 | 163 | CGFloat r,g,b,a; 164 | if (![self red:&r green:&g blue:&b alpha:&a]) return 0; 165 | 166 | r = MIN(MAX(self.red, 0.0f), 1.0f); 167 | g = MIN(MAX(self.green, 0.0f), 1.0f); 168 | b = MIN(MAX(self.blue, 0.0f), 1.0f); 169 | 170 | return (((int)roundf(r * 255)) << 16) 171 | | (((int)roundf(g * 255)) << 8) 172 | | (((int)roundf(b * 255))); 173 | } 174 | 175 | #pragma mark Arithmetic operations 176 | 177 | - (UIColor *)colorByLuminanceMapping { 178 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 179 | 180 | CGFloat r,g,b,a; 181 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 182 | 183 | // http://en.wikipedia.org/wiki/Luma_(video) 184 | // Y = 0.2126 R + 0.7152 G + 0.0722 B 185 | return [UIColor colorWithWhite:r*0.2126f + g*0.7152f + b*0.0722f 186 | alpha:a]; 187 | 188 | } 189 | 190 | - (UIColor *)colorByMultiplyingByRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { 191 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 192 | 193 | CGFloat r,g,b,a; 194 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 195 | 196 | return [UIColor colorWithRed:MAX(0.0, MIN(1.0, r * red)) 197 | green:MAX(0.0, MIN(1.0, g * green)) 198 | blue:MAX(0.0, MIN(1.0, b * blue)) 199 | alpha:MAX(0.0, MIN(1.0, a * alpha))]; 200 | } 201 | 202 | - (UIColor *)colorByAddingRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { 203 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 204 | 205 | CGFloat r,g,b,a; 206 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 207 | 208 | return [UIColor colorWithRed:MAX(0.0, MIN(1.0, r + red)) 209 | green:MAX(0.0, MIN(1.0, g + green)) 210 | blue:MAX(0.0, MIN(1.0, b + blue)) 211 | alpha:MAX(0.0, MIN(1.0, a + alpha))]; 212 | } 213 | 214 | - (UIColor *)colorByLighteningToRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { 215 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 216 | 217 | CGFloat r,g,b,a; 218 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 219 | 220 | return [UIColor colorWithRed:MAX(r, red) 221 | green:MAX(g, green) 222 | blue:MAX(b, blue) 223 | alpha:MAX(a, alpha)]; 224 | } 225 | 226 | - (UIColor *)colorByDarkeningToRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { 227 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 228 | 229 | CGFloat r,g,b,a; 230 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 231 | 232 | return [UIColor colorWithRed:MIN(r, red) 233 | green:MIN(g, green) 234 | blue:MIN(b, blue) 235 | alpha:MIN(a, alpha)]; 236 | } 237 | 238 | - (UIColor *)colorByMultiplyingBy:(CGFloat)f { 239 | return [self colorByMultiplyingByRed:f green:f blue:f alpha:1.0f]; 240 | } 241 | 242 | - (UIColor *)colorByAdding:(CGFloat)f { 243 | return [self colorByMultiplyingByRed:f green:f blue:f alpha:0.0f]; 244 | } 245 | 246 | - (UIColor *)colorByLighteningTo:(CGFloat)f { 247 | return [self colorByLighteningToRed:f green:f blue:f alpha:0.0f]; 248 | } 249 | 250 | - (UIColor *)colorByDarkeningTo:(CGFloat)f { 251 | return [self colorByDarkeningToRed:f green:f blue:f alpha:1.0f]; 252 | } 253 | 254 | - (UIColor *)colorByMultiplyingByColor:(UIColor *)color { 255 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 256 | 257 | CGFloat r,g,b,a; 258 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 259 | 260 | return [self colorByMultiplyingByRed:r green:g blue:b alpha:1.0f]; 261 | } 262 | 263 | - (UIColor *)colorByAddingColor:(UIColor *)color { 264 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 265 | 266 | CGFloat r,g,b,a; 267 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 268 | 269 | return [self colorByAddingRed:r green:g blue:b alpha:0.0f]; 270 | } 271 | 272 | - (UIColor *)colorByLighteningToColor:(UIColor *)color { 273 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 274 | 275 | CGFloat r,g,b,a; 276 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 277 | 278 | return [self colorByLighteningToRed:r green:g blue:b alpha:0.0f]; 279 | } 280 | 281 | - (UIColor *)colorByDarkeningToColor:(UIColor *)color { 282 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 283 | 284 | CGFloat r,g,b,a; 285 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 286 | 287 | return [self colorByDarkeningToRed:r green:g blue:b alpha:1.0f]; 288 | } 289 | 290 | #pragma mark String utilities 291 | 292 | - (NSString *)stringFromColor { 293 | NSAssert(self.canProvideRGBComponents, @"Must be an RGB color to use -stringFromColor"); 294 | NSString *result; 295 | switch (self.colorSpaceModel) { 296 | case kCGColorSpaceModelRGB: 297 | result = [NSString stringWithFormat:@"{%0.3f, %0.3f, %0.3f, %0.3f}", self.red, self.green, self.blue, self.alpha]; 298 | break; 299 | case kCGColorSpaceModelMonochrome: 300 | result = [NSString stringWithFormat:@"{%0.3f, %0.3f}", self.white, self.alpha]; 301 | break; 302 | default: 303 | result = nil; 304 | } 305 | return result; 306 | } 307 | 308 | - (NSString *)hexStringFromColor { 309 | return [NSString stringWithFormat:@"%0.6X", self.rgbHex]; 310 | } 311 | 312 | + (UIColor *)colorWithString:(NSString *)stringToConvert { 313 | NSScanner *scanner = [NSScanner scannerWithString:stringToConvert]; 314 | if (![scanner scanString:@"{" intoString:NULL]) return nil; 315 | const NSUInteger kMaxComponents = 4; 316 | CGFloat c[kMaxComponents]; 317 | NSUInteger i = 0; 318 | if (![scanner scanFloat:&c[i++]]) return nil; 319 | while (1) { 320 | if ([scanner scanString:@"}" intoString:NULL]) break; 321 | if (i >= kMaxComponents) return nil; 322 | if ([scanner scanString:@"," intoString:NULL]) { 323 | if (![scanner scanFloat:&c[i++]]) return nil; 324 | } else { 325 | // either we're at the end of there's an unexpected character here 326 | // both cases are error conditions 327 | return nil; 328 | } 329 | } 330 | if (![scanner isAtEnd]) return nil; 331 | UIColor *color; 332 | switch (i) { 333 | case 2: // monochrome 334 | color = [UIColor colorWithWhite:c[0] alpha:c[1]]; 335 | break; 336 | case 4: // RGB 337 | color = [UIColor colorWithRed:c[0] green:c[1] blue:c[2] alpha:c[3]]; 338 | break; 339 | default: 340 | color = nil; 341 | } 342 | return color; 343 | } 344 | 345 | #pragma mark Class methods 346 | 347 | + (UIColor *)randomColor { 348 | return [UIColor colorWithRed:(CGFloat)RAND_MAX / random() 349 | green:(CGFloat)RAND_MAX / random() 350 | blue:(CGFloat)RAND_MAX / random() 351 | alpha:1.0f]; 352 | } 353 | 354 | + (UIColor *)colorWithRGBHex:(UInt32)hex { 355 | int r = (hex >> 16) & 0xFF; 356 | int g = (hex >> 8) & 0xFF; 357 | int b = (hex) & 0xFF; 358 | 359 | return [UIColor colorWithRed:r / 255.0f 360 | green:g / 255.0f 361 | blue:b / 255.0f 362 | alpha:1.0f]; 363 | } 364 | 365 | // Returns a UIColor by scanning the string for a hex number and passing that to +[UIColor colorWithRGBHex:] 366 | // Skips any leading whitespace and ignores any trailing characters 367 | + (UIColor *)colorWithHexString:(NSString *)stringToConvert { 368 | NSScanner *scanner = [NSScanner scannerWithString:stringToConvert]; 369 | unsigned hexNum; 370 | if (![scanner scanHexInt:&hexNum]) return nil; 371 | return [UIColor colorWithRGBHex:hexNum]; 372 | } 373 | 374 | // Lookup a color using css 3/svg color name 375 | + (UIColor *)colorWithName:(NSString *)cssColorName { 376 | UIColor *color; 377 | @synchronized(colorNameCache) { 378 | // Look for the color in the cache 379 | color = [colorNameCache objectForKey:cssColorName]; 380 | 381 | if ((id)color == [NSNull null]) { 382 | // If it wasn't there previously, it's still not there now 383 | color = nil; 384 | } else if (!color) { 385 | // Color not in cache, so search for it now 386 | color = [self searchForColorByName:cssColorName]; 387 | 388 | // Set the value in cache, storing NSNull on failure 389 | [colorNameCache setObject:(color ?: (id)[NSNull null]) 390 | forKey:cssColorName]; 391 | } 392 | } 393 | 394 | return color; 395 | } 396 | 397 | #pragma mark UIColor_Expanded initialization 398 | 399 | + (void)load { 400 | colorNameCache = [[NSMutableDictionary alloc] init]; 401 | } 402 | 403 | @end 404 | 405 | #pragma mark - 406 | 407 | #if SUPPORTS_UNDOCUMENTED_API 408 | @implementation UIColor (UIColor_Undocumented_Expanded) 409 | - (NSString *)fetchStyleString { 410 | return [self styleString]; 411 | } 412 | 413 | // Convert a color into RGB Color space, courtesy of Poltras 414 | // via http://ofcodeandmen.poltras.com/2009/01/22/convert-a-cgcolorref-to-another-cgcolorspaceref/ 415 | // 416 | - (UIColor *)rgbColor { 417 | // Call to undocumented method "styleString". 418 | NSString *style = [self styleString]; 419 | NSScanner *scanner = [NSScanner scannerWithString:style]; 420 | CGFloat red, green, blue; 421 | if (![scanner scanString:@"rgb(" intoString:NULL]) return nil; 422 | if (![scanner scanFloat:&red]) return nil; 423 | if (![scanner scanString:@"," intoString:NULL]) return nil; 424 | if (![scanner scanFloat:&green]) return nil; 425 | if (![scanner scanString:@"," intoString:NULL]) return nil; 426 | if (![scanner scanFloat:&blue]) return nil; 427 | if (![scanner scanString:@")" intoString:NULL]) return nil; 428 | if (![scanner isAtEnd]) return nil; 429 | 430 | return [UIColor colorWithRed:red green:green blue:blue alpha:self.alpha]; 431 | } 432 | @end 433 | #endif // SUPPORTS_UNDOCUMENTED_API 434 | 435 | @implementation UIColor (UIColor_Expanded_Support) 436 | /* 437 | * Database of color names and hex rgb values, derived 438 | * from the css 3 color spec: 439 | * http://www.w3.org/TR/css3-color/ 440 | * 441 | * We think this is a very compact way of storing 442 | * this information, and relatively cheap to lookup. 443 | * 444 | * Note that we search for color names starting with ',' 445 | * and terminated by '#', so that we don't get false matches. 446 | * For this reason, the database begins with ','. 447 | */ 448 | static const char *colorNameDB = "," 449 | "aliceblue#f0f8ff,antiquewhite#faebd7,aqua#00ffff,aquamarine#7fffd4,azure#f0ffff," 450 | "beige#f5f5dc,bisque#ffe4c4,black#000000,blanchedalmond#ffebcd,blue#0000ff," 451 | "blueviolet#8a2be2,brown#a52a2a,burlywood#deb887,cadetblue#5f9ea0,chartreuse#7fff00," 452 | "chocolate#d2691e,coral#ff7f50,cornflowerblue#6495ed,cornsilk#fff8dc,crimson#dc143c," 453 | "cyan#00ffff,darkblue#00008b,darkcyan#008b8b,darkgoldenrod#b8860b,darkgray#a9a9a9," 454 | "darkgreen#006400,darkgrey#a9a9a9,darkkhaki#bdb76b,darkmagenta#8b008b," 455 | "darkolivegreen#556b2f,darkorange#ff8c00,darkorchid#9932cc,darkred#8b0000," 456 | "darksalmon#e9967a,darkseagreen#8fbc8f,darkslateblue#483d8b,darkslategray#2f4f4f," 457 | "darkslategrey#2f4f4f,darkturquoise#00ced1,darkviolet#9400d3,deeppink#ff1493," 458 | "deepskyblue#00bfff,dimgray#696969,dimgrey#696969,dodgerblue#1e90ff," 459 | "firebrick#b22222,floralwhite#fffaf0,forestgreen#228b22,fuchsia#ff00ff," 460 | "gainsboro#dcdcdc,ghostwhite#f8f8ff,gold#ffd700,goldenrod#daa520,gray#808080," 461 | "green#008000,greenyellow#adff2f,grey#808080,honeydew#f0fff0,hotpink#ff69b4," 462 | "indianred#cd5c5c,indigo#4b0082,ivory#fffff0,khaki#f0e68c,lavender#e6e6fa," 463 | "lavenderblush#fff0f5,lawngreen#7cfc00,lemonchiffon#fffacd,lightblue#add8e6," 464 | "lightcoral#f08080,lightcyan#e0ffff,lightgoldenrodyellow#fafad2,lightgray#d3d3d3," 465 | "lightgreen#90ee90,lightgrey#d3d3d3,lightpink#ffb6c1,lightsalmon#ffa07a," 466 | "lightseagreen#20b2aa,lightskyblue#87cefa,lightslategray#778899," 467 | "lightslategrey#778899,lightsteelblue#b0c4de,lightyellow#ffffe0,lime#00ff00," 468 | "limegreen#32cd32,linen#faf0e6,magenta#ff00ff,maroon#800000,mediumaquamarine#66cdaa," 469 | "mediumblue#0000cd,mediumorchid#ba55d3,mediumpurple#9370db,mediumseagreen#3cb371," 470 | "mediumslateblue#7b68ee,mediumspringgreen#00fa9a,mediumturquoise#48d1cc," 471 | "mediumvioletred#c71585,midnightblue#191970,mintcream#f5fffa,mistyrose#ffe4e1," 472 | "moccasin#ffe4b5,navajowhite#ffdead,navy#000080,oldlace#fdf5e6,olive#808000," 473 | "olivedrab#6b8e23,orange#ffa500,orangered#ff4500,orchid#da70d6,palegoldenrod#eee8aa," 474 | "palegreen#98fb98,paleturquoise#afeeee,palevioletred#db7093,papayawhip#ffefd5," 475 | "peachpuff#ffdab9,peru#cd853f,pink#ffc0cb,plum#dda0dd,powderblue#b0e0e6," 476 | "purple#800080,red#ff0000,rosybrown#bc8f8f,royalblue#4169e1,saddlebrown#8b4513," 477 | "salmon#fa8072,sandybrown#f4a460,seagreen#2e8b57,seashell#fff5ee,sienna#a0522d," 478 | "silver#c0c0c0,skyblue#87ceeb,slateblue#6a5acd,slategray#708090,slategrey#708090," 479 | "snow#fffafa,springgreen#00ff7f,steelblue#4682b4,tan#d2b48c,teal#008080," 480 | "thistle#d8bfd8,tomato#ff6347,turquoise#40e0d0,violet#ee82ee,wheat#f5deb3," 481 | "white#ffffff,whitesmoke#f5f5f5,yellow#ffff00,yellowgreen#9acd32"; 482 | 483 | + (UIColor *)searchForColorByName:(NSString *)cssColorName { 484 | UIColor *result = nil; 485 | 486 | // Compile the string we'll use to search against the database 487 | // We search for ",#" to avoid false matches 488 | const char *searchString = [[NSString stringWithFormat:@",%@#", cssColorName] UTF8String]; 489 | 490 | // Search for the color name 491 | const char *found = strstr(colorNameDB, searchString); 492 | 493 | // If found, step past the search string and grab the hex representation 494 | if (found) { 495 | const char *after = found + strlen(searchString); 496 | int hex; 497 | if (sscanf(after, "%x", &hex) == 1) { 498 | result = [self colorWithRGBHex:hex]; 499 | } 500 | } 501 | 502 | return result; 503 | } 504 | @end 505 | -------------------------------------------------------------------------------- /Vurig Calendar/UIView+convenience.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+convenience.h 3 | // 4 | // Created by Tjeerd in 't Veen on 12/1/11. 5 | // Copyright (c) 2011 Vurig Media. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface UIView (convenience) 11 | 12 | @property (nonatomic) CGPoint frameOrigin; 13 | @property (nonatomic) CGSize frameSize; 14 | 15 | @property (nonatomic) CGFloat frameX; 16 | @property (nonatomic) CGFloat frameY; 17 | 18 | // Setting these modifies the origin but not the size. 19 | @property (nonatomic) CGFloat frameRight; 20 | @property (nonatomic) CGFloat frameBottom; 21 | 22 | @property (nonatomic) CGFloat frameWidth; 23 | @property (nonatomic) CGFloat frameHeight; 24 | 25 | -(BOOL) containsSubView:(UIView *)subView; 26 | -(BOOL) containsSubViewOfClassType:(Class)class; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Vurig Calendar/UIView+convenience.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+convenience.m 3 | // 4 | // Created by Tjeerd in 't Veen on 12/1/11. 5 | // Copyright (c) 2011 Vurig Media. All rights reserved. 6 | // 7 | 8 | #import "UIView+convenience.h" 9 | 10 | @implementation UIView (convenience) 11 | 12 | -(BOOL) containsSubView:(UIView *)subView 13 | { 14 | for (UIView *view in [self subviews]) { 15 | if ([view isEqual:subView]) { 16 | return YES; 17 | } 18 | } 19 | return NO; 20 | } 21 | 22 | -(BOOL) containsSubViewOfClassType:(Class)class { 23 | for (UIView *view in [self subviews]) { 24 | if ([view isMemberOfClass:class]) { 25 | return YES; 26 | } 27 | } 28 | return NO; 29 | } 30 | 31 | - (CGPoint)frameOrigin { 32 | return self.frame.origin; 33 | } 34 | 35 | - (void)setFrameOrigin:(CGPoint)newOrigin { 36 | self.frame = CGRectMake(newOrigin.x, newOrigin.y, self.frame.size.width, self.frame.size.height); 37 | } 38 | 39 | - (CGSize)frameSize { 40 | return self.frame.size; 41 | } 42 | 43 | - (void)setFrameSize:(CGSize)newSize { 44 | self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, 45 | newSize.width, newSize.height); 46 | } 47 | 48 | - (CGFloat)frameX { 49 | return self.frame.origin.x; 50 | } 51 | 52 | - (void)setFrameX:(CGFloat)newX { 53 | self.frame = CGRectMake(newX, self.frame.origin.y, 54 | self.frame.size.width, self.frame.size.height); 55 | } 56 | 57 | - (CGFloat)frameY { 58 | return self.frame.origin.y; 59 | } 60 | 61 | - (void)setFrameY:(CGFloat)newY { 62 | self.frame = CGRectMake(self.frame.origin.x, newY, 63 | self.frame.size.width, self.frame.size.height); 64 | } 65 | 66 | - (CGFloat)frameRight { 67 | return self.frame.origin.x + self.frame.size.width; 68 | } 69 | 70 | - (void)setFrameRight:(CGFloat)newRight { 71 | self.frame = CGRectMake(newRight - self.frame.size.width, self.frame.origin.y, 72 | self.frame.size.width, self.frame.size.height); 73 | } 74 | 75 | - (CGFloat)frameBottom { 76 | return self.frame.origin.y + self.frame.size.height; 77 | } 78 | 79 | - (void)setFrameBottom:(CGFloat)newBottom { 80 | self.frame = CGRectMake(self.frame.origin.x, newBottom - self.frame.size.height, 81 | self.frame.size.width, self.frame.size.height); 82 | } 83 | 84 | - (CGFloat)frameWidth { 85 | return self.frame.size.width; 86 | } 87 | 88 | - (void)setFrameWidth:(CGFloat)newWidth { 89 | self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, 90 | newWidth, self.frame.size.height); 91 | } 92 | 93 | - (CGFloat)frameHeight { 94 | return self.frame.size.height; 95 | } 96 | 97 | - (void)setFrameHeight:(CGFloat)newHeight { 98 | self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, 99 | self.frame.size.width, newHeight); 100 | } 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /Vurig Calendar/VRGAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // VRGAppDelegate.h 3 | // Vurig Calendar 4 | // 5 | // Created by in 't Veen Tjeerd on 5/29/12. 6 | // Copyright (c) 2012 Vurig. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class VRGViewController; 12 | 13 | @interface VRGAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) VRGViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Vurig Calendar/VRGAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // VRGAppDelegate.m 3 | // Vurig Calendar 4 | // 5 | // Created by in 't Veen Tjeerd on 5/29/12. 6 | // Copyright (c) 2012 Vurig. All rights reserved. 7 | // 8 | 9 | #import "VRGAppDelegate.h" 10 | 11 | #import "VRGViewController.h" 12 | 13 | @implementation VRGAppDelegate 14 | 15 | @synthesize window = _window; 16 | @synthesize viewController = _viewController; 17 | 18 | - (void)dealloc 19 | { 20 | [_window release]; 21 | [_viewController release]; 22 | [super dealloc]; 23 | } 24 | 25 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 26 | { 27 | self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; 28 | // Override point for customization after application launch. 29 | self.viewController = [[[VRGViewController alloc] initWithNibName:@"VRGViewController" bundle:nil] autorelease]; 30 | self.window.rootViewController = self.viewController; 31 | [self.window makeKeyAndVisible]; 32 | return YES; 33 | } 34 | 35 | - (void)applicationWillResignActive:(UIApplication *)application 36 | { 37 | // 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. 38 | // 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. 39 | } 40 | 41 | - (void)applicationDidEnterBackground:(UIApplication *)application 42 | { 43 | // 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. 44 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 45 | } 46 | 47 | - (void)applicationWillEnterForeground:(UIApplication *)application 48 | { 49 | // 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. 50 | } 51 | 52 | - (void)applicationDidBecomeActive:(UIApplication *)application 53 | { 54 | // 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. 55 | } 56 | 57 | - (void)applicationWillTerminate:(UIApplication *)application 58 | { 59 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Vurig Calendar/VRGCalendarView.h: -------------------------------------------------------------------------------- 1 | // 2 | // VRGCalendarView.h 3 | // Vurig 4 | // 5 | // Created by in 't Veen Tjeerd on 5/8/12. 6 | // Copyright (c) 2012 Vurig Media. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | #import "UIColor+expanded.h" 12 | 13 | #define kVRGCalendarViewTopBarHeight 60 14 | #define kVRGCalendarViewWidth 320 15 | 16 | #define kVRGCalendarViewDayWidth 44 17 | #define kVRGCalendarViewDayHeight 44 18 | 19 | @protocol VRGCalendarViewDelegate; 20 | @interface VRGCalendarView : UIView { 21 | id delegate; 22 | 23 | NSDate *currentMonth; 24 | 25 | UILabel *labelCurrentMonth; 26 | 27 | BOOL isAnimating; 28 | BOOL prepAnimationPreviousMonth; 29 | BOOL prepAnimationNextMonth; 30 | 31 | UIImageView *animationView_A; 32 | UIImageView *animationView_B; 33 | 34 | NSArray *markedDates; 35 | NSArray *markedColors; 36 | } 37 | 38 | @property (nonatomic, retain) id delegate; 39 | @property (nonatomic, retain) NSDate *currentMonth; 40 | @property (nonatomic, retain) UILabel *labelCurrentMonth; 41 | @property (nonatomic, retain) UIImageView *animationView_A; 42 | @property (nonatomic, retain) UIImageView *animationView_B; 43 | @property (nonatomic, retain) NSArray *markedDates; 44 | @property (nonatomic, retain) NSArray *markedColors; 45 | @property (nonatomic, getter = calendarHeight) float calendarHeight; 46 | @property (nonatomic, retain, getter = selectedDate) NSDate *selectedDate; 47 | 48 | -(void)selectDate:(int)date; 49 | -(void)reset; 50 | 51 | -(void)markDates:(NSArray *)dates; 52 | -(void)markDates:(NSArray *)dates withColors:(NSArray *)colors; 53 | 54 | -(void)showNextMonth; 55 | -(void)showPreviousMonth; 56 | 57 | -(int)numRows; 58 | -(void)updateSize; 59 | -(UIImage *)drawCurrentState; 60 | 61 | @end 62 | 63 | @protocol VRGCalendarViewDelegate 64 | -(void)calendarView:(VRGCalendarView *)calendarView switchedToMonth:(int)month targetHeight:(float)targetHeight animated:(BOOL)animated; 65 | -(void)calendarView:(VRGCalendarView *)calendarView dateSelected:(NSDate *)date; 66 | @end 67 | -------------------------------------------------------------------------------- /Vurig Calendar/VRGCalendarView.m: -------------------------------------------------------------------------------- 1 | // 2 | // VRGCalendarView.m 3 | // Vurig 4 | // 5 | // Created by in 't Veen Tjeerd on 5/8/12. 6 | // Copyright (c) 2012 Vurig Media. All rights reserved. 7 | // 8 | 9 | #import "VRGCalendarView.h" 10 | #import 11 | #import "NSDate+convenience.h" 12 | #import "NSMutableArray+convenience.h" 13 | #import "UIView+convenience.h" 14 | 15 | @implementation VRGCalendarView 16 | @synthesize currentMonth,delegate,labelCurrentMonth, animationView_A,animationView_B; 17 | @synthesize markedDates,markedColors,calendarHeight,selectedDate; 18 | 19 | #pragma mark - Select Date 20 | -(void)selectDate:(int)date { 21 | NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 22 | NSDateComponents *comps = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:self.currentMonth]; 23 | [comps setDay:date]; 24 | self.selectedDate = [gregorian dateFromComponents:comps]; 25 | 26 | int selectedDateYear = [selectedDate year]; 27 | int selectedDateMonth = [selectedDate month]; 28 | int currentMonthYear = [currentMonth year]; 29 | int currentMonthMonth = [currentMonth month]; 30 | 31 | if (selectedDateYear < currentMonthYear) { 32 | [self showPreviousMonth]; 33 | } else if (selectedDateYear > currentMonthYear) { 34 | [self showNextMonth]; 35 | } else if (selectedDateMonth < currentMonthMonth) { 36 | [self showPreviousMonth]; 37 | } else if (selectedDateMonth > currentMonthMonth) { 38 | [self showNextMonth]; 39 | } else { 40 | [self setNeedsDisplay]; 41 | } 42 | 43 | if ([delegate respondsToSelector:@selector(calendarView:dateSelected:)]) [delegate calendarView:self dateSelected:self.selectedDate]; 44 | } 45 | 46 | #pragma mark - Mark Dates 47 | //NSArray can either contain NSDate objects or NSNumber objects with an int of the day. 48 | -(void)markDates:(NSArray *)dates { 49 | self.markedDates = dates; 50 | NSMutableArray *colors = [[NSMutableArray alloc] init]; 51 | 52 | for (int i = 0; i<[dates count]; i++) { 53 | [colors addObject:[UIColor colorWithHexString:@"0x383838"]]; 54 | } 55 | 56 | self.markedColors = [NSArray arrayWithArray:colors]; 57 | [colors release]; 58 | 59 | [self setNeedsDisplay]; 60 | } 61 | 62 | //NSArray can either contain NSDate objects or NSNumber objects with an int of the day. 63 | -(void)markDates:(NSArray *)dates withColors:(NSArray *)colors { 64 | self.markedDates = dates; 65 | self.markedColors = colors; 66 | 67 | [self setNeedsDisplay]; 68 | } 69 | 70 | #pragma mark - Set date to now 71 | -(void)reset { 72 | NSCalendar *gregorian = [[NSCalendar alloc] 73 | initWithCalendarIdentifier:NSGregorianCalendar]; 74 | NSDateComponents *components = 75 | [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | 76 | NSDayCalendarUnit) fromDate: [NSDate date]]; 77 | self.currentMonth = [gregorian dateFromComponents:components]; //clean month 78 | 79 | [self updateSize]; 80 | [self setNeedsDisplay]; 81 | [delegate calendarView:self switchedToMonth:[currentMonth month] targetHeight:self.calendarHeight animated:NO]; 82 | } 83 | 84 | #pragma mark - Next & Previous 85 | -(void)showNextMonth { 86 | if (isAnimating) return; 87 | self.markedDates=nil; 88 | isAnimating=YES; 89 | prepAnimationNextMonth=YES; 90 | 91 | [self setNeedsDisplay]; 92 | 93 | int lastBlock = [currentMonth firstWeekDayInMonth]+[currentMonth numDaysInMonth]-1; 94 | int numBlocks = [self numRows]*7; 95 | BOOL hasNextMonthDays = lastBlock1; 158 | float oldSize = self.calendarHeight; 159 | UIImage *imageCurrentMonth = [self drawCurrentState]; 160 | 161 | //Prepare next screen 162 | self.currentMonth = [currentMonth offsetMonth:-1]; 163 | if ([delegate respondsToSelector:@selector(calendarView:switchedToMonth:targetHeight:animated:)]) [delegate calendarView:self switchedToMonth:[currentMonth month] targetHeight:self.calendarHeight animated:YES]; 164 | prepAnimationPreviousMonth=NO; 165 | [self setNeedsDisplay]; 166 | UIImage *imagePreviousMonth = [self drawCurrentState]; 167 | 168 | float targetSize = fmaxf(oldSize, self.calendarHeight); 169 | UIView *animationHolder = [[UIView alloc] initWithFrame:CGRectMake(0, kVRGCalendarViewTopBarHeight, kVRGCalendarViewWidth, targetSize-kVRGCalendarViewTopBarHeight)]; 170 | 171 | [animationHolder setClipsToBounds:YES]; 172 | [self addSubview:animationHolder]; 173 | [animationHolder release]; 174 | 175 | self.animationView_A = [[UIImageView alloc] initWithImage:imageCurrentMonth]; 176 | self.animationView_B = [[UIImageView alloc] initWithImage:imagePreviousMonth]; 177 | [animationHolder addSubview:animationView_A]; 178 | [animationHolder addSubview:animationView_B]; 179 | 180 | if (hasPreviousDays) { 181 | animationView_B.frameY = animationView_A.frameY - (animationView_B.frameHeight-kVRGCalendarViewDayHeight) + 3; 182 | } else { 183 | animationView_B.frameY = animationView_A.frameY - animationView_B.frameHeight + 3; 184 | } 185 | 186 | __block VRGCalendarView *blockSafeSelf = self; 187 | [UIView animateWithDuration:.35 188 | animations:^{ 189 | [self updateSize]; 190 | 191 | if (hasPreviousDays) { 192 | animationView_A.frameY = animationView_B.frameHeight-(kVRGCalendarViewDayHeight+3); 193 | 194 | } else { 195 | animationView_A.frameY = animationView_B.frameHeight-3; 196 | } 197 | 198 | animationView_B.frameY = 0; 199 | } 200 | completion:^(BOOL finished) { 201 | [animationView_A removeFromSuperview]; 202 | [animationView_B removeFromSuperview]; 203 | blockSafeSelf.animationView_A=nil; 204 | blockSafeSelf.animationView_B=nil; 205 | isAnimating=NO; 206 | [animationHolder removeFromSuperview]; 207 | } 208 | ]; 209 | } 210 | 211 | 212 | #pragma mark - update size & row count 213 | -(void)updateSize { 214 | self.frameHeight = self.calendarHeight; 215 | [self setNeedsDisplay]; 216 | } 217 | 218 | -(float)calendarHeight { 219 | return kVRGCalendarViewTopBarHeight + [self numRows]*(kVRGCalendarViewDayHeight+2)+1; 220 | } 221 | 222 | -(int)numRows { 223 | float lastBlock = [self.currentMonth numDaysInMonth]+([self.currentMonth firstWeekDayInMonth]-1); 224 | return ceilf(lastBlock/7); 225 | } 226 | 227 | #pragma mark - Touches 228 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 229 | { 230 | UITouch *touch = [touches anyObject]; 231 | CGPoint touchPoint = [touch locationInView:self]; 232 | 233 | self.selectedDate=nil; 234 | 235 | //Touch a specific day 236 | if (touchPoint.y > kVRGCalendarViewTopBarHeight) { 237 | float xLocation = touchPoint.x; 238 | float yLocation = touchPoint.y-kVRGCalendarViewTopBarHeight; 239 | 240 | int column = floorf(xLocation/(kVRGCalendarViewDayWidth+2)); 241 | int row = floorf(yLocation/(kVRGCalendarViewDayHeight+2)); 242 | 243 | int blockNr = (column+1)+row*7; 244 | int firstWeekDay = [self.currentMonth firstWeekDayInMonth]-1; //-1 because weekdays begin at 1, not 0 245 | int date = blockNr-firstWeekDay; 246 | [self selectDate:date]; 247 | return; 248 | } 249 | 250 | self.markedDates=nil; 251 | self.markedColors=nil; 252 | 253 | CGRect rectArrowLeft = CGRectMake(0, 0, 50, 40); 254 | CGRect rectArrowRight = CGRectMake(self.frame.size.width-50, 0, 50, 40); 255 | 256 | //Touch either arrows or month in middle 257 | if (CGRectContainsPoint(rectArrowLeft, touchPoint)) { 258 | [self showPreviousMonth]; 259 | } else if (CGRectContainsPoint(rectArrowRight, touchPoint)) { 260 | [self showNextMonth]; 261 | } else if (CGRectContainsPoint(self.labelCurrentMonth.frame, touchPoint)) { 262 | //Detect touch in current month 263 | int currentMonthIndex = [self.currentMonth month]; 264 | int todayMonth = [[NSDate date] month]; 265 | [self reset]; 266 | if ((todayMonth!=currentMonthIndex) && [delegate respondsToSelector:@selector(calendarView:switchedToMonth:targetHeight:animated:)]) [delegate calendarView:self switchedToMonth:[currentMonth month] targetHeight:self.calendarHeight animated:NO]; 267 | } 268 | } 269 | 270 | #pragma mark - Drawing 271 | - (void)drawRect:(CGRect)rect 272 | { 273 | int firstWeekDay = [self.currentMonth firstWeekDayInMonth]-1; //-1 because weekdays begin at 1, not 0 274 | 275 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 276 | [formatter setDateFormat:@"MMMM yyyy"]; 277 | labelCurrentMonth.text = [formatter stringFromDate:self.currentMonth]; 278 | [labelCurrentMonth sizeToFit]; 279 | labelCurrentMonth.frameX = roundf(self.frame.size.width/2 - labelCurrentMonth.frameWidth/2); 280 | labelCurrentMonth.frameY = 10; 281 | [formatter release]; 282 | [currentMonth firstWeekDayInMonth]; 283 | 284 | CGContextClearRect(UIGraphicsGetCurrentContext(),rect); 285 | CGContextRef context = UIGraphicsGetCurrentContext(); 286 | 287 | CGRect rectangle = CGRectMake(0,0,self.frame.size.width,kVRGCalendarViewTopBarHeight); 288 | CGContextAddRect(context, rectangle); 289 | CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); 290 | CGContextFillPath(context); 291 | 292 | //Arrows 293 | int arrowSize = 12; 294 | int xmargin = 20; 295 | int ymargin = 18; 296 | 297 | //Arrow Left 298 | CGContextBeginPath(context); 299 | CGContextMoveToPoint(context, xmargin+arrowSize/1.5, ymargin); 300 | CGContextAddLineToPoint(context,xmargin+arrowSize/1.5,ymargin+arrowSize); 301 | CGContextAddLineToPoint(context,xmargin,ymargin+arrowSize/2); 302 | CGContextAddLineToPoint(context,xmargin+arrowSize/1.5, ymargin); 303 | 304 | CGContextSetFillColorWithColor(context, 305 | [UIColor blackColor].CGColor); 306 | CGContextFillPath(context); 307 | 308 | //Arrow right 309 | CGContextBeginPath(context); 310 | CGContextMoveToPoint(context, self.frame.size.width-(xmargin+arrowSize/1.5), ymargin); 311 | CGContextAddLineToPoint(context,self.frame.size.width-xmargin,ymargin+arrowSize/2); 312 | CGContextAddLineToPoint(context,self.frame.size.width-(xmargin+arrowSize/1.5),ymargin+arrowSize); 313 | CGContextAddLineToPoint(context,self.frame.size.width-(xmargin+arrowSize/1.5), ymargin); 314 | 315 | CGContextSetFillColorWithColor(context, 316 | [UIColor blackColor].CGColor); 317 | CGContextFillPath(context); 318 | 319 | //Weekdays 320 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 321 | dateFormatter.dateFormat=@"EEE"; 322 | //always assume gregorian with monday first 323 | NSMutableArray *weekdays = [[NSMutableArray alloc] initWithArray:[dateFormatter shortWeekdaySymbols]]; 324 | [weekdays moveObjectFromIndex:0 toIndex:6]; 325 | 326 | CGContextSetFillColorWithColor(context, 327 | [UIColor colorWithHexString:@"0x383838"].CGColor); 328 | for (int i =0; i<[weekdays count]; i++) { 329 | NSString *weekdayValue = (NSString *)[weekdays objectAtIndex:i]; 330 | UIFont *font = [UIFont fontWithName:@"HelveticaNeue" size:12]; 331 | [weekdayValue drawInRect:CGRectMake(i*(kVRGCalendarViewDayWidth+2), 40, kVRGCalendarViewDayWidth+2, 20) withFont:font lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentCenter]; 332 | } 333 | 334 | int numRows = [self numRows]; 335 | 336 | CGContextSetAllowsAntialiasing(context, NO); 337 | 338 | //Grid background 339 | float gridHeight = numRows*(kVRGCalendarViewDayHeight+2)+1; 340 | CGRect rectangleGrid = CGRectMake(0,kVRGCalendarViewTopBarHeight,self.frame.size.width,gridHeight); 341 | CGContextAddRect(context, rectangleGrid); 342 | CGContextSetFillColorWithColor(context, [UIColor colorWithHexString:@"0xf3f3f3"].CGColor); 343 | //CGContextSetFillColorWithColor(context, [UIColor colorWithHexString:@"0xff0000"].CGColor); 344 | CGContextFillPath(context); 345 | 346 | //Grid white lines 347 | CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor); 348 | CGContextBeginPath(context); 349 | CGContextMoveToPoint(context, 0, kVRGCalendarViewTopBarHeight+1); 350 | CGContextAddLineToPoint(context, kVRGCalendarViewWidth, kVRGCalendarViewTopBarHeight+1); 351 | for (int i = 1; i<7; i++) { 352 | CGContextMoveToPoint(context, i*(kVRGCalendarViewDayWidth+1)+i*1-1, kVRGCalendarViewTopBarHeight); 353 | CGContextAddLineToPoint(context, i*(kVRGCalendarViewDayWidth+1)+i*1-1, kVRGCalendarViewTopBarHeight+gridHeight); 354 | 355 | if (i>numRows-1) continue; 356 | //rows 357 | CGContextMoveToPoint(context, 0, kVRGCalendarViewTopBarHeight+i*(kVRGCalendarViewDayHeight+1)+i*1+1); 358 | CGContextAddLineToPoint(context, kVRGCalendarViewWidth, kVRGCalendarViewTopBarHeight+i*(kVRGCalendarViewDayHeight+1)+i*1+1); 359 | } 360 | 361 | CGContextStrokePath(context); 362 | 363 | //Grid dark lines 364 | CGContextSetStrokeColorWithColor(context, [UIColor colorWithHexString:@"0xcfd4d8"].CGColor); 365 | CGContextBeginPath(context); 366 | CGContextMoveToPoint(context, 0, kVRGCalendarViewTopBarHeight); 367 | CGContextAddLineToPoint(context, kVRGCalendarViewWidth, kVRGCalendarViewTopBarHeight); 368 | for (int i = 1; i<7; i++) { 369 | //columns 370 | CGContextMoveToPoint(context, i*(kVRGCalendarViewDayWidth+1)+i*1, kVRGCalendarViewTopBarHeight); 371 | CGContextAddLineToPoint(context, i*(kVRGCalendarViewDayWidth+1)+i*1, kVRGCalendarViewTopBarHeight+gridHeight); 372 | 373 | if (i>numRows-1) continue; 374 | //rows 375 | CGContextMoveToPoint(context, 0, kVRGCalendarViewTopBarHeight+i*(kVRGCalendarViewDayHeight+1)+i*1); 376 | CGContextAddLineToPoint(context, kVRGCalendarViewWidth, kVRGCalendarViewTopBarHeight+i*(kVRGCalendarViewDayHeight+1)+i*1); 377 | } 378 | CGContextMoveToPoint(context, 0, gridHeight+kVRGCalendarViewTopBarHeight); 379 | CGContextAddLineToPoint(context, kVRGCalendarViewWidth, gridHeight+kVRGCalendarViewTopBarHeight); 380 | 381 | CGContextStrokePath(context); 382 | 383 | CGContextSetAllowsAntialiasing(context, YES); 384 | 385 | //Draw days 386 | CGContextSetFillColorWithColor(context, 387 | [UIColor colorWithHexString:@"0x383838"].CGColor); 388 | 389 | 390 | //NSLog(@"currentMonth month = %i, first weekday in month = %i",[self.currentMonth month],[self.currentMonth firstWeekDayInMonth]); 391 | 392 | int numBlocks = numRows*7; 393 | NSDate *previousMonth = [self.currentMonth offsetMonth:-1]; 394 | int currentMonthNumDays = [currentMonth numDaysInMonth]; 395 | int prevMonthNumDays = [previousMonth numDaysInMonth]; 396 | 397 | int selectedDateBlock = ([selectedDate day]-1)+firstWeekDay; 398 | 399 | //prepAnimationPreviousMonth nog wat mee doen 400 | 401 | //prev next month 402 | BOOL isSelectedDatePreviousMonth = prepAnimationPreviousMonth; 403 | BOOL isSelectedDateNextMonth = prepAnimationNextMonth; 404 | 405 | if (self.selectedDate!=nil) { 406 | isSelectedDatePreviousMonth = ([selectedDate year]==[currentMonth year] && [selectedDate month]<[currentMonth month]) || [selectedDate year] < [currentMonth year]; 407 | 408 | if (!isSelectedDatePreviousMonth) { 409 | isSelectedDateNextMonth = ([selectedDate year]==[currentMonth year] && [selectedDate month]>[currentMonth month]) || [selectedDate year] > [currentMonth year]; 410 | } 411 | } 412 | 413 | if (isSelectedDatePreviousMonth) { 414 | int lastPositionPreviousMonth = firstWeekDay-1; 415 | selectedDateBlock=lastPositionPreviousMonth-([selectedDate numDaysInMonth]-[selectedDate day]); 416 | } else if (isSelectedDateNextMonth) { 417 | selectedDateBlock = [currentMonth numDaysInMonth] + (firstWeekDay-1) + [selectedDate day]; 418 | } 419 | 420 | 421 | NSDate *todayDate = [NSDate date]; 422 | int todayBlock = -1; 423 | 424 | // NSLog(@"currentMonth month = %i day = %i, todaydate day = %i",[currentMonth month],[currentMonth day],[todayDate month]); 425 | 426 | if ([todayDate month] == [currentMonth month] && [todayDate year] == [currentMonth year]) { 427 | todayBlock = [todayDate day] + firstWeekDay - 1; 428 | } 429 | 430 | for (int i=0; i=(firstWeekDay+currentMonthNumDays)) { //next month 445 | targetDate = (i+1) - (firstWeekDay+currentMonthNumDays); 446 | NSString *hex = (isSelectedDateNextMonth) ? @"0x383838" : @"aaaaaa"; 447 | CGContextSetFillColorWithColor(context, 448 | [UIColor colorWithHexString:hex].CGColor); 449 | } else { //current month 450 | // isCurrentMonth = YES; 451 | targetDate = (i-firstWeekDay)+1; 452 | NSString *hex = (isSelectedDatePreviousMonth || isSelectedDateNextMonth) ? @"0xaaaaaa" : @"0x383838"; 453 | CGContextSetFillColorWithColor(context, 454 | [UIColor colorWithHexString:hex].CGColor); 455 | } 456 | 457 | NSString *date = [NSString stringWithFormat:@"%i",targetDate]; 458 | 459 | //draw selected date 460 | if (selectedDate && i==selectedDateBlock) { 461 | CGRect rectangleGrid = CGRectMake(targetX,targetY,kVRGCalendarViewDayWidth+2,kVRGCalendarViewDayHeight+2); 462 | CGContextAddRect(context, rectangleGrid); 463 | CGContextSetFillColorWithColor(context, [UIColor colorWithHexString:@"0x006dbc"].CGColor); 464 | CGContextFillPath(context); 465 | 466 | CGContextSetFillColorWithColor(context, 467 | [UIColor whiteColor].CGColor); 468 | } else if (todayBlock==i) { 469 | CGRect rectangleGrid = CGRectMake(targetX,targetY,kVRGCalendarViewDayWidth+2,kVRGCalendarViewDayHeight+2); 470 | CGContextAddRect(context, rectangleGrid); 471 | CGContextSetFillColorWithColor(context, [UIColor colorWithHexString:@"0x383838"].CGColor); 472 | CGContextFillPath(context); 473 | 474 | CGContextSetFillColorWithColor(context, 475 | [UIColor whiteColor].CGColor); 476 | } 477 | 478 | [date drawInRect:CGRectMake(targetX+2, targetY+10, kVRGCalendarViewDayWidth, kVRGCalendarViewDayHeight) withFont:[UIFont fontWithName:@"HelveticaNeue-Bold" size:17] lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentCenter]; 479 | } 480 | 481 | // CGContextClosePath(context); 482 | 483 | 484 | //Draw markings 485 | if (!self.markedDates || isSelectedDatePreviousMonth || isSelectedDateNextMonth) return; 486 | 487 | for (int i = 0; i<[self.markedDates count]; i++) { 488 | id markedDateObj = [self.markedDates objectAtIndex:i]; 489 | 490 | int targetDate; 491 | if ([markedDateObj isKindOfClass:[NSNumber class]]) { 492 | targetDate = [(NSNumber *)markedDateObj intValue]; 493 | } else if ([markedDateObj isKindOfClass:[NSDate class]]) { 494 | NSDate *date = (NSDate *)markedDateObj; 495 | targetDate = [date day]; 496 | } else { 497 | continue; 498 | } 499 | 500 | 501 | 502 | int targetBlock = firstWeekDay + (targetDate-1); 503 | int targetColumn = targetBlock%7; 504 | int targetRow = targetBlock/7; 505 | 506 | int targetX = targetColumn * (kVRGCalendarViewDayWidth+2) + 7; 507 | int targetY = kVRGCalendarViewTopBarHeight + targetRow * (kVRGCalendarViewDayHeight+2) + 38; 508 | 509 | CGRect rectangle = CGRectMake(targetX,targetY,32,2); 510 | CGContextAddRect(context, rectangle); 511 | 512 | UIColor *color; 513 | if (selectedDate && selectedDateBlock==targetBlock) { 514 | color = [UIColor whiteColor]; 515 | } else if (todayBlock==targetBlock) { 516 | color = [UIColor whiteColor]; 517 | } else { 518 | color = (UIColor *)[markedColors objectAtIndex:i]; 519 | } 520 | 521 | 522 | CGContextSetFillColorWithColor(context, color.CGColor); 523 | CGContextFillPath(context); 524 | } 525 | } 526 | 527 | #pragma mark - Draw image for animation 528 | -(UIImage *)drawCurrentState { 529 | float targetHeight = kVRGCalendarViewTopBarHeight + [self numRows]*(kVRGCalendarViewDayHeight+2)+1; 530 | 531 | UIGraphicsBeginImageContext(CGSizeMake(kVRGCalendarViewWidth, targetHeight-kVRGCalendarViewTopBarHeight)); 532 | CGContextRef c = UIGraphicsGetCurrentContext(); 533 | CGContextTranslateCTM(c, 0, -kVRGCalendarViewTopBarHeight); // <-- shift everything up by 40px when drawing. 534 | [self.layer renderInContext:c]; 535 | UIImage* viewImage = UIGraphicsGetImageFromCurrentImageContext(); 536 | UIGraphicsEndImageContext(); 537 | return viewImage; 538 | } 539 | 540 | #pragma mark - Init 541 | -(id)init { 542 | self = [super initWithFrame:CGRectMake(0, 0, kVRGCalendarViewWidth, 0)]; 543 | if (self) { 544 | self.contentMode = UIViewContentModeTop; 545 | self.clipsToBounds=YES; 546 | 547 | isAnimating=NO; 548 | self.labelCurrentMonth = [[UILabel alloc] initWithFrame:CGRectMake(34, 0, kVRGCalendarViewWidth-68, 40)]; 549 | [self addSubview:labelCurrentMonth]; 550 | labelCurrentMonth.backgroundColor=[UIColor whiteColor]; 551 | labelCurrentMonth.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:17]; 552 | labelCurrentMonth.textColor = [UIColor colorWithHexString:@"0x383838"]; 553 | labelCurrentMonth.textAlignment = UITextAlignmentCenter; 554 | 555 | [self performSelector:@selector(reset) withObject:nil afterDelay:0.1]; //so delegate can be set after init and still get called on init 556 | // [self reset]; 557 | } 558 | return self; 559 | } 560 | 561 | -(void)dealloc { 562 | 563 | self.delegate=nil; 564 | self.currentMonth=nil; 565 | self.labelCurrentMonth=nil; 566 | 567 | self.markedDates=nil; 568 | self.markedColors=nil; 569 | 570 | [super dealloc]; 571 | } 572 | @end 573 | -------------------------------------------------------------------------------- /Vurig Calendar/VRGViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // VRGViewController.h 3 | // Vurig Calendar 4 | // 5 | // Created by in 't Veen Tjeerd on 5/29/12. 6 | // Copyright (c) 2012 Vurig. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "VRGCalendarView.h" 11 | 12 | @interface VRGViewController : UIViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Vurig Calendar/VRGViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // VRGViewController.m 3 | // Vurig Calendar 4 | // 5 | // Created by in 't Veen Tjeerd on 5/29/12. 6 | // Copyright (c) 2012 Vurig. All rights reserved. 7 | // 8 | 9 | #import "VRGViewController.h" 10 | 11 | 12 | 13 | @interface VRGViewController () 14 | 15 | @end 16 | 17 | @implementation VRGViewController 18 | 19 | - (void)viewDidLoad 20 | { 21 | [super viewDidLoad]; 22 | // Do any additional setup after loading the view, typically from a nib. 23 | 24 | VRGCalendarView *calendar = [[VRGCalendarView alloc] init]; 25 | calendar.delegate=self; 26 | [self.view addSubview:calendar]; 27 | 28 | 29 | 30 | } 31 | 32 | -(void)calendarView:(VRGCalendarView *)calendarView switchedToMonth:(int)month targetHeight:(float)targetHeight animated:(BOOL)animated { 33 | if (month==[[NSDate date] month]) { 34 | NSArray *dates = [NSArray arrayWithObjects:[NSNumber numberWithInt:1],[NSNumber numberWithInt:5], nil]; 35 | [calendarView markDates:dates]; 36 | } 37 | } 38 | 39 | -(void)calendarView:(VRGCalendarView *)calendarView dateSelected:(NSDate *)date { 40 | NSLog(@"Selected date = %@",date); 41 | } 42 | 43 | 44 | 45 | - (void)viewDidUnload 46 | { 47 | [super viewDidUnload]; 48 | // Release any retained subviews of the main view. 49 | } 50 | 51 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 52 | { 53 | return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Vurig Calendar/Vurig Calendar-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | nl.vurig.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Vurig Calendar/Vurig Calendar-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Vurig Calendar' target in the 'Vurig Calendar' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Vurig Calendar/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Vurig Calendar/en.lproj/VRGViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1296 5 | 11E53 6 | 2182 7 | 1138.47 8 | 569.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 1181 12 | 13 | 14 | IBProxyObject 15 | IBUIView 16 | 17 | 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | PluginDependencyRecalculationVersion 22 | 23 | 24 | 25 | 26 | IBFilesOwner 27 | IBCocoaTouchFramework 28 | 29 | 30 | IBFirstResponder 31 | IBCocoaTouchFramework 32 | 33 | 34 | 35 | 274 36 | {{0, 20}, {320, 460}} 37 | 38 | 39 | 40 | 1 41 | MSAxIDEAA 42 | 43 | NO 44 | 45 | IBCocoaTouchFramework 46 | 47 | 48 | 49 | 50 | 51 | 52 | view 53 | 54 | 55 | 56 | 7 57 | 58 | 59 | 60 | 61 | 62 | 0 63 | 64 | 65 | 66 | 67 | 68 | -1 69 | 70 | 71 | File's Owner 72 | 73 | 74 | -2 75 | 76 | 77 | 78 | 79 | 6 80 | 81 | 82 | 83 | 84 | 85 | 86 | VRGViewController 87 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 88 | UIResponder 89 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 90 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 91 | 92 | 93 | 94 | 95 | 96 | 7 97 | 98 | 99 | 100 | 101 | VRGViewController 102 | UIViewController 103 | 104 | IBProjectSource 105 | ./Classes/VRGViewController.h 106 | 107 | 108 | 109 | 110 | 0 111 | IBCocoaTouchFramework 112 | 113 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 114 | 115 | 116 | YES 117 | 3 118 | 1181 119 | 120 | 121 | -------------------------------------------------------------------------------- /Vurig Calendar/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Vurig Calendar 4 | // 5 | // Created by in 't Veen Tjeerd on 5/29/12. 6 | // Copyright (c) 2012 Vurig. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "VRGAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([VRGAppDelegate class])); 17 | } 18 | } 19 | --------------------------------------------------------------------------------