├── HooDatePicker └── 1.0 │ └── HooDatePicker.podspec ├── HooDatePickerDeomo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── hoojackie.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── hoojackie.xcuserdatad │ └── xcschemes │ │ ├── HooDatePickerDeomo.xcscheme │ │ └── xcschememanagement.plist │ └── hujh.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── HooDatePickerDeomo.xcscheme │ └── xcschememanagement.plist ├── HooDatePickerDeomo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── HooDatePicker │ ├── HooDatePicker.h │ ├── HooDatePicker.m │ ├── NSDate+HooDatePicker.h │ └── NSDate+HooDatePicker.m ├── Info.plist ├── Simulator Screen Shot Mar 6, 2016, 3.04.09 AM.png ├── Simulator Screen Shot Mar 6, 2016, 3.04.30 AM.png ├── ViewController.h ├── ViewController.m └── main.m ├── HooDatePickerDeomoTests ├── HooDatePickerDeomoTests.m └── Info.plist ├── HooDatePickerDeomoUITests ├── HooDatePickerDeomoUITests.m └── Info.plist ├── LICENSE └── README.md /HooDatePicker/1.0/HooDatePicker.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "HooDatePicker" 3 | s.version = "1.0" 4 | s.summary = "一个非常漂亮的日期选择空间The open source for a beautiful date picker." 5 | s.homepage = "https://github.com/jakciehoo/HooDatePicker.git" 6 | s.license = 'Code is MIT, then custom font licenses.' 7 | s.author = { "jackiehoo" => "niat05ethjh1112@163.com" } 8 | s.source = { :git => "https://github.com/jakciehoo/HooDatePicker.git", :tag => s.version } 9 | s.social_media_url = 'http://jackiehoo.com/' 10 | s.platform = :ios, '7.0' 11 | s.requires_arc = true 12 | 13 | s.source_files = 'HooDatePickerDeomo/HooDatePicker/*{h,m}' 14 | 15 | s.frameworks = 'UIKit' 16 | s.module_name = 'HooDatePicker' 17 | end 18 | -------------------------------------------------------------------------------- /HooDatePickerDeomo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 225C163C1C8ADF7A00040297 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 225C163B1C8ADF7A00040297 /* main.m */; }; 11 | 225C163F1C8ADF7A00040297 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 225C163E1C8ADF7A00040297 /* AppDelegate.m */; }; 12 | 225C16421C8ADF7A00040297 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 225C16411C8ADF7A00040297 /* ViewController.m */; }; 13 | 225C16451C8ADF7A00040297 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 225C16431C8ADF7A00040297 /* Main.storyboard */; }; 14 | 225C16471C8ADF7A00040297 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 225C16461C8ADF7A00040297 /* Assets.xcassets */; }; 15 | 225C164A1C8ADF7A00040297 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 225C16481C8ADF7A00040297 /* LaunchScreen.storyboard */; }; 16 | 225C16551C8ADF7A00040297 /* HooDatePickerDeomoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 225C16541C8ADF7A00040297 /* HooDatePickerDeomoTests.m */; }; 17 | 225C16601C8ADF7A00040297 /* HooDatePickerDeomoUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 225C165F1C8ADF7A00040297 /* HooDatePickerDeomoUITests.m */; }; 18 | 225C16721C8B656400040297 /* Simulator Screen Shot Mar 6, 2016, 3.04.09 AM.png in Resources */ = {isa = PBXBuildFile; fileRef = 225C16711C8B656400040297 /* Simulator Screen Shot Mar 6, 2016, 3.04.09 AM.png */; }; 19 | 225C16741C8B656E00040297 /* Simulator Screen Shot Mar 6, 2016, 3.04.30 AM.png in Resources */ = {isa = PBXBuildFile; fileRef = 225C16731C8B656E00040297 /* Simulator Screen Shot Mar 6, 2016, 3.04.30 AM.png */; }; 20 | 226DC5371C9EA384008EE2F7 /* HooDatePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 226DC5361C9EA384008EE2F7 /* HooDatePicker.m */; }; 21 | 22A64FA01D18CDC300EAA922 /* NSDate+HooDatePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 22A64F9F1D18CDC300EAA922 /* NSDate+HooDatePicker.m */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | 225C16511C8ADF7A00040297 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = 225C162F1C8ADF7A00040297 /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = 225C16361C8ADF7A00040297; 30 | remoteInfo = HooDatePickerDeomo; 31 | }; 32 | 225C165C1C8ADF7A00040297 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = 225C162F1C8ADF7A00040297 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = 225C16361C8ADF7A00040297; 37 | remoteInfo = HooDatePickerDeomo; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXFileReference section */ 42 | 225C16371C8ADF7A00040297 /* HooDatePickerDeomo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HooDatePickerDeomo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 43 | 225C163B1C8ADF7A00040297 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 44 | 225C163D1C8ADF7A00040297 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 45 | 225C163E1C8ADF7A00040297 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 46 | 225C16401C8ADF7A00040297 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 47 | 225C16411C8ADF7A00040297 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 48 | 225C16441C8ADF7A00040297 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 49 | 225C16461C8ADF7A00040297 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 50 | 225C16491C8ADF7A00040297 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 51 | 225C164B1C8ADF7A00040297 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | 225C16501C8ADF7A00040297 /* HooDatePickerDeomoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HooDatePickerDeomoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 225C16541C8ADF7A00040297 /* HooDatePickerDeomoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HooDatePickerDeomoTests.m; sourceTree = ""; }; 54 | 225C16561C8ADF7A00040297 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55 | 225C165B1C8ADF7A00040297 /* HooDatePickerDeomoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HooDatePickerDeomoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | 225C165F1C8ADF7A00040297 /* HooDatePickerDeomoUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HooDatePickerDeomoUITests.m; sourceTree = ""; }; 57 | 225C16611C8ADF7A00040297 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | 225C16711C8B656400040297 /* Simulator Screen Shot Mar 6, 2016, 3.04.09 AM.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Simulator Screen Shot Mar 6, 2016, 3.04.09 AM.png"; sourceTree = ""; }; 59 | 225C16731C8B656E00040297 /* Simulator Screen Shot Mar 6, 2016, 3.04.30 AM.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Simulator Screen Shot Mar 6, 2016, 3.04.30 AM.png"; sourceTree = ""; }; 60 | 226DC5351C9EA384008EE2F7 /* HooDatePicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HooDatePicker.h; sourceTree = ""; }; 61 | 226DC5361C9EA384008EE2F7 /* HooDatePicker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HooDatePicker.m; sourceTree = ""; }; 62 | 22A64F9E1D18CDC300EAA922 /* NSDate+HooDatePicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+HooDatePicker.h"; sourceTree = ""; }; 63 | 22A64F9F1D18CDC300EAA922 /* NSDate+HooDatePicker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+HooDatePicker.m"; sourceTree = ""; }; 64 | /* End PBXFileReference section */ 65 | 66 | /* Begin PBXFrameworksBuildPhase section */ 67 | 225C16341C8ADF7A00040297 /* Frameworks */ = { 68 | isa = PBXFrameworksBuildPhase; 69 | buildActionMask = 2147483647; 70 | files = ( 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | 225C164D1C8ADF7A00040297 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | 225C16581C8ADF7A00040297 /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | /* End PBXFrameworksBuildPhase section */ 89 | 90 | /* Begin PBXGroup section */ 91 | 225C162E1C8ADF7A00040297 = { 92 | isa = PBXGroup; 93 | children = ( 94 | 225C16391C8ADF7A00040297 /* HooDatePickerDeomo */, 95 | 225C16531C8ADF7A00040297 /* HooDatePickerDeomoTests */, 96 | 225C165E1C8ADF7A00040297 /* HooDatePickerDeomoUITests */, 97 | 225C16381C8ADF7A00040297 /* Products */, 98 | ); 99 | sourceTree = ""; 100 | }; 101 | 225C16381C8ADF7A00040297 /* Products */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | 225C16371C8ADF7A00040297 /* HooDatePickerDeomo.app */, 105 | 225C16501C8ADF7A00040297 /* HooDatePickerDeomoTests.xctest */, 106 | 225C165B1C8ADF7A00040297 /* HooDatePickerDeomoUITests.xctest */, 107 | ); 108 | name = Products; 109 | sourceTree = ""; 110 | }; 111 | 225C16391C8ADF7A00040297 /* HooDatePickerDeomo */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 226DC5341C9EA384008EE2F7 /* HooDatePicker */, 115 | 225C163D1C8ADF7A00040297 /* AppDelegate.h */, 116 | 225C163E1C8ADF7A00040297 /* AppDelegate.m */, 117 | 225C16401C8ADF7A00040297 /* ViewController.h */, 118 | 225C16411C8ADF7A00040297 /* ViewController.m */, 119 | 225C16431C8ADF7A00040297 /* Main.storyboard */, 120 | 225C16711C8B656400040297 /* Simulator Screen Shot Mar 6, 2016, 3.04.09 AM.png */, 121 | 225C16731C8B656E00040297 /* Simulator Screen Shot Mar 6, 2016, 3.04.30 AM.png */, 122 | 225C16461C8ADF7A00040297 /* Assets.xcassets */, 123 | 225C16481C8ADF7A00040297 /* LaunchScreen.storyboard */, 124 | 225C164B1C8ADF7A00040297 /* Info.plist */, 125 | 225C163A1C8ADF7A00040297 /* Supporting Files */, 126 | ); 127 | path = HooDatePickerDeomo; 128 | sourceTree = ""; 129 | }; 130 | 225C163A1C8ADF7A00040297 /* Supporting Files */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 225C163B1C8ADF7A00040297 /* main.m */, 134 | ); 135 | name = "Supporting Files"; 136 | sourceTree = ""; 137 | }; 138 | 225C16531C8ADF7A00040297 /* HooDatePickerDeomoTests */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | 225C16541C8ADF7A00040297 /* HooDatePickerDeomoTests.m */, 142 | 225C16561C8ADF7A00040297 /* Info.plist */, 143 | ); 144 | path = HooDatePickerDeomoTests; 145 | sourceTree = ""; 146 | }; 147 | 225C165E1C8ADF7A00040297 /* HooDatePickerDeomoUITests */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 225C165F1C8ADF7A00040297 /* HooDatePickerDeomoUITests.m */, 151 | 225C16611C8ADF7A00040297 /* Info.plist */, 152 | ); 153 | path = HooDatePickerDeomoUITests; 154 | sourceTree = ""; 155 | }; 156 | 226DC5341C9EA384008EE2F7 /* HooDatePicker */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 226DC5351C9EA384008EE2F7 /* HooDatePicker.h */, 160 | 226DC5361C9EA384008EE2F7 /* HooDatePicker.m */, 161 | 22A64F9E1D18CDC300EAA922 /* NSDate+HooDatePicker.h */, 162 | 22A64F9F1D18CDC300EAA922 /* NSDate+HooDatePicker.m */, 163 | ); 164 | path = HooDatePicker; 165 | sourceTree = ""; 166 | }; 167 | /* End PBXGroup section */ 168 | 169 | /* Begin PBXNativeTarget section */ 170 | 225C16361C8ADF7A00040297 /* HooDatePickerDeomo */ = { 171 | isa = PBXNativeTarget; 172 | buildConfigurationList = 225C16641C8ADF7A00040297 /* Build configuration list for PBXNativeTarget "HooDatePickerDeomo" */; 173 | buildPhases = ( 174 | 225C16331C8ADF7A00040297 /* Sources */, 175 | 225C16341C8ADF7A00040297 /* Frameworks */, 176 | 225C16351C8ADF7A00040297 /* Resources */, 177 | ); 178 | buildRules = ( 179 | ); 180 | dependencies = ( 181 | ); 182 | name = HooDatePickerDeomo; 183 | productName = HooDatePickerDeomo; 184 | productReference = 225C16371C8ADF7A00040297 /* HooDatePickerDeomo.app */; 185 | productType = "com.apple.product-type.application"; 186 | }; 187 | 225C164F1C8ADF7A00040297 /* HooDatePickerDeomoTests */ = { 188 | isa = PBXNativeTarget; 189 | buildConfigurationList = 225C16671C8ADF7A00040297 /* Build configuration list for PBXNativeTarget "HooDatePickerDeomoTests" */; 190 | buildPhases = ( 191 | 225C164C1C8ADF7A00040297 /* Sources */, 192 | 225C164D1C8ADF7A00040297 /* Frameworks */, 193 | 225C164E1C8ADF7A00040297 /* Resources */, 194 | ); 195 | buildRules = ( 196 | ); 197 | dependencies = ( 198 | 225C16521C8ADF7A00040297 /* PBXTargetDependency */, 199 | ); 200 | name = HooDatePickerDeomoTests; 201 | productName = HooDatePickerDeomoTests; 202 | productReference = 225C16501C8ADF7A00040297 /* HooDatePickerDeomoTests.xctest */; 203 | productType = "com.apple.product-type.bundle.unit-test"; 204 | }; 205 | 225C165A1C8ADF7A00040297 /* HooDatePickerDeomoUITests */ = { 206 | isa = PBXNativeTarget; 207 | buildConfigurationList = 225C166A1C8ADF7A00040297 /* Build configuration list for PBXNativeTarget "HooDatePickerDeomoUITests" */; 208 | buildPhases = ( 209 | 225C16571C8ADF7A00040297 /* Sources */, 210 | 225C16581C8ADF7A00040297 /* Frameworks */, 211 | 225C16591C8ADF7A00040297 /* Resources */, 212 | ); 213 | buildRules = ( 214 | ); 215 | dependencies = ( 216 | 225C165D1C8ADF7A00040297 /* PBXTargetDependency */, 217 | ); 218 | name = HooDatePickerDeomoUITests; 219 | productName = HooDatePickerDeomoUITests; 220 | productReference = 225C165B1C8ADF7A00040297 /* HooDatePickerDeomoUITests.xctest */; 221 | productType = "com.apple.product-type.bundle.ui-testing"; 222 | }; 223 | /* End PBXNativeTarget section */ 224 | 225 | /* Begin PBXProject section */ 226 | 225C162F1C8ADF7A00040297 /* Project object */ = { 227 | isa = PBXProject; 228 | attributes = { 229 | LastUpgradeCheck = 0720; 230 | ORGANIZATIONNAME = hujianghua; 231 | TargetAttributes = { 232 | 225C16361C8ADF7A00040297 = { 233 | CreatedOnToolsVersion = 7.2; 234 | }; 235 | 225C164F1C8ADF7A00040297 = { 236 | CreatedOnToolsVersion = 7.2; 237 | TestTargetID = 225C16361C8ADF7A00040297; 238 | }; 239 | 225C165A1C8ADF7A00040297 = { 240 | CreatedOnToolsVersion = 7.2; 241 | TestTargetID = 225C16361C8ADF7A00040297; 242 | }; 243 | }; 244 | }; 245 | buildConfigurationList = 225C16321C8ADF7A00040297 /* Build configuration list for PBXProject "HooDatePickerDeomo" */; 246 | compatibilityVersion = "Xcode 3.2"; 247 | developmentRegion = English; 248 | hasScannedForEncodings = 0; 249 | knownRegions = ( 250 | en, 251 | Base, 252 | ); 253 | mainGroup = 225C162E1C8ADF7A00040297; 254 | productRefGroup = 225C16381C8ADF7A00040297 /* Products */; 255 | projectDirPath = ""; 256 | projectRoot = ""; 257 | targets = ( 258 | 225C16361C8ADF7A00040297 /* HooDatePickerDeomo */, 259 | 225C164F1C8ADF7A00040297 /* HooDatePickerDeomoTests */, 260 | 225C165A1C8ADF7A00040297 /* HooDatePickerDeomoUITests */, 261 | ); 262 | }; 263 | /* End PBXProject section */ 264 | 265 | /* Begin PBXResourcesBuildPhase section */ 266 | 225C16351C8ADF7A00040297 /* Resources */ = { 267 | isa = PBXResourcesBuildPhase; 268 | buildActionMask = 2147483647; 269 | files = ( 270 | 225C164A1C8ADF7A00040297 /* LaunchScreen.storyboard in Resources */, 271 | 225C16471C8ADF7A00040297 /* Assets.xcassets in Resources */, 272 | 225C16451C8ADF7A00040297 /* Main.storyboard in Resources */, 273 | 225C16741C8B656E00040297 /* Simulator Screen Shot Mar 6, 2016, 3.04.30 AM.png in Resources */, 274 | 225C16721C8B656400040297 /* Simulator Screen Shot Mar 6, 2016, 3.04.09 AM.png in Resources */, 275 | ); 276 | runOnlyForDeploymentPostprocessing = 0; 277 | }; 278 | 225C164E1C8ADF7A00040297 /* Resources */ = { 279 | isa = PBXResourcesBuildPhase; 280 | buildActionMask = 2147483647; 281 | files = ( 282 | ); 283 | runOnlyForDeploymentPostprocessing = 0; 284 | }; 285 | 225C16591C8ADF7A00040297 /* Resources */ = { 286 | isa = PBXResourcesBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | ); 290 | runOnlyForDeploymentPostprocessing = 0; 291 | }; 292 | /* End PBXResourcesBuildPhase section */ 293 | 294 | /* Begin PBXSourcesBuildPhase section */ 295 | 225C16331C8ADF7A00040297 /* Sources */ = { 296 | isa = PBXSourcesBuildPhase; 297 | buildActionMask = 2147483647; 298 | files = ( 299 | 226DC5371C9EA384008EE2F7 /* HooDatePicker.m in Sources */, 300 | 225C16421C8ADF7A00040297 /* ViewController.m in Sources */, 301 | 225C163F1C8ADF7A00040297 /* AppDelegate.m in Sources */, 302 | 22A64FA01D18CDC300EAA922 /* NSDate+HooDatePicker.m in Sources */, 303 | 225C163C1C8ADF7A00040297 /* main.m in Sources */, 304 | ); 305 | runOnlyForDeploymentPostprocessing = 0; 306 | }; 307 | 225C164C1C8ADF7A00040297 /* Sources */ = { 308 | isa = PBXSourcesBuildPhase; 309 | buildActionMask = 2147483647; 310 | files = ( 311 | 225C16551C8ADF7A00040297 /* HooDatePickerDeomoTests.m in Sources */, 312 | ); 313 | runOnlyForDeploymentPostprocessing = 0; 314 | }; 315 | 225C16571C8ADF7A00040297 /* Sources */ = { 316 | isa = PBXSourcesBuildPhase; 317 | buildActionMask = 2147483647; 318 | files = ( 319 | 225C16601C8ADF7A00040297 /* HooDatePickerDeomoUITests.m in Sources */, 320 | ); 321 | runOnlyForDeploymentPostprocessing = 0; 322 | }; 323 | /* End PBXSourcesBuildPhase section */ 324 | 325 | /* Begin PBXTargetDependency section */ 326 | 225C16521C8ADF7A00040297 /* PBXTargetDependency */ = { 327 | isa = PBXTargetDependency; 328 | target = 225C16361C8ADF7A00040297 /* HooDatePickerDeomo */; 329 | targetProxy = 225C16511C8ADF7A00040297 /* PBXContainerItemProxy */; 330 | }; 331 | 225C165D1C8ADF7A00040297 /* PBXTargetDependency */ = { 332 | isa = PBXTargetDependency; 333 | target = 225C16361C8ADF7A00040297 /* HooDatePickerDeomo */; 334 | targetProxy = 225C165C1C8ADF7A00040297 /* PBXContainerItemProxy */; 335 | }; 336 | /* End PBXTargetDependency section */ 337 | 338 | /* Begin PBXVariantGroup section */ 339 | 225C16431C8ADF7A00040297 /* Main.storyboard */ = { 340 | isa = PBXVariantGroup; 341 | children = ( 342 | 225C16441C8ADF7A00040297 /* Base */, 343 | ); 344 | name = Main.storyboard; 345 | sourceTree = ""; 346 | }; 347 | 225C16481C8ADF7A00040297 /* LaunchScreen.storyboard */ = { 348 | isa = PBXVariantGroup; 349 | children = ( 350 | 225C16491C8ADF7A00040297 /* Base */, 351 | ); 352 | name = LaunchScreen.storyboard; 353 | sourceTree = ""; 354 | }; 355 | /* End PBXVariantGroup section */ 356 | 357 | /* Begin XCBuildConfiguration section */ 358 | 225C16621C8ADF7A00040297 /* Debug */ = { 359 | isa = XCBuildConfiguration; 360 | buildSettings = { 361 | ALWAYS_SEARCH_USER_PATHS = NO; 362 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 363 | CLANG_CXX_LIBRARY = "libc++"; 364 | CLANG_ENABLE_MODULES = YES; 365 | CLANG_ENABLE_OBJC_ARC = YES; 366 | CLANG_WARN_BOOL_CONVERSION = YES; 367 | CLANG_WARN_CONSTANT_CONVERSION = YES; 368 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 369 | CLANG_WARN_EMPTY_BODY = YES; 370 | CLANG_WARN_ENUM_CONVERSION = YES; 371 | CLANG_WARN_INT_CONVERSION = YES; 372 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 373 | CLANG_WARN_UNREACHABLE_CODE = YES; 374 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 375 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 376 | COPY_PHASE_STRIP = NO; 377 | DEBUG_INFORMATION_FORMAT = dwarf; 378 | ENABLE_STRICT_OBJC_MSGSEND = YES; 379 | ENABLE_TESTABILITY = YES; 380 | GCC_C_LANGUAGE_STANDARD = gnu99; 381 | GCC_DYNAMIC_NO_PIC = NO; 382 | GCC_NO_COMMON_BLOCKS = YES; 383 | GCC_OPTIMIZATION_LEVEL = 0; 384 | GCC_PREPROCESSOR_DEFINITIONS = ( 385 | "DEBUG=1", 386 | "$(inherited)", 387 | ); 388 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 389 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 390 | GCC_WARN_UNDECLARED_SELECTOR = YES; 391 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 392 | GCC_WARN_UNUSED_FUNCTION = YES; 393 | GCC_WARN_UNUSED_VARIABLE = YES; 394 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 395 | MTL_ENABLE_DEBUG_INFO = YES; 396 | ONLY_ACTIVE_ARCH = YES; 397 | SDKROOT = iphoneos; 398 | }; 399 | name = Debug; 400 | }; 401 | 225C16631C8ADF7A00040297 /* Release */ = { 402 | isa = XCBuildConfiguration; 403 | buildSettings = { 404 | ALWAYS_SEARCH_USER_PATHS = NO; 405 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 406 | CLANG_CXX_LIBRARY = "libc++"; 407 | CLANG_ENABLE_MODULES = YES; 408 | CLANG_ENABLE_OBJC_ARC = YES; 409 | CLANG_WARN_BOOL_CONVERSION = YES; 410 | CLANG_WARN_CONSTANT_CONVERSION = YES; 411 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 412 | CLANG_WARN_EMPTY_BODY = YES; 413 | CLANG_WARN_ENUM_CONVERSION = YES; 414 | CLANG_WARN_INT_CONVERSION = YES; 415 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 416 | CLANG_WARN_UNREACHABLE_CODE = YES; 417 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 418 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 419 | COPY_PHASE_STRIP = NO; 420 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 421 | ENABLE_NS_ASSERTIONS = NO; 422 | ENABLE_STRICT_OBJC_MSGSEND = YES; 423 | GCC_C_LANGUAGE_STANDARD = gnu99; 424 | GCC_NO_COMMON_BLOCKS = YES; 425 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 426 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 427 | GCC_WARN_UNDECLARED_SELECTOR = YES; 428 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 429 | GCC_WARN_UNUSED_FUNCTION = YES; 430 | GCC_WARN_UNUSED_VARIABLE = YES; 431 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 432 | MTL_ENABLE_DEBUG_INFO = NO; 433 | SDKROOT = iphoneos; 434 | VALIDATE_PRODUCT = YES; 435 | }; 436 | name = Release; 437 | }; 438 | 225C16651C8ADF7A00040297 /* Debug */ = { 439 | isa = XCBuildConfiguration; 440 | buildSettings = { 441 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 442 | INFOPLIST_FILE = HooDatePickerDeomo/Info.plist; 443 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 444 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 445 | PRODUCT_BUNDLE_IDENTIFIER = jakciehoo.HooDatePickerDeomo; 446 | PRODUCT_NAME = "$(TARGET_NAME)"; 447 | }; 448 | name = Debug; 449 | }; 450 | 225C16661C8ADF7A00040297 /* Release */ = { 451 | isa = XCBuildConfiguration; 452 | buildSettings = { 453 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 454 | INFOPLIST_FILE = HooDatePickerDeomo/Info.plist; 455 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 456 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 457 | PRODUCT_BUNDLE_IDENTIFIER = jakciehoo.HooDatePickerDeomo; 458 | PRODUCT_NAME = "$(TARGET_NAME)"; 459 | }; 460 | name = Release; 461 | }; 462 | 225C16681C8ADF7A00040297 /* Debug */ = { 463 | isa = XCBuildConfiguration; 464 | buildSettings = { 465 | BUNDLE_LOADER = "$(TEST_HOST)"; 466 | INFOPLIST_FILE = HooDatePickerDeomoTests/Info.plist; 467 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 468 | PRODUCT_BUNDLE_IDENTIFIER = jakciehoo.HooDatePickerDeomoTests; 469 | PRODUCT_NAME = "$(TARGET_NAME)"; 470 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HooDatePickerDeomo.app/HooDatePickerDeomo"; 471 | }; 472 | name = Debug; 473 | }; 474 | 225C16691C8ADF7A00040297 /* Release */ = { 475 | isa = XCBuildConfiguration; 476 | buildSettings = { 477 | BUNDLE_LOADER = "$(TEST_HOST)"; 478 | INFOPLIST_FILE = HooDatePickerDeomoTests/Info.plist; 479 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 480 | PRODUCT_BUNDLE_IDENTIFIER = jakciehoo.HooDatePickerDeomoTests; 481 | PRODUCT_NAME = "$(TARGET_NAME)"; 482 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HooDatePickerDeomo.app/HooDatePickerDeomo"; 483 | }; 484 | name = Release; 485 | }; 486 | 225C166B1C8ADF7A00040297 /* Debug */ = { 487 | isa = XCBuildConfiguration; 488 | buildSettings = { 489 | INFOPLIST_FILE = HooDatePickerDeomoUITests/Info.plist; 490 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 491 | PRODUCT_BUNDLE_IDENTIFIER = jakciehoo.HooDatePickerDeomoUITests; 492 | PRODUCT_NAME = "$(TARGET_NAME)"; 493 | TEST_TARGET_NAME = HooDatePickerDeomo; 494 | USES_XCTRUNNER = YES; 495 | }; 496 | name = Debug; 497 | }; 498 | 225C166C1C8ADF7A00040297 /* Release */ = { 499 | isa = XCBuildConfiguration; 500 | buildSettings = { 501 | INFOPLIST_FILE = HooDatePickerDeomoUITests/Info.plist; 502 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 503 | PRODUCT_BUNDLE_IDENTIFIER = jakciehoo.HooDatePickerDeomoUITests; 504 | PRODUCT_NAME = "$(TARGET_NAME)"; 505 | TEST_TARGET_NAME = HooDatePickerDeomo; 506 | USES_XCTRUNNER = YES; 507 | }; 508 | name = Release; 509 | }; 510 | /* End XCBuildConfiguration section */ 511 | 512 | /* Begin XCConfigurationList section */ 513 | 225C16321C8ADF7A00040297 /* Build configuration list for PBXProject "HooDatePickerDeomo" */ = { 514 | isa = XCConfigurationList; 515 | buildConfigurations = ( 516 | 225C16621C8ADF7A00040297 /* Debug */, 517 | 225C16631C8ADF7A00040297 /* Release */, 518 | ); 519 | defaultConfigurationIsVisible = 0; 520 | defaultConfigurationName = Release; 521 | }; 522 | 225C16641C8ADF7A00040297 /* Build configuration list for PBXNativeTarget "HooDatePickerDeomo" */ = { 523 | isa = XCConfigurationList; 524 | buildConfigurations = ( 525 | 225C16651C8ADF7A00040297 /* Debug */, 526 | 225C16661C8ADF7A00040297 /* Release */, 527 | ); 528 | defaultConfigurationIsVisible = 0; 529 | defaultConfigurationName = Release; 530 | }; 531 | 225C16671C8ADF7A00040297 /* Build configuration list for PBXNativeTarget "HooDatePickerDeomoTests" */ = { 532 | isa = XCConfigurationList; 533 | buildConfigurations = ( 534 | 225C16681C8ADF7A00040297 /* Debug */, 535 | 225C16691C8ADF7A00040297 /* Release */, 536 | ); 537 | defaultConfigurationIsVisible = 0; 538 | defaultConfigurationName = Release; 539 | }; 540 | 225C166A1C8ADF7A00040297 /* Build configuration list for PBXNativeTarget "HooDatePickerDeomoUITests" */ = { 541 | isa = XCConfigurationList; 542 | buildConfigurations = ( 543 | 225C166B1C8ADF7A00040297 /* Debug */, 544 | 225C166C1C8ADF7A00040297 /* Release */, 545 | ); 546 | defaultConfigurationIsVisible = 0; 547 | defaultConfigurationName = Release; 548 | }; 549 | /* End XCConfigurationList section */ 550 | }; 551 | rootObject = 225C162F1C8ADF7A00040297 /* Project object */; 552 | } 553 | -------------------------------------------------------------------------------- /HooDatePickerDeomo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /HooDatePickerDeomo.xcodeproj/project.xcworkspace/xcuserdata/hoojackie.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakciehoo/HooDatePicker/cc739681ec46c20251e0573d8a5b4af3406d398b/HooDatePickerDeomo.xcodeproj/project.xcworkspace/xcuserdata/hoojackie.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /HooDatePickerDeomo.xcodeproj/xcuserdata/hoojackie.xcuserdatad/xcschemes/HooDatePickerDeomo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /HooDatePickerDeomo.xcodeproj/xcuserdata/hoojackie.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | HooDatePickerDeomo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 225C16361C8ADF7A00040297 16 | 17 | primary 18 | 19 | 20 | 225C164F1C8ADF7A00040297 21 | 22 | primary 23 | 24 | 25 | 225C165A1C8ADF7A00040297 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /HooDatePickerDeomo.xcodeproj/xcuserdata/hujh.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /HooDatePickerDeomo.xcodeproj/xcuserdata/hujh.xcuserdatad/xcschemes/HooDatePickerDeomo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /HooDatePickerDeomo.xcodeproj/xcuserdata/hujh.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | HooDatePickerDeomo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 225C16361C8ADF7A00040297 16 | 17 | primary 18 | 19 | 20 | 225C164F1C8ADF7A00040297 21 | 22 | primary 23 | 24 | 25 | 225C165A1C8ADF7A00040297 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /HooDatePickerDeomo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // HooDatePickerDeomo 4 | // 5 | // Created by hujianghua on 3/5/16. 6 | // Copyright © 2016 hujianghua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /HooDatePickerDeomo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // HooDatePickerDeomo 4 | // 5 | // Created by hujianghua on 3/5/16. 6 | // Copyright © 2016 hujianghua. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /HooDatePickerDeomo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /HooDatePickerDeomo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /HooDatePickerDeomo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 27 | 34 | 40 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /HooDatePickerDeomo/HooDatePicker/HooDatePicker.h: -------------------------------------------------------------------------------- 1 | // 2 | // HooDatePicker.h 3 | // HooDatePickerDeomo 4 | // 5 | // Created by hujianghua on 3/5/16. 6 | // Copyright © 2016 hujianghua. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "NSDate+HooDatePicker.h" 11 | 12 | typedef NS_ENUM(NSInteger,HooDatePickerMode) { 13 | HooDatePickerModeTime, // Displays hour, minute, and optionally AM/PM designation depending on the locale setting (e.g. 6 | 53 | PM) 14 | HooDatePickerModeDate, // Displays month, day, and year depending on the locale setting (e.g. November | 15 | 2007) 15 | HooDatePickerModeDateAndTime, // Displays date, hour, minute, and optionally AM/PM designation depending on the locale setting (e.g. Wed Nov 15 | 6 | 53 | PM) 16 | HooDatePickerModeYearAndMonth // Displays Year, Month, designation depending on the locale setting (e.g. November | 2007) 17 | }; 18 | 19 | @class HooDatePicker; 20 | 21 | @protocol HooDatePickerDelegate 22 | @optional 23 | - (void)datePicker:(HooDatePicker *)datePicker dateDidChange:(NSDate *)date; 24 | - (void)datePicker:(HooDatePicker *)datePicker didCancel:(UIButton *)sender; 25 | - (void)datePicker:(HooDatePicker *)dataPicker didSelectedDate:(NSDate *)date; 26 | @end 27 | 28 | @interface HooDatePicker : UIControl 29 | /** 30 | * Title on the top of HooDatePicker 31 | */ 32 | @property (nonatomic, copy) NSString *title; 33 | 34 | @property (nonatomic, strong) NSDate *date; 35 | /** 36 | * specify min/max date range. default is nil. When min > max, the values are ignored. 37 | */ 38 | @property (nonatomic, strong) NSDate *minimumDate; 39 | 40 | @property (nonatomic, strong) NSDate *maximumDate; 41 | /** 42 | * default is HooDatePickerModeDate. setting nil returns to default 43 | */ 44 | @property (nonatomic, assign) HooDatePickerMode datePickerMode; 45 | /** 46 | * default is [NSLocale currentLocale]. setting nil returns to default 47 | */ 48 | @property(nonatomic,strong) NSLocale *locale; 49 | /** 50 | * default is [NSCalendar currentCalendar]. setting nil returns to default 51 | */ 52 | @property(nonatomic,copy) NSCalendar *calendar; 53 | /** 54 | * default is nil. use current time zone or time zone from calendar 55 | */ 56 | @property(nonatomic,strong) NSTimeZone *timeZone; 57 | /** 58 | * read only property, indicate in datepicker is open. 59 | */ 60 | @property(nonatomic,readonly) BOOL isOpen; 61 | 62 | @property (nonatomic, weak) id delegate; 63 | 64 | - (instancetype)initWithSuperView:(UIView*)superView; 65 | 66 | - (instancetype)initDatePickerMode:(HooDatePickerMode)datePickerMode andAddToSuperView:(UIView *)superView; 67 | 68 | - (instancetype)initDatePickerMode:(HooDatePickerMode)datePickerMode minDate:(NSDate *)minimumDate maxMamDate:(NSDate *)maximumDate andAddToSuperView:(UIView *)superView; 69 | 70 | - (void)setDate:(NSDate *)date animated:(BOOL)animated; 71 | 72 | - (void)setTintColor:(UIColor *)tintColor; 73 | 74 | - (void)setHighlightColor:(UIColor *)highlightColor; 75 | 76 | - (void)show; 77 | 78 | - (void)dismiss; 79 | @end 80 | -------------------------------------------------------------------------------- /HooDatePickerDeomo/HooDatePicker/HooDatePicker.m: -------------------------------------------------------------------------------- 1 | // 2 | // HooDatePicker.m 3 | // HooDatePickerDeomo 4 | // 5 | // Created by hujianghua on 3/5/16. 6 | // Copyright © 2016 hujianghua. All rights reserved. 7 | // 8 | 9 | #import "HooDatePicker.h" 10 | 11 | // Constants : 12 | static NSString * const kSureButtonItemTitle = @"确定"; 13 | static NSString * const kCancelButtonItemTitle = @"取消"; 14 | 15 | // Constants sizes : 16 | static CGFloat const kHooDatePickerHeight = 260.0f; 17 | 18 | static CGFloat const kHooDatePickerHeaderHeight = 44.0f; 19 | 20 | static CGFloat const kHooDatePickerButtonHeaderWidth = 40.0f; 21 | 22 | static CGFloat const kHooDatePickerHeaderBottomMargin = 1.0f; 23 | 24 | static CGFloat const kHooDatePickerScrollViewDaysWidth = 90.0f; 25 | 26 | static CGFloat const kHooDatePickerScrollViewMonthWidth = 140.0f; 27 | 28 | static CGFloat const kHooDatePickerScrollViewDateWidth = 165.0f; 29 | 30 | static CGFloat const kHooDatePickerScrollViewLeftMargin = 1.0f; 31 | 32 | static CGFloat const kHooDatePickerScrollViewItemHeight = 45.0f; 33 | 34 | static CGFloat const kHooDatePickerLineWidth = 2.0f; 35 | 36 | static CGFloat const kHooDatePickerLineMargin = 15.0f; 37 | 38 | static CGFloat const kHooDatePickerPadding = 15.0f; 39 | 40 | // Constants times : 41 | static CGFloat const kHooDatePickerAnimationDuration = 0.4f; 42 | 43 | // Constants fonts 44 | #define kHooDatePickerTitleFont [UIFont systemFontOfSize:18.0] 45 | #define kHooDatePickerLabelFont [UIFont systemFontOfSize:18.0] 46 | #define kHooDatePickerLabelSelectedFont [UIFont systemFontOfSize:20.0]; 47 | 48 | // Constants colors : 49 | #define kHooDatePickerTintColor [UIColor colorWithRed:153.0/255.0 green:153.0/255.0 blue:153.0/255.0 alpha:1.0] 50 | #define kHooDatePickerHighlightColor [UIColor colorWithRed:255.0/255.0 green:180.0/255.0 blue:18.0/255.0 alpha:1.0] 51 | #define kHooDatePickerBackgroundColor [UIColor colorWithRed:244/255.0 green:242/255.0 blue:248/255.0 alpha:1.0] 52 | #define kHooDatePickerScrolViewBackgroundColor [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0] 53 | #define kHooDatePickerTitleFontColor kHooDatePickerTintColor 54 | #define kHooDatePickerFontColorLabel kHooDatePickerTintColor 55 | #define kHooDatePickerFontColorLabelSelected kHooDatePickerHighlightColor 56 | #define kHooDatePickerBackgroundColorLines kHooDatePickerHighlightColor 57 | 58 | typedef NS_ENUM(NSInteger,ScrollViewTagValue) { 59 | ScrollViewTagValue_DAYS = 1, 60 | ScrollViewTagValue_MONTHS = 2, 61 | ScrollViewTagValue_YEARS = 3, 62 | ScrollViewTagValue_HOURS = 4, 63 | ScrollViewTagValue_MINUTES = 5, 64 | ScrollViewTagValue_SECONDS = 6, 65 | ScrollViewTagValue_DATES = 7, 66 | 67 | }; 68 | 69 | @interface HooDatePicker () { 70 | // Lines : 71 | UIView *_lineDaysTop, *_lineDaysBottom, *_lineMonthsTop, *_lineMonthsBottom, *_lineYearsTop,*_lineYearsBottom, *_lineDatesTop, *_lineDatesBottom, *_lineHoursTop, *_lineHoursBottom, *_lineMinutesTop, *_lineMinutesBottom, *_lineSecondsTop, *_lineSecondsBottom; 72 | 73 | // Labels : 74 | NSMutableArray *_labelsDays, *_labelsMonths, *_labelsYears, *_labelsDates, *_labelsHours, *_labelsMinutes, *_labelsSeconds; 75 | 76 | // Date and time selected : 77 | NSInteger _selectedDay, _selectedMonth, _selectedYear, _selectedDate, _selectedHour, _selectedMinute, _selectedSecond; 78 | 79 | // First init flag : 80 | BOOL _isInitialized; 81 | NSInteger _minYear; 82 | 83 | } 84 | 85 | // Data of years, months, days, dates, hours, minutes, seconds 86 | @property (nonatomic, strong) NSMutableArray *years, *months, *days, *dates, *hours, *minutes, *seconds; 87 | 88 | // ScrollView for Years, Months, days ,Dates ,Hours ,Minute ,Seconds 89 | @property (nonatomic, strong) UIScrollView *scrollViewYears, *scrollViewMonths, *scrollViewDays, *scrollViewDates, *scrollViewHours, *scrollViewMinutes,*scrollViewSeconds; 90 | 91 | @property (nonatomic, weak) UIView *superView; 92 | 93 | @property (nonatomic, copy) UIView *dimBackgroundView; 94 | 95 | @property (nonatomic, strong) UILabel *titleLabel; 96 | 97 | @property (nonatomic, strong) UIView *headerView; 98 | 99 | @property (nonatomic, strong) UIColor *tintColor; 100 | 101 | @property (nonatomic, strong) UIColor *highlightColor; 102 | 103 | @property (nonatomic, strong) NSDateFormatter *dateFormatter; 104 | 105 | @end 106 | 107 | @implementation HooDatePicker 108 | 109 | 110 | #pragma mark - Initializers 111 | 112 | - (instancetype)initWithSuperView:(UIView*)superView { 113 | 114 | 115 | if (self = [super initWithFrame:CGRectMake(0.0, superView.frame.size.height, superView.frame.size.width, kHooDatePickerHeight)]) { 116 | _datePickerMode = HooDatePickerModeDate; 117 | [superView addSubview:self]; 118 | _superView = superView; 119 | _minYear = 1900; 120 | self.tintColor = kHooDatePickerTintColor; 121 | self.highlightColor = kHooDatePickerHighlightColor; 122 | [self addSubview:self.headerView]; 123 | [self setupControl]; 124 | } 125 | return self; 126 | } 127 | 128 | - (instancetype)initDatePickerMode:(HooDatePickerMode)datePickerMode andAddToSuperView:(UIView *)superView { 129 | if (self = [super initWithFrame:CGRectMake(0.0, superView.frame.size.height, superView.frame.size.width, kHooDatePickerHeight)]) { 130 | _datePickerMode = datePickerMode; 131 | [superView addSubview:self]; 132 | _superView = superView; 133 | _minYear = 1900; 134 | self.tintColor = kHooDatePickerTintColor; 135 | self.highlightColor = kHooDatePickerHighlightColor; 136 | [self addSubview:self.headerView]; 137 | [self setupControl]; 138 | } 139 | return self; 140 | } 141 | 142 | - (instancetype)initDatePickerMode:(HooDatePickerMode)datePickerMode minDate:(NSDate *)minimumDate maxMamDate:(NSDate *)maximumDate andAddToSuperView:(UIView *)superView { 143 | if (self = [super initWithFrame:CGRectMake(0.0, superView.frame.size.height, superView.frame.size.width, kHooDatePickerHeight)]) { 144 | _datePickerMode = datePickerMode; 145 | [superView addSubview:self]; 146 | _superView = superView; 147 | _minYear = 1900; 148 | if (maximumDate) { 149 | _maximumDate = maximumDate; 150 | } 151 | if (minimumDate) { 152 | _minimumDate = minimumDate; 153 | 154 | NSDateComponents* componentsMin = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:_minimumDate]; 155 | NSInteger yearMin = [componentsMin year]; 156 | _minYear = yearMin; 157 | } 158 | self.tintColor = kHooDatePickerTintColor; 159 | self.highlightColor = kHooDatePickerHighlightColor; 160 | [self addSubview:self.headerView]; 161 | [self setupControl]; 162 | } 163 | return self; 164 | } 165 | 166 | - (void)setupControl { 167 | 168 | // Set parent View : 169 | self.hidden = YES; 170 | 171 | // Clear old selectors 172 | [self removeSelectorYears]; 173 | [self removeSelectorMonths]; 174 | [self removeSelectorDays]; 175 | [self removeSelectorHours]; 176 | [self removeSelectorMinutes]; 177 | [self removeSelectorSeconds]; 178 | 179 | // Generate collections days, months, years, hours, minutes and seconds : 180 | _years = [self getYears]; 181 | _days = [self getDaysInMonth:[NSDate date]]; 182 | if (self.datePickerMode == HooDatePickerModeDateAndTime) { 183 | _dates = [self getDates]; 184 | } 185 | 186 | // Background : 187 | self.backgroundColor = kHooDatePickerBackgroundColor; 188 | 189 | // Date Selectors : 190 | if (self.datePickerMode == HooDatePickerModeDate) { 191 | [self buildSelectorYearsOffsetX:0.0 andWidth:kHooDatePickerScrollViewMonthWidth]; 192 | [self buildSelectorMonthsOffsetX:(_scrollViewYears.frame.size.width + kHooDatePickerScrollViewLeftMargin) andWidth:kHooDatePickerScrollViewDaysWidth]; 193 | [self buildSelectorDaysOffsetX:(_scrollViewMonths.frame.origin.x + _scrollViewMonths.frame.size.width + kHooDatePickerScrollViewLeftMargin) andWidth:(self.frame.size.width - (_scrollViewMonths.frame.origin.x + _scrollViewMonths.frame.size.width + kHooDatePickerScrollViewLeftMargin))]; 194 | } 195 | 196 | // Time Selectors : 197 | if (self.datePickerMode == HooDatePickerModeTime) { 198 | [self buildSelectorHoursOffsetX:0.0 andWidth:((self.frame.size.width / 3.0) - kHooDatePickerScrollViewLeftMargin)]; 199 | [self buildSelectorMinutesOffsetX:(self.frame.size.width / 3.0) andWidth:((self.frame.size.width / 3.0) - kHooDatePickerScrollViewLeftMargin)]; 200 | [self buildSelectorSecondsOffsetX:((self.frame.size.width / 3.0) * 2.0) andWidth:(self.frame.size.width / 3.0)]; 201 | } 202 | 203 | // Date & Time Selectors : 204 | if (self.datePickerMode == HooDatePickerModeDateAndTime) { 205 | [self buildSelectorDatesOffsetX:0.0 andWidth:kHooDatePickerScrollViewDateWidth]; 206 | [self buildSelectorHoursOffsetX:(kHooDatePickerScrollViewDateWidth + kHooDatePickerScrollViewLeftMargin) andWidth:(((self.frame.size.width - kHooDatePickerScrollViewDateWidth) / 2.0) - kHooDatePickerScrollViewLeftMargin)]; 207 | [self buildSelectorMinutesOffsetX:(kHooDatePickerScrollViewDateWidth + kHooDatePickerScrollViewLeftMargin + ((self.frame.size.width - kHooDatePickerScrollViewDateWidth) / 2.0)) andWidth:(((self.frame.size.width - kHooDatePickerScrollViewDateWidth) / 2.0) - kHooDatePickerScrollViewLeftMargin)]; 208 | } 209 | 210 | if (self.datePickerMode == HooDatePickerModeYearAndMonth) { 211 | [self buildSelectorYearsOffsetX:0.0 andWidth:self.frame.size.width * 0.5]; 212 | [self buildSelectorMonthsOffsetX:(_scrollViewYears.frame.size.width + kHooDatePickerScrollViewLeftMargin) andWidth:self.frame.size.width * 0.5]; 213 | 214 | } 215 | 216 | // Defaut Date selected : 217 | [self setDate:[NSDate date] animated:NO]; 218 | } 219 | 220 | 221 | #pragma mark - Build Selector Days 222 | 223 | - (void)buildSelectorDaysOffsetX:(CGFloat)x andWidth:(CGFloat)width { 224 | 225 | // ScrollView Days : 226 | _scrollViewDays = [[UIScrollView alloc] initWithFrame:CGRectMake(x, kHooDatePickerHeaderHeight + kHooDatePickerHeaderBottomMargin, width, self.frame.size.height - kHooDatePickerHeaderHeight - kHooDatePickerHeaderBottomMargin)]; 227 | _scrollViewDays.tag = ScrollViewTagValue_DAYS; 228 | _scrollViewDays.delegate = self; 229 | _scrollViewDays.backgroundColor = kHooDatePickerScrolViewBackgroundColor; 230 | _scrollViewDays.showsHorizontalScrollIndicator = NO; 231 | _scrollViewDays.showsVerticalScrollIndicator = NO; 232 | [self addSubview:_scrollViewDays]; 233 | 234 | _lineDaysTop = [[UIView alloc] initWithFrame:CGRectMake(_scrollViewDays.frame.origin.x + kHooDatePickerLineMargin, _scrollViewDays.frame.origin.y + (_scrollViewDays.frame.size.height / 2) - (kHooDatePickerScrollViewItemHeight / 2), width - (2 * kHooDatePickerLineMargin), kHooDatePickerLineWidth)]; 235 | _lineDaysTop.backgroundColor = self.highlightColor; 236 | [self addSubview:_lineDaysTop]; 237 | 238 | _lineDaysBottom = [[UIView alloc] initWithFrame:CGRectMake(_scrollViewDays.frame.origin.x + kHooDatePickerLineMargin, _scrollViewDays.frame.origin.y + (_scrollViewDays.frame.size.height / 2) + (kHooDatePickerScrollViewItemHeight / 2), width - (2 * kHooDatePickerLineMargin), kHooDatePickerLineWidth)]; 239 | _lineDaysBottom.backgroundColor = self.highlightColor; 240 | [self addSubview:_lineDaysBottom]; 241 | 242 | // Update ScrollView Data 243 | [self buildSelectorLabelsDays]; 244 | 245 | UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGestureDaysCaptured:)]; 246 | singleTap.numberOfTapsRequired = 1; 247 | singleTap.numberOfTouchesRequired = 1; 248 | [_scrollViewDays addGestureRecognizer:singleTap]; 249 | } 250 | 251 | - (void)buildSelectorLabelsDays { 252 | 253 | CGFloat offsetContentScrollView = (_scrollViewYears.frame.size.height - kHooDatePickerScrollViewItemHeight) / 2.0; 254 | 255 | if (_labelsDays && _labelsDays.count > 0) { 256 | for (UILabel *label in _labelsDays) { 257 | [label removeFromSuperview]; 258 | } 259 | } 260 | 261 | _labelsDays = [[NSMutableArray alloc] init]; 262 | 263 | for (int i = 0; i < _days.count; i++) { 264 | 265 | NSString *day = (NSString*)[_days objectAtIndex:i]; 266 | 267 | UILabel *labelDay = [[UILabel alloc] initWithFrame:CGRectMake(0, (i * kHooDatePickerScrollViewItemHeight) + offsetContentScrollView, _scrollViewDays.frame.size.width, kHooDatePickerScrollViewItemHeight)]; 268 | labelDay.text = day; 269 | labelDay.font = kHooDatePickerLabelFont; 270 | labelDay.textAlignment = NSTextAlignmentCenter; 271 | labelDay.textColor = self.tintColor; 272 | labelDay.backgroundColor = [UIColor clearColor]; 273 | 274 | [_labelsDays addObject:labelDay]; 275 | [_scrollViewDays addSubview:labelDay]; 276 | } 277 | 278 | _scrollViewDays.contentSize = CGSizeMake(_scrollViewDays.frame.size.width, (kHooDatePickerScrollViewItemHeight * _days.count) + (offsetContentScrollView * 2)); 279 | } 280 | 281 | - (void)removeSelectorDays { 282 | 283 | if (_scrollViewDays) { 284 | [_scrollViewDays removeFromSuperview]; 285 | _scrollViewDays = nil; 286 | } 287 | if (_lineDaysTop) { 288 | [_lineDaysTop removeFromSuperview]; 289 | _lineDaysTop = nil; 290 | } 291 | if (_lineDaysBottom) { 292 | [_lineDaysBottom removeFromSuperview]; 293 | _lineDaysBottom = nil; 294 | } 295 | } 296 | 297 | #pragma mark - Build Selector Months 298 | 299 | - (void)buildSelectorMonthsOffsetX:(CGFloat)x andWidth:(CGFloat)width { 300 | 301 | // ScrollView Months 302 | 303 | _scrollViewMonths = [[UIScrollView alloc] initWithFrame:CGRectMake(x, kHooDatePickerHeaderHeight + kHooDatePickerHeaderBottomMargin, width, self.frame.size.height - kHooDatePickerHeaderHeight - kHooDatePickerHeaderBottomMargin)]; 304 | _scrollViewMonths.tag = ScrollViewTagValue_MONTHS; 305 | _scrollViewMonths.delegate = self; 306 | _scrollViewMonths.backgroundColor = kHooDatePickerScrolViewBackgroundColor; 307 | _scrollViewMonths.showsHorizontalScrollIndicator = NO; 308 | _scrollViewMonths.showsVerticalScrollIndicator = NO; 309 | [self addSubview:_scrollViewMonths]; 310 | 311 | _lineMonthsTop = [[UIView alloc] initWithFrame:CGRectMake(_scrollViewMonths.frame.origin.x + kHooDatePickerLineMargin, _scrollViewMonths.frame.origin.y + (_scrollViewMonths.frame.size.height / 2) - (kHooDatePickerScrollViewItemHeight / 2), width - (2 * kHooDatePickerLineMargin), kHooDatePickerLineWidth)]; 312 | _lineMonthsTop.backgroundColor = self.highlightColor; 313 | [self addSubview:_lineMonthsTop]; 314 | 315 | _lineMonthsBottom = [[UIView alloc] initWithFrame:CGRectMake(_scrollViewMonths.frame.origin.x + kHooDatePickerLineMargin, _scrollViewMonths.frame.origin.y + (_scrollViewMonths.frame.size.height / 2) + (kHooDatePickerScrollViewItemHeight / 2), width - (2 * kHooDatePickerLineMargin), kHooDatePickerLineWidth)]; 316 | _lineMonthsBottom.backgroundColor = self.highlightColor; 317 | [self addSubview:_lineMonthsBottom]; 318 | 319 | 320 | // Update ScrollView Data 321 | [self buildSelectorLabelsMonths]; 322 | 323 | UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGestureMonthsCaptured:)]; 324 | singleTap.numberOfTapsRequired = 1; 325 | singleTap.numberOfTouchesRequired = 1; 326 | [_scrollViewMonths addGestureRecognizer:singleTap]; 327 | } 328 | 329 | - (void)buildSelectorLabelsMonths { 330 | 331 | CGFloat offsetContentScrollView = (_scrollViewYears.frame.size.height - kHooDatePickerScrollViewItemHeight) / 2.0; 332 | 333 | if (_labelsMonths && _labelsMonths.count > 0) { 334 | for (UILabel *label in _labelsMonths) { 335 | [label removeFromSuperview]; 336 | } 337 | } 338 | 339 | _labelsMonths = [[NSMutableArray alloc] init]; 340 | 341 | for (int i = 0; i < self.months.count; i++) { 342 | 343 | NSString *day = (NSString*)[self.months objectAtIndex:i]; 344 | 345 | UILabel *labelDay = [[UILabel alloc] initWithFrame:CGRectMake(0.0, (i * kHooDatePickerScrollViewItemHeight) + offsetContentScrollView, _scrollViewMonths.frame.size.width, kHooDatePickerScrollViewItemHeight)]; 346 | labelDay.text = day; 347 | labelDay.font = kHooDatePickerLabelFont; 348 | labelDay.textAlignment = NSTextAlignmentCenter; 349 | labelDay.textColor = self.tintColor; 350 | labelDay.backgroundColor = [UIColor clearColor]; 351 | 352 | [_labelsMonths addObject:labelDay]; 353 | [_scrollViewMonths addSubview:labelDay]; 354 | } 355 | 356 | _scrollViewMonths.contentSize = CGSizeMake(_scrollViewMonths.frame.size.width, (kHooDatePickerScrollViewItemHeight * self.months.count) + (offsetContentScrollView * 2)); 357 | } 358 | 359 | - (void)removeSelectorMonths { 360 | 361 | if (_scrollViewMonths) { 362 | [_scrollViewMonths removeFromSuperview]; 363 | _scrollViewMonths = nil; 364 | } 365 | if (_lineMonthsTop) { 366 | [_lineMonthsTop removeFromSuperview]; 367 | _lineMonthsTop = nil; 368 | } 369 | if (_lineMonthsBottom) { 370 | [_lineMonthsBottom removeFromSuperview]; 371 | _lineMonthsBottom = nil; 372 | } 373 | } 374 | 375 | #pragma mark - Build Selector Years 376 | 377 | - (void)buildSelectorYearsOffsetX:(CGFloat)x andWidth:(CGFloat)width { 378 | 379 | // ScrollView Years 380 | 381 | _scrollViewYears = [[UIScrollView alloc] initWithFrame:CGRectMake(x, kHooDatePickerHeaderHeight + kHooDatePickerHeaderBottomMargin, width, self.frame.size.height - kHooDatePickerHeaderHeight - kHooDatePickerHeaderBottomMargin)]; 382 | _scrollViewYears.tag = ScrollViewTagValue_YEARS; 383 | _scrollViewYears.delegate = self; 384 | _scrollViewYears.backgroundColor = kHooDatePickerScrolViewBackgroundColor; 385 | _scrollViewYears.showsHorizontalScrollIndicator = NO; 386 | _scrollViewYears.showsVerticalScrollIndicator = NO; 387 | [self addSubview:_scrollViewYears]; 388 | 389 | _lineYearsTop = [[UIView alloc] initWithFrame:CGRectMake(_scrollViewYears.frame.origin.x + kHooDatePickerLineMargin, _scrollViewYears.frame.origin.y + (_scrollViewYears.frame.size.height / 2) - (kHooDatePickerScrollViewItemHeight / 2), width - (2 * kHooDatePickerLineMargin), kHooDatePickerLineWidth)]; 390 | _lineYearsTop.backgroundColor = self.highlightColor; 391 | [self addSubview:_lineYearsTop]; 392 | 393 | _lineYearsBottom = [[UIView alloc] initWithFrame:CGRectMake(_scrollViewYears.frame.origin.x + kHooDatePickerLineMargin, _scrollViewYears.frame.origin.y + (_scrollViewYears.frame.size.height / 2) + (kHooDatePickerScrollViewItemHeight / 2), width - (2 * kHooDatePickerLineMargin), kHooDatePickerLineWidth)]; 394 | _lineYearsBottom.backgroundColor = self.highlightColor; 395 | [self addSubview:_lineYearsBottom]; 396 | 397 | // Update ScrollView Data 398 | [self buildSelectorLabelsYears]; 399 | 400 | UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGestureYearsCaptured:)]; 401 | singleTap.numberOfTapsRequired = 1; 402 | singleTap.numberOfTouchesRequired = 1; 403 | [_scrollViewYears addGestureRecognizer:singleTap]; 404 | } 405 | 406 | - (void)buildSelectorLabelsYears { 407 | 408 | CGFloat offsetContentScrollView = (_scrollViewYears.frame.size.height - kHooDatePickerScrollViewItemHeight) / 2.0; 409 | 410 | if (_labelsYears && _labelsYears.count > 0) { 411 | for (UILabel *label in _labelsYears) { 412 | [label removeFromSuperview]; 413 | } 414 | } 415 | 416 | _labelsYears = [[NSMutableArray alloc] init]; 417 | 418 | for (int i = 0; i < _years.count; i++) { 419 | 420 | NSString *day = (NSString*)[_years objectAtIndex:i]; 421 | 422 | UILabel *labelDay = [[UILabel alloc] initWithFrame:CGRectMake(0.0, (i * kHooDatePickerScrollViewItemHeight) + offsetContentScrollView, _scrollViewYears.frame.size.width, kHooDatePickerScrollViewItemHeight)]; 423 | labelDay.text = day; 424 | labelDay.font = kHooDatePickerLabelFont; 425 | labelDay.textAlignment = NSTextAlignmentCenter; 426 | labelDay.textColor = self.tintColor; 427 | labelDay.backgroundColor = [UIColor clearColor]; 428 | 429 | [_labelsYears addObject:labelDay]; 430 | [_scrollViewYears addSubview:labelDay]; 431 | } 432 | 433 | _scrollViewYears.contentSize = CGSizeMake(_scrollViewYears.frame.size.width, (kHooDatePickerScrollViewItemHeight * _years.count) + (offsetContentScrollView * 2)); 434 | } 435 | 436 | - (void)removeSelectorYears { 437 | 438 | if (_scrollViewYears) { 439 | [_scrollViewYears removeFromSuperview]; 440 | _scrollViewYears = nil; 441 | } 442 | if (_lineYearsTop) { 443 | [_lineYearsTop removeFromSuperview]; 444 | _lineYearsTop = nil; 445 | } 446 | if (_lineYearsBottom) { 447 | [_lineYearsBottom removeFromSuperview]; 448 | _lineYearsBottom = nil; 449 | } 450 | } 451 | 452 | #pragma mark - Build Selector Dates 453 | 454 | - (void)buildSelectorDatesOffsetX:(CGFloat)x andWidth:(CGFloat)width { 455 | 456 | // ScrollView Dates 457 | _scrollViewDates = [[UIScrollView alloc] initWithFrame:CGRectMake(x, kHooDatePickerHeaderHeight + kHooDatePickerHeaderBottomMargin, width, self.frame.size.height - kHooDatePickerHeaderHeight - kHooDatePickerHeaderBottomMargin)]; 458 | _scrollViewDates.tag = ScrollViewTagValue_DATES; 459 | _scrollViewDates.delegate = self; 460 | _scrollViewDates.backgroundColor = kHooDatePickerScrolViewBackgroundColor; 461 | _scrollViewDates.showsHorizontalScrollIndicator = NO; 462 | _scrollViewDates.showsVerticalScrollIndicator = NO; 463 | [self addSubview:_scrollViewDates]; 464 | 465 | _lineDatesTop = [[UIView alloc] initWithFrame:CGRectMake(_scrollViewDates.frame.origin.x + kHooDatePickerLineMargin, _scrollViewDates.frame.origin.y + (_scrollViewDates.frame.size.height / 2) - (kHooDatePickerScrollViewItemHeight / 2), width - (2 * kHooDatePickerLineMargin), kHooDatePickerLineWidth)]; 466 | _lineDatesTop.backgroundColor = self.highlightColor; 467 | [self addSubview:_lineDatesTop]; 468 | 469 | _lineDatesBottom = [[UIView alloc] initWithFrame:CGRectMake(_scrollViewDates.frame.origin.x + kHooDatePickerLineMargin, _scrollViewDates.frame.origin.y + (_scrollViewDates.frame.size.height / 2) + (kHooDatePickerScrollViewItemHeight / 2), width - (2 * kHooDatePickerLineMargin), kHooDatePickerLineWidth)]; 470 | _lineDatesBottom.backgroundColor = self.highlightColor; 471 | [self addSubview:_lineDatesBottom]; 472 | 473 | // Update ScrollView Data 474 | [self buildSelectorLabelsDates]; 475 | 476 | UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGestureDatesCaptured:)]; 477 | singleTap.numberOfTapsRequired = 1; 478 | singleTap.numberOfTouchesRequired = 1; 479 | [_scrollViewDates addGestureRecognizer:singleTap]; 480 | } 481 | 482 | - (void)buildSelectorLabelsDates { 483 | 484 | CGFloat offsetContentScrollView = (_scrollViewDates.frame.size.height - kHooDatePickerScrollViewItemHeight) / 2.0; 485 | 486 | if (_labelsDates && _labelsDates.count > 0) { 487 | for (UILabel *label in _labelsDates) { 488 | [label removeFromSuperview]; 489 | } 490 | } 491 | 492 | _labelsDates = [[NSMutableArray alloc] init]; 493 | 494 | NSDateFormatter *dateFormatter = self.dateFormatter; 495 | [dateFormatter setCalendar:self.calendar]; 496 | [dateFormatter setTimeZone:self.timeZone]; 497 | [dateFormatter setDateFormat:[NSString stringWithFormat:@"MMMdd%@ EEE", @"日"]]; 498 | 499 | for (int i = 0; i < _dates.count; i++) { 500 | 501 | NSDate *date = [_dates objectAtIndex:i]; 502 | 503 | NSString *hour = [dateFormatter stringFromDate:date]; 504 | 505 | UILabel *labelDate = [[UILabel alloc] initWithFrame:CGRectMake(0, (i * kHooDatePickerScrollViewItemHeight) + offsetContentScrollView, _scrollViewDates.frame.size.width, kHooDatePickerScrollViewItemHeight)]; 506 | labelDate.text = hour; 507 | labelDate.font = kHooDatePickerLabelFont; 508 | labelDate.textAlignment = NSTextAlignmentCenter; 509 | labelDate.textColor = self.tintColor; 510 | labelDate.backgroundColor = [UIColor clearColor]; 511 | 512 | [_labelsDates addObject:labelDate]; 513 | [_scrollViewDates addSubview:labelDate]; 514 | } 515 | 516 | _scrollViewDates.contentSize = CGSizeMake(_scrollViewDates.frame.size.width, (kHooDatePickerScrollViewItemHeight * _dates.count) + (offsetContentScrollView * 2)); 517 | } 518 | 519 | - (void)removeSelectorDates { 520 | 521 | if (_scrollViewDates) { 522 | [_scrollViewDates removeFromSuperview]; 523 | _scrollViewDates = nil; 524 | } 525 | if (_lineDatesTop) { 526 | [_lineDatesTop removeFromSuperview]; 527 | _lineDatesTop = nil; 528 | } 529 | if (_lineDatesBottom) { 530 | [_lineDatesBottom removeFromSuperview]; 531 | _lineDatesBottom = nil; 532 | } 533 | } 534 | 535 | #pragma mark - Build Selector Hours 536 | 537 | - (void)buildSelectorHoursOffsetX:(CGFloat)x andWidth:(CGFloat)width { 538 | 539 | // ScrollView Hours : 540 | _scrollViewHours = [[UIScrollView alloc] initWithFrame:CGRectMake(x, kHooDatePickerHeaderHeight + kHooDatePickerHeaderBottomMargin, width, self.frame.size.height - kHooDatePickerHeaderHeight - kHooDatePickerHeaderBottomMargin)]; 541 | _scrollViewHours.tag = ScrollViewTagValue_HOURS; 542 | _scrollViewHours.delegate = self; 543 | _scrollViewHours.backgroundColor = kHooDatePickerScrolViewBackgroundColor; 544 | _scrollViewHours.showsHorizontalScrollIndicator = NO; 545 | _scrollViewHours.showsVerticalScrollIndicator = NO; 546 | [self addSubview:_scrollViewHours]; 547 | 548 | _lineHoursTop = [[UIView alloc] initWithFrame:CGRectMake(_scrollViewHours.frame.origin.x + kHooDatePickerLineMargin, _scrollViewHours.frame.origin.y + (_scrollViewHours.frame.size.height / 2) - (kHooDatePickerScrollViewItemHeight / 2), width - (2 * kHooDatePickerLineMargin), kHooDatePickerLineWidth)]; 549 | _lineHoursTop.backgroundColor = self.highlightColor; 550 | [self addSubview:_lineHoursTop]; 551 | 552 | _lineHoursBottom = [[UIView alloc] initWithFrame:CGRectMake(_scrollViewHours.frame.origin.x + kHooDatePickerLineMargin, _scrollViewHours.frame.origin.y + (_scrollViewHours.frame.size.height / 2) + (kHooDatePickerScrollViewItemHeight / 2), width - (2 * kHooDatePickerLineMargin), kHooDatePickerLineWidth)]; 553 | _lineHoursBottom.backgroundColor = self.highlightColor; 554 | [self addSubview:_lineHoursBottom]; 555 | 556 | // Update ScrollView Data 557 | [self buildSelectorLabelsHours]; 558 | 559 | UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGestureHoursCaptured:)]; 560 | singleTap.numberOfTapsRequired = 1; 561 | singleTap.numberOfTouchesRequired = 1; 562 | [_scrollViewHours addGestureRecognizer:singleTap]; 563 | } 564 | 565 | - (void)buildSelectorLabelsHours { 566 | 567 | CGFloat offsetContentScrollView = (_scrollViewHours.frame.size.height - kHooDatePickerScrollViewItemHeight) / 2.0; 568 | 569 | if (_labelsHours && _labelsHours.count > 0) { 570 | for (UILabel *label in _labelsHours) { 571 | [label removeFromSuperview]; 572 | } 573 | } 574 | 575 | _labelsHours = [[NSMutableArray alloc] init]; 576 | 577 | for (int i = 0; i < self.hours.count; i++) { 578 | 579 | NSString *hour = (NSString*)[self.hours objectAtIndex:i]; 580 | 581 | UILabel *labelHour = [[UILabel alloc] initWithFrame:CGRectMake(0, (i * kHooDatePickerScrollViewItemHeight) + offsetContentScrollView, _scrollViewHours.frame.size.width, kHooDatePickerScrollViewItemHeight)]; 582 | labelHour.text = hour; 583 | labelHour.font = kHooDatePickerLabelFont; 584 | labelHour.textAlignment = NSTextAlignmentCenter; 585 | labelHour.textColor = self.tintColor; 586 | labelHour.backgroundColor = [UIColor clearColor]; 587 | 588 | [_labelsHours addObject:labelHour]; 589 | [_scrollViewHours addSubview:labelHour]; 590 | } 591 | 592 | _scrollViewHours.contentSize = CGSizeMake(_scrollViewHours.frame.size.width, (kHooDatePickerScrollViewItemHeight * self.hours.count) + (offsetContentScrollView * 2)); 593 | } 594 | 595 | - (void)removeSelectorHours { 596 | 597 | if (_scrollViewHours) { 598 | [_scrollViewHours removeFromSuperview]; 599 | _scrollViewHours = nil; 600 | } 601 | if (_lineHoursTop) { 602 | [_lineHoursTop removeFromSuperview]; 603 | _lineHoursTop = nil; 604 | } 605 | if (_lineHoursBottom) { 606 | [_lineHoursBottom removeFromSuperview]; 607 | _lineHoursBottom = nil; 608 | } 609 | } 610 | 611 | #pragma mark - Build Selector Minutes 612 | 613 | - (void)buildSelectorMinutesOffsetX:(CGFloat)x andWidth:(CGFloat)width { 614 | 615 | // ScrollView Minutes : 616 | _scrollViewMinutes = [[UIScrollView alloc] initWithFrame:CGRectMake(x, kHooDatePickerHeaderHeight + kHooDatePickerHeaderBottomMargin, width, self.frame.size.height - kHooDatePickerHeaderHeight - kHooDatePickerHeaderBottomMargin)]; 617 | _scrollViewMinutes.tag = ScrollViewTagValue_MINUTES; 618 | _scrollViewMinutes.delegate = self; 619 | _scrollViewMinutes.backgroundColor = kHooDatePickerScrolViewBackgroundColor; 620 | _scrollViewMinutes.showsHorizontalScrollIndicator = NO; 621 | _scrollViewMinutes.showsVerticalScrollIndicator = NO; 622 | [self addSubview:_scrollViewMinutes]; 623 | 624 | _lineMinutesTop = [[UIView alloc] initWithFrame:CGRectMake(_scrollViewMinutes.frame.origin.x + kHooDatePickerLineMargin, _scrollViewMinutes.frame.origin.y + (_scrollViewMinutes.frame.size.height / 2) - (kHooDatePickerScrollViewItemHeight / 2), width - (2 * kHooDatePickerLineMargin), kHooDatePickerLineWidth)]; 625 | _lineMinutesTop.backgroundColor = self.highlightColor; 626 | [self addSubview:_lineMinutesTop]; 627 | 628 | _lineMinutesBottom = [[UIView alloc] initWithFrame:CGRectMake(_scrollViewMinutes.frame.origin.x + kHooDatePickerLineMargin, _scrollViewMinutes.frame.origin.y + (_scrollViewMinutes.frame.size.height / 2) + (kHooDatePickerScrollViewItemHeight / 2), width - (2 * kHooDatePickerLineMargin), kHooDatePickerLineWidth)]; 629 | _lineMinutesBottom.backgroundColor = self.highlightColor; 630 | [self addSubview:_lineMinutesBottom]; 631 | 632 | // Update ScrollView Data 633 | [self buildSelectorLabelsMinutes]; 634 | 635 | UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGestureMinutesCaptured:)]; 636 | singleTap.numberOfTapsRequired = 1; 637 | singleTap.numberOfTouchesRequired = 1; 638 | [_scrollViewMinutes addGestureRecognizer:singleTap]; 639 | } 640 | 641 | - (void)buildSelectorLabelsMinutes { 642 | 643 | CGFloat offsetContentScrollView = (_scrollViewMinutes.frame.size.height - kHooDatePickerScrollViewItemHeight) / 2.0; 644 | 645 | if (_labelsMinutes && _labelsMinutes.count > 0) { 646 | for (UILabel *label in _labelsMinutes) { 647 | [label removeFromSuperview]; 648 | } 649 | } 650 | 651 | _labelsMinutes = [[NSMutableArray alloc] init]; 652 | 653 | for (int i = 0; i < self.minutes.count; i++) { 654 | 655 | NSString *minute = (NSString*)[self.minutes objectAtIndex:i]; 656 | 657 | UILabel *labelMinute = [[UILabel alloc] initWithFrame:CGRectMake(0, (i * kHooDatePickerScrollViewItemHeight) + offsetContentScrollView, _scrollViewMinutes.frame.size.width, kHooDatePickerScrollViewItemHeight)]; 658 | labelMinute.text = minute; 659 | labelMinute.font = kHooDatePickerLabelFont; 660 | labelMinute.textAlignment = NSTextAlignmentCenter; 661 | labelMinute.textColor = self.tintColor; 662 | labelMinute.backgroundColor = [UIColor clearColor]; 663 | 664 | [_labelsMinutes addObject:labelMinute]; 665 | [_scrollViewMinutes addSubview:labelMinute]; 666 | } 667 | 668 | _scrollViewMinutes.contentSize = CGSizeMake(_scrollViewMinutes.frame.size.width, (kHooDatePickerScrollViewItemHeight * self.minutes.count) + (offsetContentScrollView * 2)); 669 | } 670 | 671 | - (void)removeSelectorMinutes { 672 | 673 | if (_scrollViewMinutes) { 674 | [_scrollViewMinutes removeFromSuperview]; 675 | _scrollViewMinutes = nil; 676 | } 677 | if (_lineMinutesTop) { 678 | [_lineMinutesTop removeFromSuperview]; 679 | _lineMinutesTop = nil; 680 | } 681 | if (_lineMinutesBottom) { 682 | [_lineMinutesBottom removeFromSuperview]; 683 | _lineMinutesBottom = nil; 684 | } 685 | } 686 | 687 | #pragma mark - Build Selector Seconds 688 | 689 | - (void)buildSelectorSecondsOffsetX:(CGFloat)x andWidth:(CGFloat)width { 690 | 691 | // ScrollView Seconds : 692 | _scrollViewSeconds = [[UIScrollView alloc] initWithFrame:CGRectMake(x, kHooDatePickerHeaderHeight + kHooDatePickerHeaderBottomMargin, width, self.frame.size.height - kHooDatePickerHeaderHeight - kHooDatePickerHeaderBottomMargin)]; 693 | _scrollViewSeconds.tag = ScrollViewTagValue_SECONDS; 694 | _scrollViewSeconds.delegate = self; 695 | _scrollViewSeconds.backgroundColor = kHooDatePickerScrolViewBackgroundColor; 696 | _scrollViewSeconds.showsHorizontalScrollIndicator = NO; 697 | _scrollViewSeconds.showsVerticalScrollIndicator = NO; 698 | [self addSubview:_scrollViewSeconds]; 699 | 700 | _lineSecondsTop = [[UIView alloc] initWithFrame:CGRectMake(_scrollViewSeconds.frame.origin.x + kHooDatePickerLineMargin, _scrollViewSeconds.frame.origin.y + (_scrollViewSeconds.frame.size.height / 2) - (kHooDatePickerScrollViewItemHeight / 2), width - (2 * kHooDatePickerLineMargin), kHooDatePickerLineWidth)]; 701 | _lineSecondsTop.backgroundColor = self.highlightColor; 702 | [self addSubview:_lineSecondsTop]; 703 | 704 | _lineSecondsBottom = [[UIView alloc] initWithFrame:CGRectMake(_scrollViewSeconds.frame.origin.x + kHooDatePickerLineMargin, _scrollViewSeconds.frame.origin.y + (_scrollViewSeconds.frame.size.height / 2) + (kHooDatePickerScrollViewItemHeight / 2), width - (2 * kHooDatePickerLineMargin), kHooDatePickerLineWidth)]; 705 | _lineSecondsBottom.backgroundColor = self.highlightColor; 706 | [self addSubview:_lineSecondsBottom]; 707 | 708 | // Update ScrollView Data 709 | [self buildSelectorLabelsSeconds]; 710 | 711 | UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGestureSecondsCaptured:)]; 712 | singleTap.numberOfTapsRequired = 1; 713 | singleTap.numberOfTouchesRequired = 1; 714 | [_scrollViewSeconds addGestureRecognizer:singleTap]; 715 | } 716 | 717 | - (void)buildSelectorLabelsSeconds { 718 | 719 | CGFloat offsetContentScrollView = (_scrollViewSeconds.frame.size.height - kHooDatePickerScrollViewItemHeight) / 2.0; 720 | 721 | if (_labelsSeconds && _labelsSeconds.count > 0) { 722 | for (UILabel *label in _labelsSeconds) { 723 | [label removeFromSuperview]; 724 | } 725 | } 726 | 727 | _labelsSeconds = [[NSMutableArray alloc] init]; 728 | 729 | for (int i = 0; i < self.seconds.count; i++) { 730 | 731 | NSString *second = (NSString*)[self.seconds objectAtIndex:i]; 732 | 733 | UILabel *labelSecond = [[UILabel alloc] initWithFrame:CGRectMake(0, (i * kHooDatePickerScrollViewItemHeight) + offsetContentScrollView, _scrollViewSeconds.frame.size.width, kHooDatePickerScrollViewItemHeight)]; 734 | labelSecond.text = second; 735 | labelSecond.font = kHooDatePickerLabelFont; 736 | labelSecond.textAlignment = NSTextAlignmentCenter; 737 | labelSecond.textColor = self.tintColor; 738 | labelSecond.backgroundColor = [UIColor clearColor]; 739 | 740 | [_labelsSeconds addObject:labelSecond]; 741 | [_scrollViewSeconds addSubview:labelSecond]; 742 | } 743 | 744 | _scrollViewSeconds.contentSize = CGSizeMake(_scrollViewSeconds.frame.size.width, (kHooDatePickerScrollViewItemHeight * self.seconds.count) + (offsetContentScrollView * 2)); 745 | } 746 | 747 | - (void)removeSelectorSeconds { 748 | 749 | if (_scrollViewSeconds) { 750 | [_scrollViewSeconds removeFromSuperview]; 751 | _scrollViewSeconds = nil; 752 | } 753 | if (_lineSecondsTop) { 754 | [_lineSecondsTop removeFromSuperview]; 755 | _lineSecondsTop = nil; 756 | } 757 | if (_lineSecondsBottom) { 758 | [_lineSecondsBottom removeFromSuperview]; 759 | _lineSecondsBottom = nil; 760 | } 761 | } 762 | 763 | #pragma mark - Actions 764 | 765 | - (void)actionButtonCancel:(UIButton *)sender { 766 | 767 | [self dismiss]; 768 | 769 | if ([self.delegate respondsToSelector:@selector(datePicker:didCancel:)]) { 770 | [self.delegate datePicker:self didCancel:sender]; 771 | } 772 | } 773 | 774 | - (void)actionButtonValid:(UIButton *)sender { 775 | 776 | [self dismiss]; 777 | 778 | if ([self.delegate respondsToSelector:@selector(datePicker:didSelectedDate:)]) { 779 | [self.delegate datePicker:self didSelectedDate:[self getDate]]; 780 | } 781 | } 782 | 783 | #pragma mark - Show and Dismiss 784 | 785 | -(void)show { 786 | 787 | if (!_superView) return; 788 | 789 | if (self.hidden == YES) { 790 | self.hidden = NO; 791 | } 792 | 793 | if (_isInitialized == NO) { 794 | self.frame = CGRectMake(self.frame.origin.x, _superView.frame.size.height, self.frame.size.width, self.frame.size.height); 795 | _isInitialized = YES; 796 | } 797 | 798 | [self.superView insertSubview:self.dimBackgroundView belowSubview:self]; 799 | 800 | if (self.datePickerMode == HooDatePickerModeDate || self.datePickerMode == HooDatePickerModeDateAndTime) { 801 | 802 | int indexDays = [self getIndexForScrollViewPosition:_scrollViewDays]; 803 | [self highlightLabelInArray:_labelsDays atIndex:indexDays]; 804 | 805 | int indexMonths = [self getIndexForScrollViewPosition:_scrollViewMonths]; 806 | [self highlightLabelInArray:_labelsMonths atIndex:indexMonths]; 807 | 808 | int indexYears = [self getIndexForScrollViewPosition:_scrollViewYears]; 809 | [self highlightLabelInArray:_labelsYears atIndex:indexYears]; 810 | } 811 | 812 | if (self.datePickerMode == HooDatePickerModeTime || self.datePickerMode == HooDatePickerModeDateAndTime) { 813 | 814 | int indexHours = [self getIndexForScrollViewPosition:_scrollViewHours]; 815 | [self highlightLabelInArray:_labelsHours atIndex:indexHours]; 816 | 817 | int indexMinutes = [self getIndexForScrollViewPosition:_scrollViewMinutes]; 818 | [self highlightLabelInArray:_labelsMinutes atIndex:indexMinutes]; 819 | 820 | int indexSeconds = [self getIndexForScrollViewPosition:_scrollViewSeconds]; 821 | [self highlightLabelInArray:_labelsSeconds atIndex:indexSeconds]; 822 | } 823 | 824 | if (self.datePickerMode == HooDatePickerModeYearAndMonth) { 825 | int indexMonths = [self getIndexForScrollViewPosition:_scrollViewMonths]; 826 | [self highlightLabelInArray:_labelsMonths atIndex:indexMonths]; 827 | 828 | int indexYears = [self getIndexForScrollViewPosition:_scrollViewYears]; 829 | [self highlightLabelInArray:_labelsYears atIndex:indexYears]; 830 | } 831 | 832 | [UIView animateWithDuration:kHooDatePickerAnimationDuration delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 833 | self.frame = CGRectMake(self.frame.origin.x, _superView.frame.size.height - kHooDatePickerHeight, self.frame.size.width, self.frame.size.height); 834 | } completion:^(BOOL finished) { 835 | _isOpen = YES; 836 | 837 | }]; 838 | } 839 | 840 | -(void)dismiss { 841 | 842 | if (!_superView) return; 843 | [UIView animateWithDuration:kHooDatePickerAnimationDuration delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 844 | self.frame = CGRectMake(self.frame.origin.x, _superView.frame.size.height, self.frame.size.width, self.frame.size.height); 845 | self.dimBackgroundView.alpha = 0.0; 846 | } completion:^(BOOL finished) { 847 | _isOpen = NO; 848 | [self.dimBackgroundView removeFromSuperview]; 849 | self.dimBackgroundView = nil; 850 | }]; 851 | } 852 | 853 | #pragma mark - DatePicker Mode 854 | 855 | - (void)setDatePickerMode:(HooDatePickerMode)mode { 856 | _datePickerMode = mode; 857 | [self setupControl]; 858 | } 859 | 860 | #pragma mark - Collections 861 | 862 | - (NSMutableArray*)getYears { 863 | 864 | NSMutableArray *years = [[NSMutableArray alloc] init]; 865 | 866 | NSInteger yearMin = 0; 867 | 868 | if (self.minimumDate) { 869 | NSDateComponents* componentsMin = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:self.minimumDate]; 870 | yearMin = [componentsMin year]; 871 | } else { 872 | yearMin = _minYear; 873 | } 874 | 875 | NSInteger yearMax = 0; 876 | NSDateComponents* componentsMax = nil; 877 | 878 | if (self.maximumDate) { 879 | componentsMax = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:self.maximumDate]; 880 | yearMax = [componentsMax year]; 881 | } else { 882 | componentsMax = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:[NSDate date]]; 883 | yearMax = [componentsMax year]; 884 | } 885 | 886 | for (NSInteger i = yearMin; i <= yearMax; i++) { 887 | 888 | [years addObject:[NSString stringWithFormat:@"%ld\u5e74", (long)i]]; 889 | } 890 | 891 | return years; 892 | } 893 | 894 | - (NSMutableArray*)getDates { 895 | NSMutableArray *dates = [[NSMutableArray alloc] init]; 896 | 897 | if (self.minimumDate && self.maximumDate) { 898 | NSInteger days = [self.minimumDate daysBetween:self.maximumDate]; 899 | for (NSInteger i = 0; i < days; i++) { 900 | NSDate *date = [self.minimumDate dateByAddingDays:i]; 901 | if ([date daysBetween: self.maximumDate] >= 0) { 902 | [dates addObject:date]; 903 | } 904 | } 905 | } else { 906 | 907 | NSDateComponents* currentComponents = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:[NSDate date]]; 908 | NSInteger currentYear = [currentComponents year]; 909 | 910 | NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; 911 | [dateComponents setCalendar:self.calendar]; 912 | [dateComponents setTimeZone:self.timeZone]; 913 | [dateComponents setDay:1]; 914 | [dateComponents setMonth:1]; 915 | [dateComponents setHour:0]; 916 | [dateComponents setMinute:0]; 917 | [dateComponents setSecond:0]; 918 | [dateComponents setYear:currentYear]; 919 | 920 | NSDateComponents *maxComponents = [[NSDateComponents alloc] init]; 921 | [maxComponents setCalendar:self.calendar]; 922 | [maxComponents setTimeZone:self.timeZone]; 923 | [maxComponents setDay:1]; 924 | [maxComponents setMonth:1]; 925 | [maxComponents setHour:0]; 926 | [maxComponents setMinute:0]; 927 | [maxComponents setSecond:0]; 928 | [maxComponents setYear:currentYear + 1]; 929 | 930 | NSDate *yearMin = [dateComponents date]; 931 | NSDate *yearMax = [maxComponents date]; 932 | 933 | NSInteger timestampMin = [yearMin timeIntervalSince1970]; 934 | NSInteger timestampMax = [yearMax timeIntervalSince1970]; 935 | 936 | while (timestampMin < timestampMax) { 937 | 938 | NSDate *date = [NSDate dateWithTimeIntervalSince1970:timestampMin]; 939 | 940 | [dates addObject:date]; 941 | 942 | timestampMin += 1 * 24 * 60 * 60; 943 | } 944 | } 945 | 946 | return dates; 947 | } 948 | 949 | - (NSMutableArray*)getDaysInMonth:(NSDate*)date { 950 | 951 | if (date == nil) date = [NSDate date]; 952 | 953 | NSRange daysRange = [self.calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date]; 954 | 955 | NSMutableArray *days = [[NSMutableArray alloc] init]; 956 | 957 | for (int i = 1; i <= daysRange.length; i++) { 958 | 959 | [days addObject:[NSString stringWithFormat:@"%d%@", i, @"日"]]; 960 | } 961 | 962 | return days; 963 | } 964 | 965 | #pragma mark - UIScrollView Delegate 966 | 967 | - (void)singleTapGestureDaysCaptured:(UITapGestureRecognizer *)gesture { 968 | 969 | CGPoint touchPoint = [gesture locationInView:self]; 970 | CGFloat touchY = touchPoint.y; 971 | 972 | if (touchY < (_lineDaysTop.frame.origin.y)) { 973 | 974 | if (_selectedDay > 1) { 975 | _selectedDay -= 1; 976 | [self setScrollView:_scrollViewDays atIndex:(_selectedDay - 1) animated:YES]; 977 | } 978 | 979 | } else if (touchY > (_lineDaysBottom.frame.origin.y)) { 980 | 981 | if (_selectedDay < _days.count) { 982 | _selectedDay += 1; 983 | [self setScrollView:_scrollViewDays atIndex:(_selectedDay - 1) animated:YES]; 984 | } 985 | } 986 | } 987 | 988 | - (void)singleTapGestureMonthsCaptured:(UITapGestureRecognizer *)gesture { 989 | 990 | CGPoint touchPoint = [gesture locationInView:self]; 991 | CGFloat touchY = touchPoint.y; 992 | 993 | if (touchY < (_lineMonthsTop.frame.origin.y)) { 994 | 995 | if (_selectedMonth > 1) { 996 | _selectedMonth -= 1; 997 | [self setScrollView:_scrollViewMonths atIndex:(_selectedMonth - 1) animated:YES]; 998 | } 999 | 1000 | } else if (touchY > (_lineMonthsBottom.frame.origin.y)) { 1001 | 1002 | if (_selectedMonth < self.months.count) { 1003 | _selectedMonth += 1; 1004 | [self setScrollView:_scrollViewMonths atIndex:(_selectedMonth - 1) animated:YES]; 1005 | } 1006 | } 1007 | } 1008 | 1009 | - (void)singleTapGestureYearsCaptured:(UITapGestureRecognizer *)gesture { 1010 | 1011 | CGPoint touchPoint = [gesture locationInView:self]; 1012 | CGFloat touchY = touchPoint.y; 1013 | 1014 | NSInteger minYear = _minYear; 1015 | 1016 | if (touchY < (_lineYearsTop.frame.origin.y)) { 1017 | 1018 | if (_selectedYear > minYear) { 1019 | _selectedYear -= 1; 1020 | [self setScrollView:_scrollViewYears atIndex:(_selectedYear - minYear) animated:YES]; 1021 | } 1022 | 1023 | } else if (touchY > (_lineYearsBottom.frame.origin.y)) { 1024 | 1025 | if (_selectedYear < (_years.count + (minYear - 1))) { 1026 | _selectedYear += 1; 1027 | [self setScrollView:_scrollViewYears atIndex:(_selectedYear - minYear) animated:YES]; 1028 | } 1029 | } 1030 | } 1031 | 1032 | 1033 | - (void)singleTapGestureDatesCaptured:(UITapGestureRecognizer *)gesture { 1034 | 1035 | CGPoint touchPoint = [gesture locationInView:self]; 1036 | CGFloat touchY = touchPoint.y; 1037 | 1038 | if (touchY < (_lineDatesTop.frame.origin.y)) { 1039 | 1040 | if (_selectedDate > 0) { 1041 | _selectedDate -= 1; 1042 | [self setScrollView:_scrollViewDates atIndex:_selectedDate animated:YES]; 1043 | } 1044 | 1045 | } else if (touchY > (_lineDatesBottom.frame.origin.y)) { 1046 | 1047 | if (_selectedDate < _dates.count - 1) { 1048 | _selectedDate += 1; 1049 | [self setScrollView:_scrollViewDates atIndex:_selectedDate animated:YES]; 1050 | } 1051 | } 1052 | } 1053 | 1054 | - (void)singleTapGestureHoursCaptured:(UITapGestureRecognizer *)gesture { 1055 | 1056 | CGPoint touchPoint = [gesture locationInView:self]; 1057 | CGFloat touchY = touchPoint.y; 1058 | 1059 | if (touchY < (_lineHoursTop.frame.origin.y)) { 1060 | 1061 | if (_selectedHour > 0) { 1062 | _selectedHour -= 1; 1063 | [self setScrollView:_scrollViewHours atIndex:_selectedHour animated:YES]; 1064 | } 1065 | 1066 | } else if (touchY > (_lineHoursBottom.frame.origin.y)) { 1067 | 1068 | if (_selectedHour < self.hours.count - 1) { 1069 | _selectedHour += 1; 1070 | [self setScrollView:_scrollViewHours atIndex:_selectedHour animated:YES]; 1071 | } 1072 | } 1073 | } 1074 | 1075 | - (void)singleTapGestureMinutesCaptured:(UITapGestureRecognizer *)gesture { 1076 | 1077 | CGPoint touchPoint = [gesture locationInView:self]; 1078 | CGFloat touchY = touchPoint.y; 1079 | 1080 | if (touchY < (_lineMinutesTop.frame.origin.y)) { 1081 | 1082 | if (_selectedMinute > 0) { 1083 | _selectedMinute -= 1; 1084 | [self setScrollView:_scrollViewMinutes atIndex:_selectedMinute animated:YES]; 1085 | } 1086 | 1087 | } else if (touchY > (_lineMinutesBottom.frame.origin.y)) { 1088 | 1089 | if (_selectedMinute < self.minutes.count - 1) { 1090 | _selectedMinute += 1; 1091 | [self setScrollView:_scrollViewMinutes atIndex:_selectedMinute animated:YES]; 1092 | } 1093 | } 1094 | } 1095 | 1096 | - (void)singleTapGestureSecondsCaptured:(UITapGestureRecognizer *)gesture { 1097 | 1098 | CGPoint touchPoint = [gesture locationInView:self]; 1099 | CGFloat touchY = touchPoint.y; 1100 | 1101 | if (touchY < (_lineSecondsTop.frame.origin.y)) { 1102 | 1103 | if (_selectedSecond > 0) { 1104 | _selectedSecond -= 1; 1105 | [self setScrollView:_scrollViewSeconds atIndex:_selectedSecond animated:YES]; 1106 | } 1107 | 1108 | } else if (touchY > (_lineSecondsBottom.frame.origin.y)) { 1109 | 1110 | if (_selectedSecond < self.seconds.count - 1) { 1111 | _selectedSecond += 1; 1112 | [self setScrollView:_scrollViewSeconds atIndex:_selectedSecond animated:YES]; 1113 | } 1114 | } 1115 | } 1116 | 1117 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { 1118 | 1119 | int index = [self getIndexForScrollViewPosition:scrollView]; 1120 | 1121 | [self updateSelectedDateAtIndex:index forScrollView:scrollView]; 1122 | 1123 | if (scrollView.tag == ScrollViewTagValue_DAYS) { 1124 | [self highlightLabelInArray:_labelsDays atIndex:index]; 1125 | } else if (scrollView.tag == ScrollViewTagValue_MONTHS) { 1126 | [self highlightLabelInArray:_labelsMonths atIndex:index]; 1127 | } else if (scrollView.tag == ScrollViewTagValue_YEARS) { 1128 | [self highlightLabelInArray:_labelsYears atIndex:index]; 1129 | } else if (scrollView.tag == ScrollViewTagValue_HOURS) { 1130 | [self highlightLabelInArray:_labelsHours atIndex:index]; 1131 | } else if (scrollView.tag == ScrollViewTagValue_MINUTES) { 1132 | [self highlightLabelInArray:_labelsMinutes atIndex:index]; 1133 | } else if (scrollView.tag == ScrollViewTagValue_SECONDS) { 1134 | [self highlightLabelInArray:_labelsSeconds atIndex:index]; 1135 | } else if (scrollView.tag == ScrollViewTagValue_DATES) { 1136 | [self highlightLabelInArray:_labelsDates atIndex:index]; 1137 | } 1138 | } 1139 | 1140 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { 1141 | 1142 | int index = [self getIndexForScrollViewPosition:scrollView]; 1143 | 1144 | [self updateSelectedDateAtIndex:index forScrollView:scrollView]; 1145 | 1146 | [self setScrollView:scrollView atIndex:index animated:YES]; 1147 | 1148 | NSDate *selectedDate = [self getDate]; 1149 | if (self.datePickerMode != HooDatePickerModeDateAndTime && self.datePickerMode != HooDatePickerModeTime) { 1150 | if ([selectedDate compare:self.minimumDate] == NSOrderedAscending) { 1151 | [self setDate:self.minimumDate animated:YES]; 1152 | } 1153 | 1154 | if ([selectedDate compare:self.maximumDate] == NSOrderedDescending) { 1155 | [self setDate:self.maximumDate animated:YES]; 1156 | } 1157 | } 1158 | if ([self.delegate respondsToSelector:@selector(datePicker:dateDidChange:)]) { 1159 | [self.delegate datePicker:self dateDidChange:selectedDate]; 1160 | } 1161 | } 1162 | 1163 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 1164 | 1165 | int index = [self getIndexForScrollViewPosition:scrollView]; 1166 | 1167 | [self updateSelectedDateAtIndex:index forScrollView:scrollView]; 1168 | 1169 | [self setScrollView:scrollView atIndex:index animated:YES]; 1170 | 1171 | NSDate *selectedDate = [self getDate]; 1172 | if (self.datePickerMode != HooDatePickerModeDateAndTime && self.datePickerMode != HooDatePickerModeTime) { 1173 | if ([selectedDate compare:self.minimumDate] == NSOrderedAscending) { 1174 | [self setDate:self.minimumDate animated:YES]; 1175 | return; 1176 | } 1177 | 1178 | if ([selectedDate compare:self.maximumDate] == NSOrderedDescending) { 1179 | [self setDate:self.maximumDate animated:YES]; 1180 | return; 1181 | } 1182 | } 1183 | 1184 | if ([self.delegate respondsToSelector:@selector(datePicker:dateDidChange:)]) { 1185 | [self.delegate datePicker:self dateDidChange:selectedDate]; 1186 | } 1187 | } 1188 | 1189 | - (void)updateSelectedDateAtIndex:(int)index forScrollView:(UIScrollView*)scrollView { 1190 | 1191 | if (scrollView.tag == ScrollViewTagValue_DAYS) { 1192 | _selectedDay = index + 1; // 1 to 31 1193 | } else if (scrollView.tag == ScrollViewTagValue_MONTHS) { 1194 | 1195 | _selectedMonth = index + 1; // 1 to 12 1196 | 1197 | // Updates days : 1198 | [self updateNumberOfDays]; 1199 | 1200 | } else if (scrollView.tag == ScrollViewTagValue_YEARS) { 1201 | 1202 | _selectedYear = _minYear + index; 1203 | 1204 | // Updates days : 1205 | [self updateNumberOfDays]; 1206 | 1207 | } else if (scrollView.tag == ScrollViewTagValue_HOURS) { 1208 | _selectedHour = index; // 0 to 23 1209 | } else if (scrollView.tag == ScrollViewTagValue_MINUTES) { 1210 | _selectedMinute = index; // 0 to 59 1211 | } else if (scrollView.tag == ScrollViewTagValue_SECONDS) { 1212 | _selectedSecond = index; // 0 to 59 1213 | } else if (scrollView.tag == ScrollViewTagValue_DATES) { 1214 | _selectedDate = index; 1215 | } 1216 | } 1217 | 1218 | - (void)updateNumberOfDays { 1219 | 1220 | // Updates days : 1221 | NSDate *date = [self convertToDateDay:1 month:_selectedMonth year:_selectedYear hours:_selectedHour minutes:_selectedMinute seconds:_selectedSecond]; 1222 | 1223 | if (!date) return; 1224 | 1225 | NSMutableArray *newDays = [self getDaysInMonth:date]; 1226 | 1227 | if (newDays.count != _days.count) { 1228 | 1229 | _days = newDays; 1230 | 1231 | [self buildSelectorLabelsDays]; 1232 | 1233 | if (_selectedDay > _days.count) { 1234 | _selectedDay = _days.count; 1235 | } 1236 | 1237 | [self highlightLabelInArray:_labelsDays atIndex:_selectedDay - 1]; 1238 | } 1239 | } 1240 | 1241 | - (int)getIndexForScrollViewPosition:(UIScrollView *)scrollView { 1242 | 1243 | CGFloat offsetContentScrollView = (scrollView.frame.size.height - kHooDatePickerScrollViewItemHeight) / 2.0; 1244 | CGFloat offetY = scrollView.contentOffset.y; 1245 | CGFloat index = floorf((offetY + offsetContentScrollView) / kHooDatePickerScrollViewItemHeight); 1246 | index = (index - 1); 1247 | return index; 1248 | } 1249 | 1250 | - (void)setScrollView:(UIScrollView*)scrollView atIndex:(NSInteger)index animated:(BOOL)animated { 1251 | 1252 | if (!scrollView) return; 1253 | 1254 | if (animated) { 1255 | [UIView beginAnimations:@"ScrollViewAnimation" context:nil]; 1256 | [UIView setAnimationDelegate:self]; 1257 | [UIView setAnimationDuration:kHooDatePickerAnimationDuration]; 1258 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 1259 | } 1260 | 1261 | scrollView.contentOffset = CGPointMake(0.0, (index * kHooDatePickerScrollViewItemHeight)); 1262 | 1263 | if (animated) { 1264 | [UIView commitAnimations]; 1265 | } 1266 | 1267 | if (self.delegate != nil && [self.delegate respondsToSelector:@selector(datePicker:dateDidChange:)]) { 1268 | [self.delegate datePicker:self dateDidChange:[self getDate]]; 1269 | } 1270 | } 1271 | 1272 | - (void)highlightLabelInArray:(NSMutableArray*)labels atIndex:(NSInteger)index { 1273 | if (!labels) return; 1274 | if (index > labels.count) return; 1275 | if (index < 0) return; 1276 | 1277 | for (int i = 0; i < labels.count; i++) { 1278 | UILabel *label = (UILabel *)[labels objectAtIndex:i]; 1279 | if (i != index) { 1280 | label.textColor = self.tintColor; 1281 | label.font = kHooDatePickerLabelFont; 1282 | } else { 1283 | label.textColor = self.highlightColor; 1284 | label.font = kHooDatePickerLabelSelectedFont; 1285 | } 1286 | } 1287 | } 1288 | 1289 | #pragma mark - Date 1290 | 1291 | - (void)setDate:(NSDate *)date animated:(BOOL)animated { 1292 | 1293 | if (!date) return; 1294 | NSDateComponents* components = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate:date]; 1295 | 1296 | _selectedDay = [components day]; 1297 | _selectedMonth = [components month]; 1298 | _selectedYear = [components year]; 1299 | _selectedHour = [components hour]; 1300 | /** 1301 | * only show mininute 00 10 20 ~ 50 in hotel tour edit order for flight pick up 1302 | */ 1303 | if (self.datePickerMode != HooDatePickerModeDateAndTime) { 1304 | _selectedMinute = [components minute]; 1305 | } 1306 | _selectedSecond = [components second]; 1307 | 1308 | if (self.datePickerMode == HooDatePickerModeDateAndTime) { 1309 | if (self.minimumDate) { 1310 | [self setScrollView:_scrollViewDates atIndex:[date daysBetween:self.minimumDate] - 1 animated:animated]; 1311 | } else { 1312 | [self setScrollView:_scrollViewDates atIndex:(_selectedDay - 1) animated:animated]; 1313 | } 1314 | 1315 | } 1316 | 1317 | if (self.datePickerMode == HooDatePickerModeDate) { 1318 | [self setScrollView:_scrollViewYears atIndex:(_selectedYear - _minYear) animated:animated]; 1319 | [self setScrollView:_scrollViewMonths atIndex:(_selectedMonth - 1) animated:animated]; 1320 | [self setScrollView:_scrollViewDays atIndex:(_selectedDay - 1) animated:animated]; 1321 | 1322 | 1323 | } 1324 | 1325 | if (self.datePickerMode == HooDatePickerModeTime || self.datePickerMode == HooDatePickerModeDateAndTime) { 1326 | [self setScrollView:_scrollViewHours atIndex:_selectedHour animated:animated]; 1327 | [self setScrollView:_scrollViewMinutes atIndex:_selectedMinute animated:animated]; 1328 | [self setScrollView:_scrollViewSeconds atIndex:_selectedSecond animated:animated]; 1329 | } 1330 | 1331 | if (self.datePickerMode == HooDatePickerModeYearAndMonth) { 1332 | [self setScrollView:_scrollViewMonths atIndex:(_selectedMonth - 1) animated:animated]; 1333 | [self setScrollView:_scrollViewYears atIndex:(_selectedYear - _minYear) animated:animated]; 1334 | } 1335 | 1336 | if (self.delegate != nil && [self.delegate respondsToSelector:@selector(datePicker:dateDidChange:)]) { 1337 | [self.delegate datePicker:self dateDidChange:[self getDate]]; 1338 | } 1339 | } 1340 | 1341 | - (NSDate*)convertToDateDay:(NSInteger)day month:(NSInteger)month year:(NSInteger)year hours:(NSInteger)hours minutes:(NSInteger)minutes seconds:(NSInteger)seconds { 1342 | 1343 | NSMutableString *dateString = [[NSMutableString alloc] init]; 1344 | 1345 | NSDateFormatter *dateFormatter = self.dateFormatter; 1346 | if (self.timeZone) [dateFormatter setTimeZone:self.timeZone]; 1347 | [dateFormatter setLocale:self.locale]; 1348 | 1349 | // Date Mode : 1350 | if (self.datePickerMode == HooDatePickerModeDate) { 1351 | 1352 | if (day < 10) { 1353 | [dateString appendFormat:@"0%ld-", (long)day]; 1354 | } else { 1355 | [dateString appendFormat:@"%ld-", (long)day]; 1356 | } 1357 | 1358 | if (month < 10) { 1359 | [dateString appendFormat:@"0%ld-", (long)month]; 1360 | } else { 1361 | [dateString appendFormat:@"%ld-", (long)month]; 1362 | } 1363 | 1364 | [dateString appendFormat:@"%ld", (long)year]; 1365 | 1366 | [dateFormatter setDateFormat:@"dd-MM-yyyy"]; 1367 | } 1368 | 1369 | // Time Mode : 1370 | if (self.datePickerMode == HooDatePickerModeTime) { 1371 | 1372 | NSDateComponents* components = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:[NSDate date]]; 1373 | 1374 | NSInteger nowDay = [components day]; 1375 | NSInteger nowMonth = [components month]; 1376 | NSInteger nowYear = [components year]; 1377 | 1378 | if (nowDay < 10) { 1379 | [dateString appendFormat:@"0%ld-", (long)nowDay]; 1380 | } else { 1381 | [dateString appendFormat:@"%ld-", (long)nowDay]; 1382 | } 1383 | 1384 | if (nowMonth < 10) { 1385 | [dateString appendFormat:@"0%ld-", (long)nowMonth]; 1386 | } else { 1387 | [dateString appendFormat:@"%ld-", (long)nowMonth]; 1388 | } 1389 | 1390 | [dateString appendFormat:@"%ld", (long)nowYear]; 1391 | 1392 | if (hours < 10) { 1393 | [dateString appendFormat:@" 0%ld:", (long)hours]; 1394 | } else { 1395 | [dateString appendFormat:@" %ld:", (long)hours]; 1396 | } 1397 | 1398 | if (minutes < 10) { 1399 | [dateString appendFormat:@"0%ld:", (long)minutes]; 1400 | } else { 1401 | [dateString appendFormat:@"%ld:", (long)minutes]; 1402 | } 1403 | 1404 | if (seconds < 10) { 1405 | [dateString appendFormat:@"0%ld", (long)seconds]; 1406 | } else { 1407 | [dateString appendFormat:@"%ld", (long)seconds]; 1408 | } 1409 | 1410 | [dateFormatter setDateFormat:@"dd-MM-yyyy HH:mm:ss"]; 1411 | } 1412 | 1413 | // Date and Time Mode : 1414 | if (self.datePickerMode == HooDatePickerModeDateAndTime) { 1415 | 1416 | if (day < 10) { 1417 | [dateString appendFormat:@"0%ld-", (long)day]; 1418 | } else { 1419 | [dateString appendFormat:@"%ld-", (long)day]; 1420 | } 1421 | 1422 | if (month < 10) { 1423 | [dateString appendFormat:@"0%ld-", (long)month]; 1424 | } else { 1425 | [dateString appendFormat:@"%ld-", (long)month]; 1426 | } 1427 | 1428 | [dateString appendFormat:@"%ld", (long)year]; 1429 | 1430 | if (hours < 10) { 1431 | [dateString appendFormat:@" 0%ld:", (long)hours]; 1432 | } else { 1433 | [dateString appendFormat:@" %ld:", (long)hours]; 1434 | } 1435 | 1436 | if (minutes < 10) { 1437 | [dateString appendFormat:@"0%ld:", (long)minutes]; 1438 | } else { 1439 | [dateString appendFormat:@"%ld:", (long)minutes]; 1440 | } 1441 | 1442 | [dateString appendString:@"00"]; 1443 | 1444 | [dateFormatter setDateFormat:@"dd-MM-yyyy HH:mm:ss"]; 1445 | } 1446 | 1447 | if (self.datePickerMode == HooDatePickerModeYearAndMonth) { 1448 | 1449 | if (month < 10) { 1450 | [dateString appendFormat:@"0%ld-", (long)month]; 1451 | } else { 1452 | [dateString appendFormat:@"%ld-", (long)month]; 1453 | } 1454 | 1455 | [dateString appendFormat:@"%ld", (long)year]; 1456 | 1457 | [dateFormatter setDateFormat:@"MM-yyyy"]; 1458 | } 1459 | 1460 | return [dateFormatter dateFromString:dateString]; 1461 | } 1462 | 1463 | - (NSDate*)convertToDate:(NSInteger)days hours:(NSInteger)hours minutes:(NSInteger)minutes seconds:(NSInteger)seconds { 1464 | 1465 | NSDate *date = [self.minimumDate dateByAddingDays:days]; 1466 | 1467 | NSMutableString *dateString = [[NSMutableString alloc] initWithString:[date stringForFormat:@"dd-MM-yyyy"]]; 1468 | 1469 | NSDateFormatter *dateFormatter = self.dateFormatter; 1470 | if (self.timeZone) [dateFormatter setTimeZone:self.timeZone]; 1471 | [dateFormatter setLocale:self.locale]; 1472 | 1473 | 1474 | if (hours < 10) { 1475 | [dateString appendFormat:@" 0%ld:", (long)hours]; 1476 | } else { 1477 | [dateString appendFormat:@" %ld:", (long)hours]; 1478 | } 1479 | /** 1480 | * only show mininute 00 10 20 ~ 50 in hotel tour edit order for flight pick up 1481 | */ 1482 | 1483 | if (!minutes) { 1484 | [dateString appendFormat:@"0%ld:", (long)minutes]; 1485 | } else { 1486 | [dateString appendFormat:@"%ld:", (long)minutes * 10]; 1487 | } 1488 | 1489 | [dateString appendString:@"00"]; 1490 | 1491 | [dateFormatter setDateFormat:@"dd-MM-yyyy HH:mm:ss"]; 1492 | return [dateFormatter dateFromString:dateString]; 1493 | } 1494 | 1495 | - (NSDate*)getDate { 1496 | if (self.datePickerMode == HooDatePickerModeDateAndTime) { 1497 | return [self convertToDate:_selectedDate hours:_selectedHour minutes:_selectedMinute seconds:_selectedSecond]; 1498 | } 1499 | return [self convertToDateDay:_selectedDay month:_selectedMonth year:_selectedYear hours:_selectedHour minutes:_selectedMinute seconds:_selectedSecond]; 1500 | } 1501 | 1502 | #pragma mark - Getters and Setters 1503 | 1504 | - (UIView *)dimBackgroundView { 1505 | if(!_dimBackgroundView) { 1506 | _dimBackgroundView = [[UIView alloc] initWithFrame:self.superView.bounds]; 1507 | [_dimBackgroundView setTranslatesAutoresizingMaskIntoConstraints:YES]; 1508 | _dimBackgroundView.backgroundColor = [UIColor clearColor]; 1509 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismiss)]; 1510 | [_dimBackgroundView addGestureRecognizer:tap]; 1511 | } 1512 | return _dimBackgroundView; 1513 | } 1514 | 1515 | - (UIView *)headerView { 1516 | if (!_headerView) { 1517 | _headerView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.frame.size.width, kHooDatePickerHeaderHeight)]; 1518 | // Button Cancel 1519 | UIButton *cancelButton = [[UIButton alloc] initWithFrame:CGRectMake(kHooDatePickerPadding, 0.0, kHooDatePickerButtonHeaderWidth, kHooDatePickerHeaderHeight)]; 1520 | [cancelButton setTitle:kCancelButtonItemTitle forState:UIControlStateNormal]; 1521 | [cancelButton setTitleColor:self.tintColor forState:UIControlStateNormal]; 1522 | [cancelButton addTarget:self action:@selector(actionButtonCancel:) forControlEvents:UIControlEventTouchUpInside]; 1523 | [_headerView addSubview:cancelButton]; 1524 | 1525 | // Button confirm 1526 | UIButton *sureButton = [[UIButton alloc] initWithFrame:CGRectMake(self.frame.size.width - kHooDatePickerButtonHeaderWidth - kHooDatePickerPadding, 0.0, kHooDatePickerButtonHeaderWidth, kHooDatePickerHeaderHeight)]; 1527 | [sureButton setTitle:kSureButtonItemTitle forState:UIControlStateNormal]; 1528 | [sureButton setTitleColor:self.highlightColor forState:UIControlStateNormal]; 1529 | [sureButton addTarget:self action:@selector(actionButtonValid:) forControlEvents:UIControlEventTouchUpInside]; 1530 | [_headerView addSubview:sureButton]; 1531 | 1532 | // Label Title 1533 | _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(cancelButton.frame) + kHooDatePickerPadding, 0.0, self.frame.size.width - ((kHooDatePickerButtonHeaderWidth + kHooDatePickerPadding * 2) * 2 ), kHooDatePickerHeaderHeight)]; 1534 | _titleLabel.text = self.title; 1535 | _titleLabel.font = kHooDatePickerTitleFont; 1536 | _titleLabel.textAlignment = NSTextAlignmentCenter; 1537 | _titleLabel.textColor = self.tintColor; 1538 | [_headerView addSubview:_titleLabel]; 1539 | } 1540 | return _headerView; 1541 | } 1542 | 1543 | - (NSDateFormatter *)dateFormatter { 1544 | if (!_dateFormatter) { 1545 | NSDateFormatter *dateFormatter = [NSDate shareDateFormatter]; 1546 | _dateFormatter = dateFormatter; 1547 | } 1548 | _dateFormatter.dateFormat = kDateFormatYYYYMMDD; 1549 | return _dateFormatter; 1550 | } 1551 | 1552 | - (NSCalendar *)calendar { 1553 | if (!_calendar) { 1554 | _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; 1555 | _calendar.timeZone = self.timeZone; 1556 | _calendar.locale = self.locale; 1557 | } 1558 | return _calendar; 1559 | } 1560 | 1561 | - (NSMutableArray *)months { 1562 | NSMutableArray *months = [[NSMutableArray alloc] init]; 1563 | for (int monthNumber = 1; monthNumber <= 12; monthNumber++) { 1564 | NSString *dateString = [NSString stringWithFormat: @"%d", monthNumber]; 1565 | NSDateFormatter* dateFormatter = self.dateFormatter; 1566 | if (self.timeZone) [dateFormatter setTimeZone:self.timeZone]; 1567 | [dateFormatter setLocale:self.locale]; 1568 | [dateFormatter setDateFormat:@"MM"]; 1569 | NSDate* myDate = [dateFormatter dateFromString:dateString]; 1570 | 1571 | NSDateFormatter *formatter = self.dateFormatter; 1572 | if (self.timeZone) [dateFormatter setTimeZone:self.timeZone]; 1573 | [dateFormatter setLocale:self.locale]; 1574 | [formatter setDateFormat:@"MMM"]; 1575 | NSString *stringFromDate = [formatter stringFromDate:myDate]; 1576 | 1577 | [months addObject:stringFromDate]; 1578 | } 1579 | _months = months; 1580 | return _months; 1581 | } 1582 | 1583 | - (NSMutableArray*)hours { 1584 | if (!_hours) { 1585 | NSMutableArray *hours = [[NSMutableArray alloc] init]; 1586 | 1587 | for (int i = 0; i < 24; i++) { 1588 | if (i < 10) { 1589 | [hours addObject:[NSString stringWithFormat:@"0%d%@", i, @"时"]]; 1590 | } else { 1591 | [hours addObject:[NSString stringWithFormat:@"%d%@", i, @"时"]]; 1592 | } 1593 | } 1594 | _hours = hours; 1595 | } 1596 | return _hours; 1597 | } 1598 | 1599 | - (NSMutableArray*)minutes { 1600 | if (!_minutes) { 1601 | NSMutableArray *minutes = [[NSMutableArray alloc] init]; 1602 | /** 1603 | * only show mininute 00 10 20 ~ 50 in hotel tour edit order for flight pick up 1604 | */ 1605 | for (int i = 0; i < 6; i++) { 1606 | if (!i) { 1607 | [minutes addObject:[NSString stringWithFormat:@"%d0%@", i, @"分"]]; 1608 | } else { 1609 | [minutes addObject:[NSString stringWithFormat:@"%d%@", i * 10, @"分"]]; 1610 | } 1611 | 1612 | } 1613 | _minutes = minutes; 1614 | } 1615 | return _minutes; 1616 | } 1617 | 1618 | - (NSMutableArray*)seconds { 1619 | if (!_seconds) { 1620 | 1621 | NSMutableArray *seconds = [[NSMutableArray alloc] init]; 1622 | 1623 | for (int i = 0; i < 60; i++) { 1624 | if (i < 10) { 1625 | [seconds addObject:[NSString stringWithFormat:@"0%d", i]]; 1626 | } else { 1627 | [seconds addObject:[NSString stringWithFormat:@"%d", i]]; 1628 | } 1629 | } 1630 | _seconds = seconds; 1631 | } 1632 | return _seconds; 1633 | } 1634 | - (NSTimeZone *)timeZone { 1635 | if (!_timeZone) { 1636 | _timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; 1637 | } 1638 | return _timeZone; 1639 | } 1640 | 1641 | - (NSLocale *)locale { 1642 | if (!_locale) { 1643 | _locale = [NSLocale currentLocale]; 1644 | } 1645 | return _locale; 1646 | } 1647 | 1648 | - (void)setTintColor:(UIColor *)tintColor { 1649 | _tintColor = tintColor; 1650 | [self setupControl]; 1651 | } 1652 | 1653 | - (void)setHighlightColor:(UIColor *)highlightColor { 1654 | _highlightColor = highlightColor; 1655 | [self setupControl]; 1656 | } 1657 | 1658 | - (void)setMinimumDate:(NSDate*)date { 1659 | _minimumDate = date; 1660 | NSDateComponents* componentsMin = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:_minimumDate]; 1661 | NSInteger yearMin = [componentsMin year]; 1662 | _minYear = yearMin; 1663 | [self setupControl]; 1664 | } 1665 | 1666 | - (void)setMaximumDate:(NSDate*)date { 1667 | _maximumDate = date; 1668 | [self setupControl]; 1669 | } 1670 | 1671 | 1672 | @end 1673 | -------------------------------------------------------------------------------- /HooDatePickerDeomo/HooDatePicker/NSDate+HooDatePicker.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+HooDatePicker.h 3 | // HooDatePickerDeomo 4 | // 5 | // Created by hujianghua on 6/21/16. 6 | // Copyright © 2016 hujianghua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | extern NSString *const kDateFormatYYYYMMDD; 12 | extern NSString *const kDateFormatYYMMDDTHHmmss; 13 | 14 | 15 | @interface NSDate (HooDatePicker) 16 | 17 | + (NSDateFormatter *)shareDateFormatter; 18 | 19 | - (NSInteger)daysBetween:(NSDate *)aDate; 20 | 21 | - (NSDate *)dateByAddingDays:(NSInteger)days; 22 | 23 | - (NSString *)stringForFormat:(NSString *)format; 24 | 25 | 26 | @end 27 | 28 | @interface NSCalendar (AT) 29 | 30 | + (instancetype)sharedCalendar; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /HooDatePickerDeomo/HooDatePicker/NSDate+HooDatePicker.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+HooDatePicker.m 3 | // HooDatePickerDeomo 4 | // 5 | // Created by hujianghua on 6/21/16. 6 | // Copyright © 2016 hujianghua. All rights reserved. 7 | // 8 | 9 | #import "NSDate+HooDatePicker.h" 10 | 11 | NSString * const kDateFormatYYYYMMDD = @"yyyy-MM-dd"; 12 | NSString * const kDateFormatYYMMDDTHHmmss = @"yyyy-MM-dd'T'HH:mm:ss"; 13 | 14 | 15 | @implementation NSDate (HooDatePicker) 16 | 17 | + (NSDateFormatter *)shareDateFormatter { 18 | static NSDateFormatter *currentFormatter = nil; 19 | static dispatch_once_t sharedDateFormatter_onceToken; 20 | dispatch_once(&sharedDateFormatter_onceToken, ^{ 21 | if (!currentFormatter) { 22 | currentFormatter = [[NSDateFormatter alloc] init]; 23 | [currentFormatter setDateFormat:kDateFormatYYYYMMDD]; 24 | [currentFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; 25 | } 26 | }); 27 | return currentFormatter; 28 | } 29 | 30 | - (NSDate *)dateByAddingDays:(NSInteger)days { 31 | NSCalendar *calendar = [NSCalendar sharedCalendar]; 32 | NSDateComponents *components = [[NSDateComponents alloc] init]; 33 | [components setDay:days]; 34 | return [calendar dateByAddingComponents:components toDate:self options:0]; 35 | } 36 | 37 | - (NSInteger)daysBetween:(NSDate *)aDate { 38 | NSUInteger unitFlags = NSCalendarUnitDay; 39 | NSDate *from = [NSDate at_dateFromString:[self stringForYearMonthDayDashed]]; 40 | NSDate *to = [NSDate at_dateFromString:[aDate stringForYearMonthDayDashed]]; 41 | NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; 42 | NSDateComponents *components = [calendar components:unitFlags fromDate:from toDate:to options:0]; 43 | return labs([components day]) + 1; 44 | } 45 | 46 | - (NSString *) stringForYearMonthDayDashed { 47 | return [self stringForFormat:kDateFormatYYYYMMDD]; 48 | } 49 | 50 | - (NSString *)stringForFormat:(NSString *)format { 51 | if (!format) { 52 | return nil; 53 | } 54 | 55 | NSDateFormatter *formatter = [NSDate shareDateFormatter]; 56 | [formatter setDateFormat:format]; 57 | 58 | NSString *timeStr = [formatter stringFromDate:self]; 59 | return timeStr; 60 | } 61 | 62 | + (NSDate *)at_dateFromString:(NSString *)dateString { 63 | NSDateFormatter *dateFormatter = [self shareDateFormatter]; 64 | if (dateString.length > kDateFormatYYYYMMDD.length) { 65 | [dateFormatter setDateFormat:kDateFormatYYMMDDTHHmmss]; 66 | } else { 67 | [dateFormatter setDateFormat:kDateFormatYYYYMMDD]; 68 | } 69 | NSDate *date = [dateFormatter dateFromString:dateString]; 70 | if (!date) { 71 | date = [NSDate date]; 72 | } 73 | return date; 74 | } 75 | 76 | @end 77 | 78 | @implementation NSCalendar (AT) 79 | 80 | + (instancetype)sharedCalendar 81 | { 82 | static id instance; 83 | static dispatch_once_t onceToken; 84 | dispatch_once(&onceToken, ^{ 85 | instance = [NSCalendar currentCalendar]; 86 | }); 87 | return instance; 88 | } 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /HooDatePickerDeomo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /HooDatePickerDeomo/Simulator Screen Shot Mar 6, 2016, 3.04.09 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakciehoo/HooDatePicker/cc739681ec46c20251e0573d8a5b4af3406d398b/HooDatePickerDeomo/Simulator Screen Shot Mar 6, 2016, 3.04.09 AM.png -------------------------------------------------------------------------------- /HooDatePickerDeomo/Simulator Screen Shot Mar 6, 2016, 3.04.30 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakciehoo/HooDatePicker/cc739681ec46c20251e0573d8a5b4af3406d398b/HooDatePickerDeomo/Simulator Screen Shot Mar 6, 2016, 3.04.30 AM.png -------------------------------------------------------------------------------- /HooDatePickerDeomo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // HooDatePickerDeomo 4 | // 5 | // Created by hujianghua on 3/5/16. 6 | // Copyright © 2016 hujianghua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /HooDatePickerDeomo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // HooDatePickerDeomo 4 | // 5 | // Created by hujianghua on 3/5/16. 6 | // Copyright © 2016 hujianghua. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "HooDatePicker/HooDatePicker.h" 11 | 12 | @interface ViewController () 13 | @property (nonatomic, strong) HooDatePicker *datePicker; 14 | @property (weak, nonatomic) IBOutlet UILabel *labelDateSelected; 15 | @end 16 | 17 | @implementation ViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | // Do any additional setup after loading the view, typically from a nib. 22 | self.datePicker = [[HooDatePicker alloc] initWithSuperView:self.view]; 23 | self.datePicker.delegate = self; 24 | self.datePicker.datePickerMode = HooDatePickerModeDate; 25 | NSDateFormatter *dateFormatter = [NSDate shareDateFormatter]; 26 | [dateFormatter setDateFormat:kDateFormatYYYYMMDD]; 27 | NSDate *maxDate = [dateFormatter dateFromString:@"2050-01-01"]; 28 | NSDate *minDate = [dateFormatter dateFromString:@"2016-01-01"]; 29 | 30 | [self.datePicker setDate:[NSDate date] animated:YES]; 31 | self.datePicker.minimumDate = minDate; 32 | self.datePicker.maximumDate = maxDate; 33 | } 34 | 35 | - (IBAction)actionOpen:(id)sender { 36 | 37 | [self.datePicker show]; 38 | } 39 | 40 | - (IBAction)actionClose:(id)sender { 41 | 42 | [self.datePicker dismiss]; 43 | } 44 | 45 | - (IBAction)actionSetDate:(id)sender { 46 | 47 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 48 | [dateFormatter setLocale:[NSLocale currentLocale]]; 49 | [dateFormatter setDateFormat:@"dd-MM-yyyy HH:mm:ss"]; 50 | NSDate *date = [dateFormatter dateFromString:@"07-12-1985 15:36:45"]; 51 | 52 | if (self.datePicker.isOpen) { 53 | [self.datePicker setDate:date animated:YES]; 54 | } else { 55 | [self.datePicker setDate:date animated:NO]; 56 | } 57 | } 58 | 59 | #pragma mark - FlatDatePicker Delegate 60 | 61 | - (void)datePicker:(HooDatePicker *)datePicker dateDidChange:(NSDate *)date { 62 | 63 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 64 | [dateFormatter setLocale:[NSLocale currentLocale]]; 65 | 66 | if (datePicker.datePickerMode == HooDatePickerModeDate) { 67 | [dateFormatter setDateFormat:@"dd MMMM yyyy"]; 68 | } else if (datePicker.datePickerMode == HooDatePickerModeTime) { 69 | [dateFormatter setDateFormat:@"HH:mm:ss"]; 70 | } else if (datePicker.datePickerMode == HooDatePickerModeYearAndMonth){ 71 | [dateFormatter setDateFormat:@"MM/yy"]; 72 | } else { 73 | [dateFormatter setDateFormat:@"dd MMMM yyyy HH:mm:ss"]; 74 | 75 | } 76 | 77 | NSString *value = [dateFormatter stringFromDate:date]; 78 | 79 | self.labelDateSelected.text = value; 80 | } 81 | 82 | - (void)datePicker:(HooDatePicker *)datePicker didCancel:(UIButton *)sender { 83 | 84 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"关闭日期选择" delegate:self cancelButtonTitle:@"好" otherButtonTitles:nil, nil]; 85 | [alertView show]; 86 | } 87 | 88 | - (void)datePicker:(HooDatePicker *)datePicker didSelectedDate:(NSDate*)date { 89 | 90 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 91 | [dateFormatter setLocale:[NSLocale currentLocale]]; 92 | 93 | if (datePicker.datePickerMode == HooDatePickerModeDate) { 94 | [dateFormatter setDateFormat:@"dd MMMM yyyy"]; 95 | } else if (datePicker.datePickerMode == HooDatePickerModeTime) { 96 | [dateFormatter setDateFormat:@"HH:mm:ss"]; 97 | } else if (datePicker.datePickerMode == HooDatePickerModeYearAndMonth){ 98 | [dateFormatter setDateFormat:@"MM/yy"]; 99 | } else { 100 | [dateFormatter setDateFormat:@"dd MMMM yyyy HH:mm:ss"]; 101 | } 102 | 103 | NSString *value = [dateFormatter stringFromDate:date]; 104 | 105 | self.labelDateSelected.text = value; 106 | 107 | NSString *message = [NSString stringWithFormat:@"确定选择日期 : %@", value]; 108 | 109 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil]; 110 | [alertView show]; 111 | } 112 | @end 113 | -------------------------------------------------------------------------------- /HooDatePickerDeomo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // HooDatePickerDeomo 4 | // 5 | // Created by hujianghua on 3/5/16. 6 | // Copyright © 2016 hujianghua. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /HooDatePickerDeomoTests/HooDatePickerDeomoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // HooDatePickerDeomoTests.m 3 | // HooDatePickerDeomoTests 4 | // 5 | // Created by hujianghua on 3/5/16. 6 | // Copyright © 2016 hujianghua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface HooDatePickerDeomoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation HooDatePickerDeomoTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /HooDatePickerDeomoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /HooDatePickerDeomoUITests/HooDatePickerDeomoUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // HooDatePickerDeomoUITests.m 3 | // HooDatePickerDeomoUITests 4 | // 5 | // Created by hujianghua on 3/5/16. 6 | // Copyright © 2016 hujianghua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface HooDatePickerDeomoUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation HooDatePickerDeomoUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /HooDatePickerDeomoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 JackieHoo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ### HooDatePicker 介绍(introduction) 3 | ================================================== 4 | 项目需要一个DatePicker,只显示年月,而且选中的时间高亮显示(苹果默认的只显示灰色),研究多个代码后,封装的一个性能比较高的自定义DatePicker。苹果原生的UIDatePicker无法实现只提供年月选择,而HooDatePicker增加了年月显示,并提供了扁平化和样式美化,也更加符合中国人的时间习惯。 5 | 6 | A customized DatePicker. which can show only Years and months.the UIDatePicker don't achive this. and HooDatePicker looks much more beautiful than UIDatePicker.I hope you can like it. 7 | 8 | Github address(Github下载地址):https://github.com/jakciehoo/HooDatePicker 9 | ### 效果图展示(picure show): 10 | ================================================== 11 | `HooDatePickerModeDate Demo picture:` 12 | 13 | 14 | ![Simulator Screen Shot Mar 6, 2016, 3.04.09 AM.png](http://upload-images.jianshu.io/upload_images/1112722-99526bace022799d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 15 | 16 | `HooDatePickerModeYearAndMonth Demo picture` 17 | 18 | 19 | ![Simulator Screen Shot Mar 6, 2016, 3.04.30 AM.png](http://upload-images.jianshu.io/upload_images/1112722-134a88183835d837.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 20 | 21 | 22 | # `如何使用How To Use:` 23 | ================================================== 24 | ```java 25 | HooDatePicker *datePicker = [[HooDatePicker alloc] initWithSuperView:self.view]; 26 | datePicker.delegate = self; 27 | datePicker.datePickerMode = HooDatePickerModeYearAndMonth; 28 | [datePicker show]; 29 | ``` 30 | ### 更多用法More: 31 | ================================================== 32 | 1.设置其他属性 33 | ```java 34 |     NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 35 |     [dateFormatter setDateFormat:@"dd-MM-yyyy HH:mm:ss"]; 36 |     NSDate *maxDate = [dateFormatter dateFromString:@"01-01-2050 00:00:00"]; 37 |     NSDate *minDate = [dateFormatter dateFromString:@"01-01-2016 00:00:00"]; 38 |     [self.datePicker setDate:[NSDate date] animated:YES];//设置默认日期 39 |     self.datePicker.minimumDate = minDate;//设置显示的最小日期 40 |     self.datePicker.maximumDate = maxDate;//设置显示的最大日期 41 |     [self.datePicker setTintColor:[UIColor redColor]];//设置主色 42 |     [self.datePicker setHighlightColor:[UIColor yellowColor]];//设置高亮颜色 43 | ``` 44 | 2.相关代理 45 | ```java 46 | @protocol HooDatePickerDelegate 47 | @optional 48 | - (void)datePicker:(HooDatePicker *)datePicker dateDidChange:(NSDate *)date; 49 | - (void)datePicker:(HooDatePicker *)datePicker clickedCancelButton:(UIButton *)sender; 50 | - (void)datePicker:(HooDatePicker *)datePicker clickedSureButton:(UIButton *)sender date:(NSDate*)date; 51 | @end 52 | ``` 53 | For more detail, you can download this project and see demo code in it. 54 | 55 | Enjoy it!! 56 | 57 | 欢迎关注我的微信公众号“丁丁的coding日记”,一起学习iOS开发技术 58 | 59 | ![qrcode_for_gh_a0330831fea6_430 (1).jpg](http://upload-images.jianshu.io/upload_images/1112722-cfce03ad624ff2c0.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 60 | --------------------------------------------------------------------------------