├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE.txt ├── LTHMonthYearPickerView Demo.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── LTHMonthYearPickerView Demo ├── Images.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-167@2x.png │ │ ├── Icon-40.png │ │ ├── Icon-40@2x-1.png │ │ ├── Icon-40@2x.png │ │ ├── Icon-60@2x.png │ │ ├── Icon-72.png │ │ ├── Icon-72@2x.png │ │ ├── Icon-76.png │ │ ├── Icon-76@2x.png │ │ ├── Icon-Small-1.png │ │ ├── Icon-Small-50.png │ │ ├── Icon-Small-50@2x.png │ │ ├── Icon-Small.png │ │ ├── Icon-Small@2x-1.png │ │ ├── Icon-Small@2x.png │ │ ├── Icon.png │ │ └── Icon@2x.png │ └── LaunchImage.launchimage │ │ └── Contents.json ├── LTHAppDelegate.h ├── LTHAppDelegate.m ├── LTHMonthYearPickerView Demo-Info.plist ├── LTHMonthYearPickerView Demo-Prefix.pch ├── LTHViewController.h ├── LTHViewController.m ├── en.lproj │ └── InfoPlist.strings └── main.m ├── LTHMonthYearPickerView ├── LTHMonthYearPickerView.h └── LTHMonthYearPickerView.m └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: rolandleth 2 | patreon: rolandleth 3 | custom: "https://paypal.me/rolandleth" 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xcscheme 14 | *.xcworkspace 15 | profile 16 | *.moved-aside 17 | DerivedData 18 | .idea/ 19 | *.hmap 20 | *.xccheckout 21 | 22 | #CocoaPods 23 | Pods -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Roland Leth 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2AD10F50189AED6E000A4A73 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AD10F4F189AED6E000A4A73 /* Foundation.framework */; }; 11 | 2AD10F52189AED6E000A4A73 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AD10F51189AED6E000A4A73 /* CoreGraphics.framework */; }; 12 | 2AD10F54189AED6E000A4A73 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AD10F53189AED6E000A4A73 /* UIKit.framework */; }; 13 | 2AD10F5A189AED6E000A4A73 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2AD10F58189AED6E000A4A73 /* InfoPlist.strings */; }; 14 | 2AD10F5C189AED6E000A4A73 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD10F5B189AED6E000A4A73 /* main.m */; }; 15 | 2AD10F60189AED6E000A4A73 /* LTHAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD10F5F189AED6E000A4A73 /* LTHAppDelegate.m */; }; 16 | 2AD10F62189AED6E000A4A73 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2AD10F61189AED6E000A4A73 /* Images.xcassets */; }; 17 | 2AD10F69189AED6E000A4A73 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AD10F68189AED6E000A4A73 /* XCTest.framework */; }; 18 | 2AD10F6A189AED6E000A4A73 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AD10F4F189AED6E000A4A73 /* Foundation.framework */; }; 19 | 2AD10F6B189AED6E000A4A73 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AD10F53189AED6E000A4A73 /* UIKit.framework */; }; 20 | 2AD10F81189AEDAF000A4A73 /* LTHMonthYearPickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD10F80189AEDAF000A4A73 /* LTHMonthYearPickerView.m */; }; 21 | 2AD10F84189AEF64000A4A73 /* LTHViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD10F83189AEF64000A4A73 /* LTHViewController.m */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | 2AD10F6C189AED6E000A4A73 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = 2AD10F44189AED6E000A4A73 /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = 2AD10F4B189AED6E000A4A73; 30 | remoteInfo = "LTHMonthYearPickerView Demo"; 31 | }; 32 | /* End PBXContainerItemProxy section */ 33 | 34 | /* Begin PBXFileReference section */ 35 | 2AD10F4C189AED6E000A4A73 /* LTHMonthYearPickerView Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "LTHMonthYearPickerView Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 36 | 2AD10F4F189AED6E000A4A73 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 37 | 2AD10F51189AED6E000A4A73 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 38 | 2AD10F53189AED6E000A4A73 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 39 | 2AD10F57189AED6E000A4A73 /* LTHMonthYearPickerView Demo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "LTHMonthYearPickerView Demo-Info.plist"; sourceTree = ""; }; 40 | 2AD10F59189AED6E000A4A73 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 41 | 2AD10F5B189AED6E000A4A73 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 42 | 2AD10F5D189AED6E000A4A73 /* LTHMonthYearPickerView Demo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "LTHMonthYearPickerView Demo-Prefix.pch"; sourceTree = ""; }; 43 | 2AD10F5E189AED6E000A4A73 /* LTHAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LTHAppDelegate.h; sourceTree = ""; }; 44 | 2AD10F5F189AED6E000A4A73 /* LTHAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LTHAppDelegate.m; sourceTree = ""; }; 45 | 2AD10F61189AED6E000A4A73 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 46 | 2AD10F67189AED6E000A4A73 /* LTHMonthYearPickerView DemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "LTHMonthYearPickerView DemoTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 2AD10F68189AED6E000A4A73 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 48 | 2AD10F7F189AEDAF000A4A73 /* LTHMonthYearPickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = LTHMonthYearPickerView.h; sourceTree = ""; usesTabs = 0; }; 49 | 2AD10F80189AEDAF000A4A73 /* LTHMonthYearPickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = LTHMonthYearPickerView.m; sourceTree = ""; usesTabs = 0; }; 50 | 2AD10F82189AEF64000A4A73 /* LTHViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LTHViewController.h; sourceTree = ""; }; 51 | 2AD10F83189AEF64000A4A73 /* LTHViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LTHViewController.m; sourceTree = ""; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | 2AD10F49189AED6E000A4A73 /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | 2AD10F52189AED6E000A4A73 /* CoreGraphics.framework in Frameworks */, 60 | 2AD10F54189AED6E000A4A73 /* UIKit.framework in Frameworks */, 61 | 2AD10F50189AED6E000A4A73 /* Foundation.framework in Frameworks */, 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | 2AD10F64189AED6E000A4A73 /* Frameworks */ = { 66 | isa = PBXFrameworksBuildPhase; 67 | buildActionMask = 2147483647; 68 | files = ( 69 | 2AD10F69189AED6E000A4A73 /* XCTest.framework in Frameworks */, 70 | 2AD10F6B189AED6E000A4A73 /* UIKit.framework in Frameworks */, 71 | 2AD10F6A189AED6E000A4A73 /* Foundation.framework in Frameworks */, 72 | ); 73 | runOnlyForDeploymentPostprocessing = 0; 74 | }; 75 | /* End PBXFrameworksBuildPhase section */ 76 | 77 | /* Begin PBXGroup section */ 78 | 2AD10F43189AED6E000A4A73 = { 79 | isa = PBXGroup; 80 | children = ( 81 | 2AD10F7E189AEDAF000A4A73 /* LTHMonthYearPickerView */, 82 | 2AD10F55189AED6E000A4A73 /* LTHMonthYearPickerView Demo */, 83 | 2AD10F4E189AED6E000A4A73 /* Frameworks */, 84 | 2AD10F4D189AED6E000A4A73 /* Products */, 85 | ); 86 | sourceTree = ""; 87 | }; 88 | 2AD10F4D189AED6E000A4A73 /* Products */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 2AD10F4C189AED6E000A4A73 /* LTHMonthYearPickerView Demo.app */, 92 | 2AD10F67189AED6E000A4A73 /* LTHMonthYearPickerView DemoTests.xctest */, 93 | ); 94 | name = Products; 95 | sourceTree = ""; 96 | }; 97 | 2AD10F4E189AED6E000A4A73 /* Frameworks */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 2AD10F4F189AED6E000A4A73 /* Foundation.framework */, 101 | 2AD10F51189AED6E000A4A73 /* CoreGraphics.framework */, 102 | 2AD10F53189AED6E000A4A73 /* UIKit.framework */, 103 | 2AD10F68189AED6E000A4A73 /* XCTest.framework */, 104 | ); 105 | name = Frameworks; 106 | sourceTree = ""; 107 | }; 108 | 2AD10F55189AED6E000A4A73 /* LTHMonthYearPickerView Demo */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 2AD10F5E189AED6E000A4A73 /* LTHAppDelegate.h */, 112 | 2AD10F5F189AED6E000A4A73 /* LTHAppDelegate.m */, 113 | 2AD10F61189AED6E000A4A73 /* Images.xcassets */, 114 | 2AD10F56189AED6E000A4A73 /* Supporting Files */, 115 | 2AD10F82189AEF64000A4A73 /* LTHViewController.h */, 116 | 2AD10F83189AEF64000A4A73 /* LTHViewController.m */, 117 | ); 118 | path = "LTHMonthYearPickerView Demo"; 119 | sourceTree = ""; 120 | }; 121 | 2AD10F56189AED6E000A4A73 /* Supporting Files */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 2AD10F57189AED6E000A4A73 /* LTHMonthYearPickerView Demo-Info.plist */, 125 | 2AD10F58189AED6E000A4A73 /* InfoPlist.strings */, 126 | 2AD10F5B189AED6E000A4A73 /* main.m */, 127 | 2AD10F5D189AED6E000A4A73 /* LTHMonthYearPickerView Demo-Prefix.pch */, 128 | ); 129 | name = "Supporting Files"; 130 | sourceTree = ""; 131 | }; 132 | 2AD10F7E189AEDAF000A4A73 /* LTHMonthYearPickerView */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 2AD10F7F189AEDAF000A4A73 /* LTHMonthYearPickerView.h */, 136 | 2AD10F80189AEDAF000A4A73 /* LTHMonthYearPickerView.m */, 137 | ); 138 | path = LTHMonthYearPickerView; 139 | sourceTree = ""; 140 | }; 141 | /* End PBXGroup section */ 142 | 143 | /* Begin PBXNativeTarget section */ 144 | 2AD10F4B189AED6E000A4A73 /* LTHMonthYearPickerView Demo */ = { 145 | isa = PBXNativeTarget; 146 | buildConfigurationList = 2AD10F78189AED6E000A4A73 /* Build configuration list for PBXNativeTarget "LTHMonthYearPickerView Demo" */; 147 | buildPhases = ( 148 | 2AD10F48189AED6E000A4A73 /* Sources */, 149 | 2AD10F49189AED6E000A4A73 /* Frameworks */, 150 | 2AD10F4A189AED6E000A4A73 /* Resources */, 151 | ); 152 | buildRules = ( 153 | ); 154 | dependencies = ( 155 | ); 156 | name = "LTHMonthYearPickerView Demo"; 157 | productName = "LTHMonthYearPickerView Demo"; 158 | productReference = 2AD10F4C189AED6E000A4A73 /* LTHMonthYearPickerView Demo.app */; 159 | productType = "com.apple.product-type.application"; 160 | }; 161 | 2AD10F66189AED6E000A4A73 /* LTHMonthYearPickerView DemoTests */ = { 162 | isa = PBXNativeTarget; 163 | buildConfigurationList = 2AD10F7B189AED6E000A4A73 /* Build configuration list for PBXNativeTarget "LTHMonthYearPickerView DemoTests" */; 164 | buildPhases = ( 165 | 2AD10F63189AED6E000A4A73 /* Sources */, 166 | 2AD10F64189AED6E000A4A73 /* Frameworks */, 167 | 2AD10F65189AED6E000A4A73 /* Resources */, 168 | ); 169 | buildRules = ( 170 | ); 171 | dependencies = ( 172 | 2AD10F6D189AED6E000A4A73 /* PBXTargetDependency */, 173 | ); 174 | name = "LTHMonthYearPickerView DemoTests"; 175 | productName = "LTHMonthYearPickerView DemoTests"; 176 | productReference = 2AD10F67189AED6E000A4A73 /* LTHMonthYearPickerView DemoTests.xctest */; 177 | productType = "com.apple.product-type.bundle.unit-test"; 178 | }; 179 | /* End PBXNativeTarget section */ 180 | 181 | /* Begin PBXProject section */ 182 | 2AD10F44189AED6E000A4A73 /* Project object */ = { 183 | isa = PBXProject; 184 | attributes = { 185 | CLASSPREFIX = LTH; 186 | LastUpgradeCheck = 1000; 187 | ORGANIZATIONNAME = "Roland Leth"; 188 | TargetAttributes = { 189 | 2AD10F4B189AED6E000A4A73 = { 190 | DevelopmentTeam = 78653ABY96; 191 | ProvisioningStyle = Automatic; 192 | }; 193 | 2AD10F66189AED6E000A4A73 = { 194 | TestTargetID = 2AD10F4B189AED6E000A4A73; 195 | }; 196 | }; 197 | }; 198 | buildConfigurationList = 2AD10F47189AED6E000A4A73 /* Build configuration list for PBXProject "LTHMonthYearPickerView Demo" */; 199 | compatibilityVersion = "Xcode 3.2"; 200 | developmentRegion = English; 201 | hasScannedForEncodings = 0; 202 | knownRegions = ( 203 | en, 204 | ); 205 | mainGroup = 2AD10F43189AED6E000A4A73; 206 | productRefGroup = 2AD10F4D189AED6E000A4A73 /* Products */; 207 | projectDirPath = ""; 208 | projectRoot = ""; 209 | targets = ( 210 | 2AD10F4B189AED6E000A4A73 /* LTHMonthYearPickerView Demo */, 211 | 2AD10F66189AED6E000A4A73 /* LTHMonthYearPickerView DemoTests */, 212 | ); 213 | }; 214 | /* End PBXProject section */ 215 | 216 | /* Begin PBXResourcesBuildPhase section */ 217 | 2AD10F4A189AED6E000A4A73 /* Resources */ = { 218 | isa = PBXResourcesBuildPhase; 219 | buildActionMask = 2147483647; 220 | files = ( 221 | 2AD10F5A189AED6E000A4A73 /* InfoPlist.strings in Resources */, 222 | 2AD10F62189AED6E000A4A73 /* Images.xcassets in Resources */, 223 | ); 224 | runOnlyForDeploymentPostprocessing = 0; 225 | }; 226 | 2AD10F65189AED6E000A4A73 /* Resources */ = { 227 | isa = PBXResourcesBuildPhase; 228 | buildActionMask = 2147483647; 229 | files = ( 230 | ); 231 | runOnlyForDeploymentPostprocessing = 0; 232 | }; 233 | /* End PBXResourcesBuildPhase section */ 234 | 235 | /* Begin PBXSourcesBuildPhase section */ 236 | 2AD10F48189AED6E000A4A73 /* Sources */ = { 237 | isa = PBXSourcesBuildPhase; 238 | buildActionMask = 2147483647; 239 | files = ( 240 | 2AD10F81189AEDAF000A4A73 /* LTHMonthYearPickerView.m in Sources */, 241 | 2AD10F84189AEF64000A4A73 /* LTHViewController.m in Sources */, 242 | 2AD10F5C189AED6E000A4A73 /* main.m in Sources */, 243 | 2AD10F60189AED6E000A4A73 /* LTHAppDelegate.m in Sources */, 244 | ); 245 | runOnlyForDeploymentPostprocessing = 0; 246 | }; 247 | 2AD10F63189AED6E000A4A73 /* Sources */ = { 248 | isa = PBXSourcesBuildPhase; 249 | buildActionMask = 2147483647; 250 | files = ( 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | }; 254 | /* End PBXSourcesBuildPhase section */ 255 | 256 | /* Begin PBXTargetDependency section */ 257 | 2AD10F6D189AED6E000A4A73 /* PBXTargetDependency */ = { 258 | isa = PBXTargetDependency; 259 | target = 2AD10F4B189AED6E000A4A73 /* LTHMonthYearPickerView Demo */; 260 | targetProxy = 2AD10F6C189AED6E000A4A73 /* PBXContainerItemProxy */; 261 | }; 262 | /* End PBXTargetDependency section */ 263 | 264 | /* Begin PBXVariantGroup section */ 265 | 2AD10F58189AED6E000A4A73 /* InfoPlist.strings */ = { 266 | isa = PBXVariantGroup; 267 | children = ( 268 | 2AD10F59189AED6E000A4A73 /* en */, 269 | ); 270 | name = InfoPlist.strings; 271 | sourceTree = ""; 272 | }; 273 | /* End PBXVariantGroup section */ 274 | 275 | /* Begin XCBuildConfiguration section */ 276 | 2AD10F76189AED6E000A4A73 /* Debug */ = { 277 | isa = XCBuildConfiguration; 278 | buildSettings = { 279 | ALWAYS_SEARCH_USER_PATHS = NO; 280 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 281 | CLANG_CXX_LIBRARY = "libc++"; 282 | CLANG_ENABLE_MODULES = YES; 283 | CLANG_ENABLE_OBJC_ARC = YES; 284 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 285 | CLANG_WARN_BOOL_CONVERSION = YES; 286 | CLANG_WARN_COMMA = YES; 287 | CLANG_WARN_CONSTANT_CONVERSION = YES; 288 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 289 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 290 | CLANG_WARN_EMPTY_BODY = YES; 291 | CLANG_WARN_ENUM_CONVERSION = YES; 292 | CLANG_WARN_INFINITE_RECURSION = YES; 293 | CLANG_WARN_INT_CONVERSION = YES; 294 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 295 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 296 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 297 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 298 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 299 | CLANG_WARN_STRICT_PROTOTYPES = YES; 300 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 301 | CLANG_WARN_UNREACHABLE_CODE = YES; 302 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 303 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 304 | COPY_PHASE_STRIP = NO; 305 | ENABLE_STRICT_OBJC_MSGSEND = YES; 306 | ENABLE_TESTABILITY = YES; 307 | GCC_C_LANGUAGE_STANDARD = gnu99; 308 | GCC_DYNAMIC_NO_PIC = NO; 309 | GCC_NO_COMMON_BLOCKS = YES; 310 | GCC_OPTIMIZATION_LEVEL = 0; 311 | GCC_PREPROCESSOR_DEFINITIONS = ( 312 | "DEBUG=1", 313 | "$(inherited)", 314 | ); 315 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 316 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 317 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 318 | GCC_WARN_UNDECLARED_SELECTOR = YES; 319 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 320 | GCC_WARN_UNUSED_FUNCTION = YES; 321 | GCC_WARN_UNUSED_VARIABLE = YES; 322 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 323 | ONLY_ACTIVE_ARCH = YES; 324 | SDKROOT = iphoneos; 325 | TARGETED_DEVICE_FAMILY = "1,2"; 326 | }; 327 | name = Debug; 328 | }; 329 | 2AD10F77189AED6E000A4A73 /* Release */ = { 330 | isa = XCBuildConfiguration; 331 | buildSettings = { 332 | ALWAYS_SEARCH_USER_PATHS = NO; 333 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 334 | CLANG_CXX_LIBRARY = "libc++"; 335 | CLANG_ENABLE_MODULES = YES; 336 | CLANG_ENABLE_OBJC_ARC = YES; 337 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 338 | CLANG_WARN_BOOL_CONVERSION = YES; 339 | CLANG_WARN_COMMA = YES; 340 | CLANG_WARN_CONSTANT_CONVERSION = YES; 341 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 342 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 343 | CLANG_WARN_EMPTY_BODY = YES; 344 | CLANG_WARN_ENUM_CONVERSION = YES; 345 | CLANG_WARN_INFINITE_RECURSION = YES; 346 | CLANG_WARN_INT_CONVERSION = YES; 347 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 348 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 349 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 350 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 351 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 352 | CLANG_WARN_STRICT_PROTOTYPES = YES; 353 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 354 | CLANG_WARN_UNREACHABLE_CODE = YES; 355 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 356 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 357 | COPY_PHASE_STRIP = YES; 358 | ENABLE_NS_ASSERTIONS = NO; 359 | ENABLE_STRICT_OBJC_MSGSEND = YES; 360 | GCC_C_LANGUAGE_STANDARD = gnu99; 361 | GCC_NO_COMMON_BLOCKS = YES; 362 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 363 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 364 | GCC_WARN_UNDECLARED_SELECTOR = YES; 365 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 366 | GCC_WARN_UNUSED_FUNCTION = YES; 367 | GCC_WARN_UNUSED_VARIABLE = YES; 368 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 369 | SDKROOT = iphoneos; 370 | TARGETED_DEVICE_FAMILY = "1,2"; 371 | VALIDATE_PRODUCT = YES; 372 | }; 373 | name = Release; 374 | }; 375 | 2AD10F79189AED6E000A4A73 /* Debug */ = { 376 | isa = XCBuildConfiguration; 377 | buildSettings = { 378 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 379 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 380 | DEVELOPMENT_TEAM = 78653ABY96; 381 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 382 | GCC_PREFIX_HEADER = "LTHMonthYearPickerView Demo/LTHMonthYearPickerView Demo-Prefix.pch"; 383 | INFOPLIST_FILE = "LTHMonthYearPickerView Demo/LTHMonthYearPickerView Demo-Info.plist"; 384 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 385 | PRODUCT_BUNDLE_IDENTIFIER = "com.rolandleth.${PRODUCT_NAME:rfc1034identifier}"; 386 | PRODUCT_NAME = "$(TARGET_NAME)"; 387 | WRAPPER_EXTENSION = app; 388 | }; 389 | name = Debug; 390 | }; 391 | 2AD10F7A189AED6E000A4A73 /* Release */ = { 392 | isa = XCBuildConfiguration; 393 | buildSettings = { 394 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 395 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 396 | DEVELOPMENT_TEAM = 78653ABY96; 397 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 398 | GCC_PREFIX_HEADER = "LTHMonthYearPickerView Demo/LTHMonthYearPickerView Demo-Prefix.pch"; 399 | INFOPLIST_FILE = "LTHMonthYearPickerView Demo/LTHMonthYearPickerView Demo-Info.plist"; 400 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 401 | PRODUCT_BUNDLE_IDENTIFIER = "com.rolandleth.${PRODUCT_NAME:rfc1034identifier}"; 402 | PRODUCT_NAME = "$(TARGET_NAME)"; 403 | WRAPPER_EXTENSION = app; 404 | }; 405 | name = Release; 406 | }; 407 | 2AD10F7C189AED6E000A4A73 /* Debug */ = { 408 | isa = XCBuildConfiguration; 409 | buildSettings = { 410 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LTHMonthYearPickerView Demo.app/LTHMonthYearPickerView Demo"; 411 | FRAMEWORK_SEARCH_PATHS = ( 412 | "$(SDKROOT)/Developer/Library/Frameworks", 413 | "$(inherited)", 414 | "$(DEVELOPER_FRAMEWORKS_DIR)", 415 | ); 416 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 417 | GCC_PREFIX_HEADER = "LTHMonthYearPickerView Demo/LTHMonthYearPickerView Demo-Prefix.pch"; 418 | GCC_PREPROCESSOR_DEFINITIONS = ( 419 | "DEBUG=1", 420 | "$(inherited)", 421 | ); 422 | INFOPLIST_FILE = "LTHMonthYearPickerView DemoTests/LTHMonthYearPickerView DemoTests-Info.plist"; 423 | PRODUCT_NAME = "$(TARGET_NAME)"; 424 | TEST_HOST = "$(BUNDLE_LOADER)"; 425 | WRAPPER_EXTENSION = xctest; 426 | }; 427 | name = Debug; 428 | }; 429 | 2AD10F7D189AED6E000A4A73 /* Release */ = { 430 | isa = XCBuildConfiguration; 431 | buildSettings = { 432 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LTHMonthYearPickerView Demo.app/LTHMonthYearPickerView Demo"; 433 | FRAMEWORK_SEARCH_PATHS = ( 434 | "$(SDKROOT)/Developer/Library/Frameworks", 435 | "$(inherited)", 436 | "$(DEVELOPER_FRAMEWORKS_DIR)", 437 | ); 438 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 439 | GCC_PREFIX_HEADER = "LTHMonthYearPickerView Demo/LTHMonthYearPickerView Demo-Prefix.pch"; 440 | INFOPLIST_FILE = "LTHMonthYearPickerView DemoTests/LTHMonthYearPickerView DemoTests-Info.plist"; 441 | PRODUCT_NAME = "$(TARGET_NAME)"; 442 | TEST_HOST = "$(BUNDLE_LOADER)"; 443 | WRAPPER_EXTENSION = xctest; 444 | }; 445 | name = Release; 446 | }; 447 | /* End XCBuildConfiguration section */ 448 | 449 | /* Begin XCConfigurationList section */ 450 | 2AD10F47189AED6E000A4A73 /* Build configuration list for PBXProject "LTHMonthYearPickerView Demo" */ = { 451 | isa = XCConfigurationList; 452 | buildConfigurations = ( 453 | 2AD10F76189AED6E000A4A73 /* Debug */, 454 | 2AD10F77189AED6E000A4A73 /* Release */, 455 | ); 456 | defaultConfigurationIsVisible = 0; 457 | defaultConfigurationName = Release; 458 | }; 459 | 2AD10F78189AED6E000A4A73 /* Build configuration list for PBXNativeTarget "LTHMonthYearPickerView Demo" */ = { 460 | isa = XCConfigurationList; 461 | buildConfigurations = ( 462 | 2AD10F79189AED6E000A4A73 /* Debug */, 463 | 2AD10F7A189AED6E000A4A73 /* Release */, 464 | ); 465 | defaultConfigurationIsVisible = 0; 466 | defaultConfigurationName = Release; 467 | }; 468 | 2AD10F7B189AED6E000A4A73 /* Build configuration list for PBXNativeTarget "LTHMonthYearPickerView DemoTests" */ = { 469 | isa = XCConfigurationList; 470 | buildConfigurations = ( 471 | 2AD10F7C189AED6E000A4A73 /* Debug */, 472 | 2AD10F7D189AED6E000A4A73 /* Release */, 473 | ); 474 | defaultConfigurationIsVisible = 0; 475 | defaultConfigurationName = Release; 476 | }; 477 | /* End XCConfigurationList section */ 478 | }; 479 | rootObject = 2AD10F44189AED6E000A4A73 /* Project object */; 480 | } 481 | -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "size" : "29x29", 15 | "idiom" : "iphone", 16 | "filename" : "Icon-Small-1.png", 17 | "scale" : "1x" 18 | }, 19 | { 20 | "size" : "29x29", 21 | "idiom" : "iphone", 22 | "filename" : "Icon-Small@2x-1.png", 23 | "scale" : "2x" 24 | }, 25 | { 26 | "idiom" : "iphone", 27 | "size" : "29x29", 28 | "scale" : "3x" 29 | }, 30 | { 31 | "size" : "40x40", 32 | "idiom" : "iphone", 33 | "filename" : "Icon-40@2x.png", 34 | "scale" : "2x" 35 | }, 36 | { 37 | "idiom" : "iphone", 38 | "size" : "40x40", 39 | "scale" : "3x" 40 | }, 41 | { 42 | "size" : "57x57", 43 | "idiom" : "iphone", 44 | "filename" : "Icon.png", 45 | "scale" : "1x" 46 | }, 47 | { 48 | "size" : "57x57", 49 | "idiom" : "iphone", 50 | "filename" : "Icon@2x.png", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "size" : "60x60", 55 | "idiom" : "iphone", 56 | "filename" : "Icon-60@2x.png", 57 | "scale" : "2x" 58 | }, 59 | { 60 | "idiom" : "iphone", 61 | "size" : "60x60", 62 | "scale" : "3x" 63 | }, 64 | { 65 | "idiom" : "ipad", 66 | "size" : "20x20", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "idiom" : "ipad", 71 | "size" : "20x20", 72 | "scale" : "2x" 73 | }, 74 | { 75 | "size" : "29x29", 76 | "idiom" : "ipad", 77 | "filename" : "Icon-Small.png", 78 | "scale" : "1x" 79 | }, 80 | { 81 | "size" : "29x29", 82 | "idiom" : "ipad", 83 | "filename" : "Icon-Small@2x.png", 84 | "scale" : "2x" 85 | }, 86 | { 87 | "size" : "40x40", 88 | "idiom" : "ipad", 89 | "filename" : "Icon-40.png", 90 | "scale" : "1x" 91 | }, 92 | { 93 | "size" : "40x40", 94 | "idiom" : "ipad", 95 | "filename" : "Icon-40@2x-1.png", 96 | "scale" : "2x" 97 | }, 98 | { 99 | "size" : "50x50", 100 | "idiom" : "ipad", 101 | "filename" : "Icon-Small-50.png", 102 | "scale" : "1x" 103 | }, 104 | { 105 | "size" : "50x50", 106 | "idiom" : "ipad", 107 | "filename" : "Icon-Small-50@2x.png", 108 | "scale" : "2x" 109 | }, 110 | { 111 | "size" : "72x72", 112 | "idiom" : "ipad", 113 | "filename" : "Icon-72.png", 114 | "scale" : "1x" 115 | }, 116 | { 117 | "size" : "72x72", 118 | "idiom" : "ipad", 119 | "filename" : "Icon-72@2x.png", 120 | "scale" : "2x" 121 | }, 122 | { 123 | "size" : "76x76", 124 | "idiom" : "ipad", 125 | "filename" : "Icon-76.png", 126 | "scale" : "1x" 127 | }, 128 | { 129 | "size" : "76x76", 130 | "idiom" : "ipad", 131 | "filename" : "Icon-76@2x.png", 132 | "scale" : "2x" 133 | }, 134 | { 135 | "size" : "83.5x83.5", 136 | "idiom" : "ipad", 137 | "filename" : "Icon-167@2x.png", 138 | "scale" : "2x" 139 | } 140 | ], 141 | "info" : { 142 | "version" : 1, 143 | "author" : "xcode" 144 | } 145 | } -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-167@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-167@2x.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-40.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-40@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-40@2x-1.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-72.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-72@2x.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-Small-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-Small-1.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-Small-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-Small-50.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-Small.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandleth/LTHMonthYearPickerView/eaf708812dbfec47ac3786313cde0dcefb9dcfd7/LTHMonthYearPickerView Demo/Images.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/LTHAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // LTHAppDelegate.h 3 | // LTHMonthYearPickerView Demo 4 | // 5 | // Created by Roland Leth on 30/11/13. 6 | // Copyright (c) 2014 Roland Leth. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LTHAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/LTHAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // LTHAppDelegate.m 3 | // LTHMonthYearPickerView Demo 4 | // 5 | // Created by Roland Leth on 30/11/13. 6 | // Copyright (c) 2014 Roland Leth. All rights reserved. 7 | // 8 | 9 | #import "LTHAppDelegate.h" 10 | #import "LTHViewController.h" 11 | 12 | @implementation LTHAppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 15 | { 16 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 17 | self.window.rootViewController = [[LTHViewController alloc] init]; 18 | // Override point for customization after application launch. 19 | self.window.backgroundColor = [UIColor whiteColor]; 20 | [self.window makeKeyAndVisible]; 21 | return YES; 22 | } 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application 25 | { 26 | // 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. 27 | // 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. 28 | } 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application 31 | { 32 | // 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. 33 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 34 | } 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application 37 | { 38 | // 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. 39 | } 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application 42 | { 43 | // 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. 44 | } 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application 47 | { 48 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/LTHMonthYearPickerView Demo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIcons 12 | 13 | CFBundleIcons~ipad 14 | 15 | CFBundleIdentifier 16 | $(PRODUCT_BUNDLE_IDENTIFIER) 17 | CFBundleInfoDictionaryVersion 18 | 6.0 19 | CFBundleName 20 | ${PRODUCT_NAME} 21 | CFBundlePackageType 22 | APPL 23 | CFBundleShortVersionString 24 | 1.0 25 | CFBundleSignature 26 | ???? 27 | CFBundleVersion 28 | 1.0 29 | LSRequiresIPhoneOS 30 | 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/LTHMonthYearPickerView Demo-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/LTHViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LTHViewController.h 3 | // LTHMonthYearPickerView Demo 4 | // 5 | // Created by Roland Leth on 30/11/13. 6 | // Copyright (c) 2014 Roland Leth. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "LTHMonthYearPickerView.h" 11 | 12 | @interface LTHViewController : UIViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/LTHViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // LTHViewController.m 3 | // LTHMonthYearPickerView Demo 4 | // 5 | // Created by Roland Leth on 30/11/13. 6 | // Copyright (c) 2014 Roland Leth. All rights reserved. 7 | // 8 | 9 | #import "LTHViewController.h" 10 | 11 | 12 | @interface LTHViewController () 13 | 14 | @property (nonatomic, strong) UITextField *dateTextField; 15 | @property (nonatomic, strong) LTHMonthYearPickerView *monthYearPicker; 16 | @end 17 | 18 | 19 | @implementation LTHViewController 20 | 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | 25 | CGSize winSize = [UIScreen mainScreen].bounds.size; 26 | _dateTextField = [[UITextField alloc] initWithFrame: CGRectMake(winSize.width * 0.5 - 75.0, 27 | winSize.height * 0.5 - 20.0, 28 | 150.0, 29 | 40.0)]; 30 | 31 | NSDateFormatter *dateFormatter = [NSDateFormatter new]; 32 | [dateFormatter setDateFormat:@"MM / yyyy"]; 33 | NSDate *minDate = [dateFormatter dateFromString:[NSString stringWithFormat: @"%i / %i", 3, 2015]]; 34 | NSDate *maxDate = [dateFormatter dateFromString:[NSString stringWithFormat: @"%i / %i", 3, 2115]]; 35 | 36 | _monthYearPicker = [[LTHMonthYearPickerView alloc] initWithDate: [NSDate date] 37 | shortMonths: NO 38 | numberedMonths: NO 39 | andToolbar: YES 40 | minDate: minDate 41 | andMaxDate: maxDate]; 42 | // _monthYearPicker = [[LTHMonthYearPickerView alloc] initWithDate: [NSDate date] 43 | // shortMonths: NO 44 | // numberedMonths: NO 45 | // andToolbar: YES 46 | // minYear: 2015 47 | // andMaxYear: 2115]; 48 | _monthYearPicker.delegate = self; 49 | _dateTextField.delegate = self; 50 | _dateTextField.textAlignment = NSTextAlignmentCenter; 51 | _dateTextField.layer.borderColor = [UIColor lightGrayColor].CGColor; 52 | _dateTextField.layer.borderWidth = 1.0; 53 | _dateTextField.textColor = [UIColor purpleColor]; 54 | _dateTextField.tintColor = [UIColor purpleColor]; 55 | _dateTextField.inputView = _monthYearPicker; 56 | [self.view addSubview: _dateTextField]; 57 | [_dateTextField becomeFirstResponder]; 58 | } 59 | 60 | 61 | #pragma mark - LTHMonthYearPickerView Delegate 62 | - (void)pickerDidPressCancelWithInitialValues:(NSDictionary *)initialValues { 63 | _dateTextField.text = [NSString stringWithFormat: 64 | @"%@ / %@", 65 | initialValues[@"month"], 66 | initialValues[@"year"]]; 67 | [_dateTextField resignFirstResponder]; 68 | } 69 | 70 | 71 | - (void)pickerDidPressDoneWithMonth:(NSString *)month andYear:(NSString *)year { 72 | _dateTextField.text = [NSString stringWithFormat: @"%@ / %@", month, year]; 73 | [_dateTextField resignFirstResponder]; 74 | } 75 | 76 | 77 | - (void)pickerDidPressCancel { 78 | [_dateTextField resignFirstResponder]; 79 | } 80 | 81 | 82 | - (void)pickerDidSelectRow:(NSInteger)row inComponent:(NSInteger)component { 83 | NSLog(@"row: %zd in component: %zd", row, component); 84 | } 85 | 86 | 87 | - (void)pickerDidSelectMonth:(NSString *)month { 88 | NSLog(@"month: %@ ", month); 89 | } 90 | 91 | 92 | - (void)pickerDidSelectYear:(NSString *)year { 93 | NSLog(@"year: %@ ", year); 94 | } 95 | 96 | 97 | - (void)pickerDidSelectMonth:(NSString *)month andYear:(NSString *)year { 98 | _dateTextField.text = [NSString stringWithFormat: @"%@ / %@", month, year]; 99 | } 100 | 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /LTHMonthYearPickerView Demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // LTHMonthYearPickerView Demo 4 | // 5 | // Created by Roland Leth on 30/1/14. 6 | // Copyright (c) 2014 Roland Leth. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "LTHAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([LTHAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /LTHMonthYearPickerView/LTHMonthYearPickerView.h: -------------------------------------------------------------------------------- 1 | // 2 | // LTHMonthYearPickerView.m 3 | // LTHMonthYearPickerView Demo 4 | // 5 | // Created by Roland Leth on 30/11/13. 6 | // Copyright (c) 2014 Roland Leth. All rights reserved. 7 | // 8 | 9 | @protocol LTHMonthYearPickerViewDelegate 10 | @optional 11 | - (void)pickerDidSelectRow:(NSInteger)row inComponent:(NSInteger)component; 12 | - (void)pickerDidSelectMonth:(NSString *)month; 13 | - (void)pickerDidSelectYear:(NSString *)year; 14 | - (void)pickerDidSelectMonth:(NSString *)month andYear:(NSString *)year; 15 | - (void)pickerDidPressDoneWithMonth:(NSString *)month andYear:(NSString *)year; 16 | - (void)pickerDidPressCancel; 17 | /** 18 | @brief If you want to change your text field (and/or variables) dynamically by implementing any of the @c pickerDidSelect delegate methods, instead of doing the change when @c Done was pressed, you should implement this method too, so the @c Cancel button restores old values. 19 | @param initialValues @{ "month" : month, @"year" : year } 20 | */ 21 | - (void)pickerDidPressCancelWithInitialValues:(NSDictionary *)initialValues; 22 | @end 23 | 24 | @interface LTHMonthYearPickerView : UIView 25 | 26 | @property (nonatomic, weak) id delegate; 27 | @property (nonatomic, strong) UIPickerView *datePicker; 28 | @property (nonatomic, strong) NSString *year; 29 | @property (nonatomic, strong) NSString *month; 30 | 31 | 32 | /** 33 | @brief Month / Year picker view, for those pesky Credit Card expiration dates and alike. 34 | @param date set if you want the picker to be initialized with a specific month and year, otherwise it will be initialized with the current month and year. 35 | @param shortMonths set to YES if you want months to be returned as Jan, Feb, etc, set to NO if you want months to be returned as January, February, etc. 36 | @param numberedMonths set to YES if you want months to be returned as 01, 02, etc. This takes precedence over shortMonths if set to YES. 37 | @param showToolbar set to YES if you want the picker to have a Cancel/Done toolbar. 38 | @return a container view which contains the UIPicker and toolbar 39 | */ 40 | - (id)initWithDate:(NSDate *)date shortMonths:(BOOL)shortMonths numberedMonths:(BOOL)numberedMonths andToolbar:(BOOL)showToolbar; 41 | 42 | /** 43 | @brief Month / Year picker view, for those pesky Credit Card expiration dates and alike. 44 | @param date set if you want the picker to be initialized with a specific month and year, otherwise it will be initialized with the current month and year. 45 | @param shortMonths set to YES if you want months to be returned as Jan, Feb, etc, set to NO if you want months to be returned as January, February, etc. 46 | @param numberedMonths set to YES if you want months to be returned as 01, 02, etc. This takes precedence over shortMonths if set to YES. 47 | @param showToolbar set to YES if you want the picker to have a Cancel/Done toolbar. 48 | @param minYear set value for minimum year that is displayed in picker. 49 | @param maxYear set value for maximum year that is displayed in picker. 50 | @return a container view which contains the UIPicker and toolbar 51 | */ 52 | - (id)initWithDate:(NSDate *)date 53 | shortMonths:(BOOL)shortMonths 54 | numberedMonths:(BOOL)numberedMonths 55 | andToolbar:(BOOL)showToolbar 56 | minYear:(NSInteger)minYear 57 | andMaxYear:(NSInteger)maxYear; 58 | 59 | 60 | /** 61 | @brief Month / Year picker view, for those pesky Credit Card expiration dates and alike. 62 | @param date set if you want the picker to be initialized with a specific month and year, otherwise it will be initialized with the current month and year. 63 | @param shortMonths set to YES if you want months to be returned as Jan, Feb, etc, set to NO if you want months to be returned as January, February, etc. 64 | @param numberedMonths set to YES if you want months to be returned as 01, 02, etc. This takes precedence over shortMonths if set to YES. 65 | @param showToolbar set to YES if you want the picker to have a Cancel/Done toolbar. 66 | @param minDate set value for minimum date that is displayed in picker. Day 1 is default. 67 | @param maxDate set value for maximum date that is displayed in picker. Day 1 is default. 68 | @return a container view which contains the UIPicker and toolbar 69 | */ 70 | - (id)initWithDate:(NSDate *)date 71 | shortMonths:(BOOL)shortMonths 72 | numberedMonths:(BOOL)numberedMonths 73 | andToolbar:(BOOL)showToolbar 74 | minDate:(NSDate *)minDate 75 | andMaxDate:(NSDate *)maxDate; 76 | @end 77 | -------------------------------------------------------------------------------- /LTHMonthYearPickerView/LTHMonthYearPickerView.m: -------------------------------------------------------------------------------- 1 | // 2 | // LTHMonthYearPickerView.m 3 | // LTHMonthYearPickerView Demo 4 | // 5 | // Created by Roland Leth on 30/11/13. 6 | // Copyright (c) 2014 Roland Leth. All rights reserved. 7 | // 8 | 9 | #import "LTHMonthYearPickerView.h" 10 | 11 | #define kMonthColor [UIColor grayColor] 12 | #define kYearColor [UIColor darkGrayColor] 13 | #define kMonthFont [UIFont systemFontOfSize: 22.0] 14 | #define kYearFont [UIFont systemFontOfSize: 22.0] 15 | #define kWinSize [UIScreen mainScreen].bounds.size 16 | 17 | const NSUInteger kMonthComponent = 0; 18 | const NSUInteger kYearComponent = 1; 19 | const NSUInteger kMinYear = 1950; 20 | const NSUInteger kMaxYear = 2080; 21 | const CGFloat kRowHeight = 30.0; 22 | 23 | @interface LTHMonthYearPickerView () 24 | 25 | @property (readwrite) NSInteger yearIndex; 26 | @property (readwrite) NSInteger monthIndex; 27 | @property (nonatomic, strong) NSArray *months; 28 | @property (nonatomic, strong) NSMutableArray *years; 29 | @property (nonatomic, strong) NSDictionary *initialValues; 30 | @property (nonatomic, strong) NSDateComponents *minComponents; 31 | @property (nonatomic, strong) NSDateComponents *maxComponents; 32 | 33 | @end 34 | 35 | 36 | @implementation LTHMonthYearPickerView 37 | 38 | 39 | #pragma mark - UIPickerViewDelegate 40 | 41 | - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { 42 | if (!_initialValues) _initialValues = @{ @"month" : _months[_monthIndex], 43 | @"year" : _years[_yearIndex] }; 44 | NSUInteger (^month)(void) = ^NSUInteger() { 45 | return [pickerView selectedRowInComponent: 0]; 46 | }; 47 | NSUInteger (^year)(void) = ^NSUInteger() { 48 | return [pickerView selectedRowInComponent: 1]; 49 | }; 50 | 51 | if (year() == 0 && month() < _minComponents.month - 1) { 52 | _monthIndex = _minComponents.month - 1; 53 | [pickerView selectRow:_monthIndex inComponent:0 animated:YES]; 54 | } 55 | else if (year() == _years.count - 1 && month() > _maxComponents.month - 1) { 56 | _monthIndex = _maxComponents.month - 1; 57 | [pickerView selectRow:_monthIndex inComponent:0 animated:YES]; 58 | } 59 | 60 | if (component == 0) { 61 | _monthIndex = month(); 62 | if ([self.delegate respondsToSelector: @selector(pickerDidSelectMonth:)]) 63 | [self.delegate pickerDidSelectMonth: _months[_monthIndex]]; 64 | } 65 | else if (component == 1) { 66 | _yearIndex = year(); 67 | if ([self.delegate respondsToSelector: @selector(pickerDidSelectYear:)]) 68 | [self.delegate pickerDidSelectYear: _years[_yearIndex]]; 69 | } 70 | 71 | if ([self.delegate respondsToSelector: @selector(pickerDidSelectRow:inComponent:)]) { 72 | [self.delegate pickerDidSelectRow: row inComponent: component]; 73 | } 74 | if ([self.delegate respondsToSelector: @selector(pickerDidSelectMonth:andYear:)]) { 75 | [self.delegate pickerDidSelectMonth: _months[_monthIndex] 76 | andYear: _years[_yearIndex]]; 77 | } 78 | 79 | _year = _years[_yearIndex]; 80 | _month = _months[_monthIndex]; 81 | } 82 | 83 | 84 | - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view { 85 | UILabel *label = [[UILabel alloc] initWithFrame: CGRectZero]; 86 | label.textAlignment = NSTextAlignmentCenter; 87 | if (component == kMonthComponent) { 88 | label.text = [NSString stringWithFormat: @"%@", _months[row]]; 89 | label.textColor = kMonthColor; 90 | label.font = kMonthFont; 91 | label.frame = CGRectMake(0, 0, kWinSize.width * 0.5, kRowHeight); 92 | } 93 | else { 94 | label.text = [NSString stringWithFormat: @"%@", _years[row]]; 95 | label.textColor = kYearColor; 96 | label.font = kYearFont; 97 | label.frame = CGRectMake(kWinSize.width * 0.5, 0, kWinSize.width * 0.5, kRowHeight); 98 | } 99 | return label; 100 | } 101 | 102 | 103 | - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component { 104 | return self.bounds.size.width / 2; 105 | } 106 | 107 | 108 | #pragma mark - UIPickerViewDataSource 109 | 110 | - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { 111 | return 2; 112 | } 113 | 114 | 115 | - (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component { 116 | return kRowHeight; 117 | } 118 | 119 | 120 | - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { 121 | if (component == kMonthComponent) { 122 | return _months.count; 123 | } 124 | return _years.count; 125 | } 126 | 127 | 128 | #pragma mark - Actions 129 | 130 | - (void)_done { 131 | if ([self.delegate respondsToSelector: @selector(pickerDidPressDoneWithMonth:andYear:)]) 132 | [self.delegate pickerDidPressDoneWithMonth: _months[_monthIndex] 133 | andYear: _years[_yearIndex]]; 134 | 135 | _initialValues = nil; 136 | _year = _years[_yearIndex]; 137 | _month = _months[_monthIndex]; 138 | } 139 | 140 | 141 | - (void)_cancel { 142 | if (!_initialValues) _initialValues = @{ @"month" : _months[_monthIndex], 143 | @"year" : _years[_yearIndex] }; 144 | if ([self.delegate respondsToSelector: @selector(pickerDidPressCancelWithInitialValues:)]) { 145 | [self.delegate pickerDidPressCancelWithInitialValues: _initialValues]; 146 | [self.datePicker selectRow: [_months indexOfObject: _initialValues[@"month"]] 147 | inComponent: 0 148 | animated: NO]; 149 | [self.datePicker selectRow: [_years indexOfObject: _initialValues[@"year"]] 150 | inComponent: 1 151 | animated: NO]; 152 | } 153 | else if ([self.delegate respondsToSelector: @selector(pickerDidPressCancel)]) { 154 | [self.delegate pickerDidPressCancel]; 155 | } 156 | 157 | _monthIndex = [_months indexOfObject: _initialValues[@"month"]]; 158 | _yearIndex = [_years indexOfObject: _initialValues[@"year"]]; 159 | _year = _years[_yearIndex]; 160 | _month = _months[_monthIndex]; 161 | _initialValues = nil; 162 | } 163 | 164 | 165 | #pragma mark - Init 166 | 167 | - (void)_setupComponentsFromDate:(NSDate *)date { 168 | NSCalendar *calendar = [NSCalendar currentCalendar]; 169 | NSDateComponents *dateComponents = 170 | [calendar components: NSCalendarUnitMonth | NSCalendarUnitYear 171 | fromDate: date]; 172 | 173 | NSInteger currentYear = MAX(_minComponents.year, MIN(_maxComponents.year, dateComponents.year)); 174 | 175 | _yearIndex = [_years indexOfObject: [NSString stringWithFormat: @"%zd", currentYear]]; 176 | _monthIndex = dateComponents.month - 1; 177 | 178 | [_datePicker selectRow: _monthIndex 179 | inComponent: 0 180 | animated: YES]; 181 | [_datePicker selectRow: _yearIndex 182 | inComponent: 1 183 | animated: YES]; 184 | [self performSelector: @selector(_sendFirstPickerValues) withObject: nil afterDelay: 0.1]; 185 | } 186 | 187 | - (void)_sendFirstPickerValues { 188 | if ([self.delegate respondsToSelector: @selector(pickerDidSelectRow:inComponent:)]) { 189 | [self.delegate pickerDidSelectRow: [self.datePicker selectedRowInComponent:0] 190 | inComponent: 0]; 191 | [self.delegate pickerDidSelectRow: [self.datePicker selectedRowInComponent:1] 192 | inComponent: 1]; 193 | } 194 | if ([self.delegate respondsToSelector: @selector(pickerDidSelectMonth:andYear:)]) 195 | [self.delegate pickerDidSelectMonth: _months[_monthIndex] 196 | andYear: _years[_yearIndex]]; 197 | _year = _years[_yearIndex]; 198 | _month = _months[_monthIndex]; 199 | } 200 | 201 | 202 | #pragma mark - Init 203 | - (id)initWithDate:(NSDate *)date shortMonths:(BOOL)shortMonths numberedMonths:(BOOL)numberedMonths andToolbar:(BOOL)showToolbar { 204 | return [self initWithDate:date shortMonths:shortMonths numberedMonths:numberedMonths andToolbar:showToolbar minYear:kMinYear andMaxYear:kMaxYear]; 205 | } 206 | 207 | - (id)initWithDate:(NSDate *)date shortMonths:(BOOL)shortMonths numberedMonths:(BOOL)numberedMonths andToolbar:(BOOL)showToolbar minDate:(NSDate *)minDate andMaxDate:(NSDate *)maxDate { 208 | self = [super init]; 209 | 210 | if (self != nil) { 211 | if ([date compare:minDate] == NSOrderedAscending) { 212 | date = minDate; 213 | } 214 | else if ([date compare:maxDate] == NSOrderedDescending) { 215 | date = maxDate; 216 | } 217 | 218 | NSCalendar *calendar = [NSCalendar currentCalendar]; 219 | _minComponents = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth 220 | fromDate:minDate]; 221 | _maxComponents = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth 222 | fromDate:maxDate]; 223 | 224 | if (!date) { date = [NSDate date]; } 225 | 226 | NSDateComponents *dateComponents = [NSDateComponents new]; 227 | NSDateFormatter *dateFormatter = [NSDateFormatter new]; 228 | NSMutableArray *months = [NSMutableArray new]; 229 | dateComponents.month = 1; 230 | 231 | if (numberedMonths) { [dateFormatter setDateFormat: @"MM"]; } 232 | else if (shortMonths) { [dateFormatter setDateFormat: @"MMM"]; } 233 | else { [dateFormatter setDateFormat: @"MMMM"]; } 234 | 235 | for (NSInteger i = 1; i <= 12; i++) { 236 | [months addObject: [dateFormatter stringFromDate: [calendar dateFromComponents: dateComponents]]]; 237 | dateComponents.month++; 238 | } 239 | 240 | _months = [months copy]; 241 | _years = [NSMutableArray new]; 242 | 243 | for (NSInteger year = _minComponents.year; year <= _maxComponents.year; year++) { 244 | [_years addObject: [NSString stringWithFormat: @"%zd", year]]; 245 | } 246 | 247 | CGRect datePickerFrame; 248 | if (showToolbar) { 249 | self.frame = CGRectMake(0.0, 0.0, kWinSize.width, 260.0); 250 | datePickerFrame = CGRectMake(0.0, 44.5, self.frame.size.width, 216.0); 251 | 252 | UIToolbar *toolbar = [[UIToolbar alloc] 253 | initWithFrame: CGRectMake(0.0, 0.0, self.frame.size.width, datePickerFrame.origin.y - 0.5)]; 254 | 255 | UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] 256 | initWithBarButtonSystemItem: UIBarButtonSystemItemCancel 257 | target: self 258 | action: @selector(_cancel)]; 259 | UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] 260 | initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace 261 | target: self 262 | action: nil]; 263 | UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] 264 | initWithBarButtonSystemItem: UIBarButtonSystemItemDone 265 | target: self 266 | action: @selector(_done)]; 267 | 268 | toolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth; 269 | [toolbar setItems: @[cancelButton, flexSpace, doneBtn] 270 | animated: YES]; 271 | [self addSubview: toolbar]; 272 | } 273 | else { 274 | self.frame = CGRectMake(0.0, 0.0, kWinSize.width, 216.0); 275 | datePickerFrame = self.frame; 276 | } 277 | _datePicker = [[UIPickerView alloc] initWithFrame: datePickerFrame]; 278 | _datePicker.autoresizingMask = UIViewAutoresizingFlexibleWidth; 279 | _datePicker.dataSource = self; 280 | _datePicker.delegate = self; 281 | [self addSubview: _datePicker]; 282 | [self _setupComponentsFromDate: date]; 283 | } 284 | 285 | return self; 286 | } 287 | 288 | - (id)initWithDate:(NSDate *)date shortMonths:(BOOL)shortMonths numberedMonths:(BOOL)numberedMonths andToolbar:(BOOL)showToolbar minYear:(NSInteger)minYear andMaxYear:(NSInteger)maxYear { 289 | NSDate *current = [NSDate date]; 290 | 291 | NSDateComponents *minComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitYear | NSCalendarUnitMonth 292 | fromDate:current]; 293 | minComponents.year = minYear; 294 | minComponents.month = 1; 295 | NSDate *minDate = [[NSCalendar currentCalendar] dateFromComponents:minComponents]; 296 | 297 | NSDate *maxFromCurrent = [[NSCalendar currentCalendar] dateBySettingUnit:NSCalendarUnitYear 298 | value:maxYear + 1 299 | ofDate:current 300 | options:NSCalendarMatchNextTime | NSCalendarMatchLast]; 301 | NSDate *maxDate = [[NSCalendar currentCalendar] dateByAddingUnit:NSCalendarUnitDay 302 | value:-1 303 | toDate:maxFromCurrent 304 | options:NSCalendarMatchNextTime | NSCalendarMatchLast]; 305 | 306 | return [self initWithDate:date shortMonths:shortMonths numberedMonths:numberedMonths andToolbar:showToolbar minDate:minDate andMaxDate:maxDate]; 307 | } 308 | 309 | 310 | #pragma mark - Setters 311 | 312 | - (void)setMonth:(NSString *)month { 313 | _monthIndex = [_months indexOfObject:month]; 314 | [_datePicker selectRow:_monthIndex inComponent:0 animated:NO]; 315 | } 316 | 317 | - (void)setYear:(NSString *)year { 318 | _yearIndex = [_years indexOfObject:year]; 319 | [_datePicker selectRow:_yearIndex inComponent:1 animated:NO]; 320 | } 321 | 322 | 323 | @end 324 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LTHMonthYearPickerView 2 | Simple to use month & year picker view for those pesky Credit Card expiration dates & Co. 3 | 4 | # How to use 5 | Drag the contents of `LTHMonthYearPickerView` to your project, or add `pod 'LTHMonthYearPickerView'` to your podspec file. 6 | 7 | ```objc 8 | /** 9 | * Month / Year picker view, for those pesky Credit Card expiration dates and alike. 10 | * 11 | * @param date set to a date if you want the picker to be initialized with a specific month and year, otherwise it is initialized with the current month and year. 12 | * @param shortMonths set to YES if you want months to be returned as Jan, Feb, etc, set to NO if you want months to be returned as January, February, etc. 13 | * @param numberedMonths set to YES if you want months to be returned as 01, 02, etc. This takes precedence over shortMonths if set to YES. 14 | * @param showToolbar set to YES if you want the picker to have a Cancel/Done toolbar. 15 | * 16 | * @return a container view which contains the UIPicker and toolbar 17 | */ 18 | _monthYearPicker = [[LTHMonthYearPickerView alloc] initWithDate: [NSDate date] 19 | shortMonths: NO 20 | numberedMonths: NO 21 | andToolbar: YES]; 22 | _monthYearPicker.delegate = self; 23 | ``` 24 | 25 | Comes with several delegate methods: 26 | ```objc 27 | - (void)pickerDidSelectRow:(NSInteger)row inComponent:(NSInteger)component; 28 | - (void)pickerDidSelectMonth:(NSString *)month; 29 | - (void)pickerDidSelectYear:(NSString *)year; 30 | - (void)pickerDidSelectMonth:(NSString *)month andYear:(NSString *)year; 31 | - (void)pickerDidPressDoneWithMonth:(NSString *)month andYear:(NSString *)year; 32 | - (void)pickerDidPressCancel; 33 | - (void)pickerDidPressCancelWithInitialValues:(NSDictionary *)initialValues; 34 | // Or corresponding notifications; if you prefer it like that, just uncomment the notification posts. 35 | ``` 36 | 37 | Everything is easily customizable with macros and constants, from month & year fonts and colors (individually) to the month names, if you need them in another language (control was created long ago and I didn't really think of proper localization). 38 | 39 | ![Screenshot](https://rolandleth.com/images/monthyearpickerview/Screenshot.png) 40 | 41 | # Apps using this control 42 | If you're using this control, I'd love hearing from you! 43 | 44 | # License 45 | Licensed under MIT. If you'd like (or need) a license without attribution, don't hesitate to [contact me](mailto:roland@rolandleth.com). --------------------------------------------------------------------------------