├── Foundation+Log.m ├── LICENSE ├── README.md ├── YMCitySelect.podspec ├── YMCitySelect.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── mac.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── mac.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── YMCitySelect.xcscheme │ └── xcschememanagement.plist ├── YMCitySelect ├── UIView+ym_extension.h ├── UIView+ym_extension.m ├── YMCityGroupsModel.h ├── YMCityGroupsModel.m ├── YMCityModel.h ├── YMCityModel.m ├── YMCitySearch.h ├── YMCitySearch.m ├── YMCitySelect.bundle │ ├── btn_navigation_close.png │ ├── btn_navigation_close@2x.png │ ├── btn_navigation_close_hl.png │ ├── btn_navigation_close_hl@2x.png │ ├── cities.plist │ └── cityGroups.plist ├── YMCitySelect.h ├── YMCitySelect.m ├── YMCollectionViewCell.h ├── YMCollectionViewCell.m ├── YMSearchBar.h ├── YMSearchBar.m ├── YMTableViewCell.h └── YMTableViewCell.m ├── YMCitySelectExample ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ └── ym_iosdeveloper.imageset │ │ ├── Contents.json │ │ └── ym_iosdeveloper.jpg ├── Base.lproj │ └── LaunchScreen.storyboard ├── Info.plist ├── YMViewController.h ├── YMViewController.m └── main.m └── ymcityselect.gif /Foundation+Log.m: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @implementation NSDictionary (Log) 5 | /** 6 | * 系统会自动调用 7 | */ 8 | - (NSString *)descriptionWithLocale:(id)locale 9 | { 10 | NSMutableString *str = [NSMutableString string]; 11 | 12 | [str appendString:@"{\n"]; 13 | 14 | // 遍历字典的所有键值对 15 | [self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 16 | [str appendFormat:@"\t%@ = %@,\n", key, obj]; 17 | }]; 18 | 19 | [str appendString:@"}"]; 20 | 21 | // 查出最后一个,的范围 22 | NSRange range = [str rangeOfString:@"," options:NSBackwardsSearch]; 23 | // 删掉最后一个, 24 | [str deleteCharactersInRange:range]; 25 | 26 | return str; 27 | } 28 | @end 29 | 30 | @implementation NSArray (Log) 31 | /** 32 | * 系统会自动调用 33 | */ 34 | - (NSString *)descriptionWithLocale:(id)locale 35 | { 36 | NSMutableString *str = [NSMutableString string]; 37 | 38 | [str appendString:@"[\n"]; 39 | 40 | // 遍历数组的所有元素 41 | [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 42 | [str appendFormat:@"%@,\n", obj]; 43 | }]; 44 | 45 | [str appendString:@"]"]; 46 | 47 | // 查出最后一个,的范围 48 | NSRange range = [str rangeOfString:@"," options:NSBackwardsSearch]; 49 | // 删掉最后一个, 50 | [str deleteCharactersInRange:range]; 51 | 52 | return str; 53 | } 54 | @end 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 iOSDeveloper赵依民 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 |

YMCitySelect

2 | 11 |

GitHub:iosdeveloperSVIP 12 |     邮箱:iosdeveloper@vip.163.com

13 |

亲爱的各位同行,如果在使用中出现bug,请联系邮箱:iosdeveloper@vip.163.com,如果使用不错的话请帮我点下右上角星星Star,非常感谢

14 |

操作目录

15 | 21 | 22 | 23 |
24 |

安装使用

25 |

使用 CocoaPods安装

26 |
pod 'YMCitySelect'
27 |

手动导入文件

28 | 32 |

一行代码集成

33 |
34 | 
35 | [self presentViewController:[[YMCitySelect alloc] initWithDelegate:self] animated:YES completion:nil];
36 | 
//通过Modal弹出城市控制器,并传入代理控制器 37 |
YMCitySelectDelegate //请遵守协议 38 |
-(void)ym_ymCitySelectCityName:(NSString *)cityName 39 |
//请实现代理方法cityName就是返回的城市名
40 |

亲爱的各位同行,如果你已经浏览到这,请帮我点下右上角星星Star,非常感谢

41 | -------------------------------------------------------------------------------- /YMCitySelect.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'YMCitySelect' 3 | s.version = '1.0.2' 4 | s.summary = 'One line of code do city choice' 5 | s.homepage = 'https://github.com/iosdeveloperSVIP/YMCitySelect' 6 | s.license = 'MIT' 7 | s.authors = {'zhaoyimin' => 'iosdeveloper@vip.163.com'} 8 | s.platform = :ios, '8.0' 9 | s.source = {:git => 'https://github.com/iosdeveloperSVIP/YMCitySelect.git', :tag => s.version} 10 | s.source_files = 'YMCitySelect/*.{h,m}' 11 | s.resource = 'YMCitySelect/YMCitySelect.bundle' 12 | s.requires_arc = true 13 | end 14 | -------------------------------------------------------------------------------- /YMCitySelect.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 04505A671CCCA0E100D0613A /* YMCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 04505A661CCCA0E100D0613A /* YMCollectionViewCell.m */; }; 11 | 04505A6B1CCD0D4F00D0613A /* Foundation+Log.m in Sources */ = {isa = PBXBuildFile; fileRef = 04505A6A1CCD0D4F00D0613A /* Foundation+Log.m */; }; 12 | 04505A6E1CCD32AE00D0613A /* YMCityModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 04505A6D1CCD32AE00D0613A /* YMCityModel.m */; }; 13 | 047FC5D31CCB6C4F0062A943 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 047FC5CB1CCB6C4F0062A943 /* AppDelegate.m */; }; 14 | 047FC5D41CCB6C4F0062A943 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 047FC5CC1CCB6C4F0062A943 /* Assets.xcassets */; }; 15 | 047FC5D51CCB6C4F0062A943 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 047FC5CD1CCB6C4F0062A943 /* LaunchScreen.storyboard */; }; 16 | 047FC5D71CCB6C4F0062A943 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 047FC5D01CCB6C4F0062A943 /* main.m */; }; 17 | 047FC5D81CCB6C4F0062A943 /* YMViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 047FC5D21CCB6C4F0062A943 /* YMViewController.m */; }; 18 | 047FC5DC1CCB6D4E0062A943 /* YMCitySelect.m in Sources */ = {isa = PBXBuildFile; fileRef = 047FC5DB1CCB6D4E0062A943 /* YMCitySelect.m */; }; 19 | 047FC5DE1CCB6DA10062A943 /* YMCitySelect.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 047FC5DD1CCB6DA10062A943 /* YMCitySelect.bundle */; }; 20 | 047FC5E11CCB72240062A943 /* YMCitySearch.m in Sources */ = {isa = PBXBuildFile; fileRef = 047FC5E01CCB72240062A943 /* YMCitySearch.m */; }; 21 | 047FC5E41CCB761E0062A943 /* UIView+ym_extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 047FC5E31CCB761E0062A943 /* UIView+ym_extension.m */; }; 22 | 047FC5E71CCBDA360062A943 /* YMSearchBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 047FC5E61CCBDA360062A943 /* YMSearchBar.m */; }; 23 | 047FC5EA1CCBE9A00062A943 /* YMCityGroupsModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 047FC5E91CCBE9A00062A943 /* YMCityGroupsModel.m */; }; 24 | 047FC5F01CCC11970062A943 /* YMTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 047FC5EF1CCC11970062A943 /* YMTableViewCell.m */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 04505A651CCCA0E100D0613A /* YMCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YMCollectionViewCell.h; sourceTree = ""; }; 29 | 04505A661CCCA0E100D0613A /* YMCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YMCollectionViewCell.m; sourceTree = ""; }; 30 | 04505A6A1CCD0D4F00D0613A /* Foundation+Log.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Foundation+Log.m"; sourceTree = ""; }; 31 | 04505A6C1CCD32AE00D0613A /* YMCityModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YMCityModel.h; sourceTree = ""; }; 32 | 04505A6D1CCD32AE00D0613A /* YMCityModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YMCityModel.m; sourceTree = ""; }; 33 | 047FC5AC1CCB690D0062A943 /* YMCitySelect.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = YMCitySelect.app; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | 047FC5CA1CCB6C4F0062A943 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 35 | 047FC5CB1CCB6C4F0062A943 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 36 | 047FC5CC1CCB6C4F0062A943 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 37 | 047FC5CE1CCB6C4F0062A943 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 38 | 047FC5CF1CCB6C4F0062A943 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 39 | 047FC5D01CCB6C4F0062A943 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 40 | 047FC5D11CCB6C4F0062A943 /* YMViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YMViewController.h; sourceTree = ""; }; 41 | 047FC5D21CCB6C4F0062A943 /* YMViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YMViewController.m; sourceTree = ""; }; 42 | 047FC5DA1CCB6D4E0062A943 /* YMCitySelect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YMCitySelect.h; sourceTree = ""; }; 43 | 047FC5DB1CCB6D4E0062A943 /* YMCitySelect.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YMCitySelect.m; sourceTree = ""; }; 44 | 047FC5DD1CCB6DA10062A943 /* YMCitySelect.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = YMCitySelect.bundle; sourceTree = ""; }; 45 | 047FC5DF1CCB72240062A943 /* YMCitySearch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YMCitySearch.h; sourceTree = ""; }; 46 | 047FC5E01CCB72240062A943 /* YMCitySearch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YMCitySearch.m; sourceTree = ""; }; 47 | 047FC5E21CCB761E0062A943 /* UIView+ym_extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+ym_extension.h"; sourceTree = ""; }; 48 | 047FC5E31CCB761E0062A943 /* UIView+ym_extension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+ym_extension.m"; sourceTree = ""; }; 49 | 047FC5E51CCBDA360062A943 /* YMSearchBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YMSearchBar.h; sourceTree = ""; }; 50 | 047FC5E61CCBDA360062A943 /* YMSearchBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YMSearchBar.m; sourceTree = ""; }; 51 | 047FC5E81CCBE9A00062A943 /* YMCityGroupsModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YMCityGroupsModel.h; sourceTree = ""; }; 52 | 047FC5E91CCBE9A00062A943 /* YMCityGroupsModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YMCityGroupsModel.m; sourceTree = ""; }; 53 | 047FC5EE1CCC11970062A943 /* YMTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YMTableViewCell.h; sourceTree = ""; }; 54 | 047FC5EF1CCC11970062A943 /* YMTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YMTableViewCell.m; sourceTree = ""; }; 55 | /* End PBXFileReference section */ 56 | 57 | /* Begin PBXFrameworksBuildPhase section */ 58 | 047FC5A91CCB690D0062A943 /* Frameworks */ = { 59 | isa = PBXFrameworksBuildPhase; 60 | buildActionMask = 2147483647; 61 | files = ( 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | /* End PBXFrameworksBuildPhase section */ 66 | 67 | /* Begin PBXGroup section */ 68 | 047FC5A31CCB690D0062A943 = { 69 | isa = PBXGroup; 70 | children = ( 71 | 04505A6A1CCD0D4F00D0613A /* Foundation+Log.m */, 72 | 047FC5D91CCB6C790062A943 /* YMCitySelect */, 73 | 047FC5C91CCB6C4F0062A943 /* YMCitySelectExample */, 74 | 047FC5AD1CCB690D0062A943 /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 047FC5AD1CCB690D0062A943 /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 047FC5AC1CCB690D0062A943 /* YMCitySelect.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 047FC5C91CCB6C4F0062A943 /* YMCitySelectExample */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 047FC5CA1CCB6C4F0062A943 /* AppDelegate.h */, 90 | 047FC5CB1CCB6C4F0062A943 /* AppDelegate.m */, 91 | 047FC5CC1CCB6C4F0062A943 /* Assets.xcassets */, 92 | 047FC5CD1CCB6C4F0062A943 /* LaunchScreen.storyboard */, 93 | 047FC5CF1CCB6C4F0062A943 /* Info.plist */, 94 | 047FC5D01CCB6C4F0062A943 /* main.m */, 95 | 047FC5D11CCB6C4F0062A943 /* YMViewController.h */, 96 | 047FC5D21CCB6C4F0062A943 /* YMViewController.m */, 97 | ); 98 | path = YMCitySelectExample; 99 | sourceTree = ""; 100 | }; 101 | 047FC5D91CCB6C790062A943 /* YMCitySelect */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | 047FC5DD1CCB6DA10062A943 /* YMCitySelect.bundle */, 105 | 047FC5DA1CCB6D4E0062A943 /* YMCitySelect.h */, 106 | 047FC5DB1CCB6D4E0062A943 /* YMCitySelect.m */, 107 | 047FC5DF1CCB72240062A943 /* YMCitySearch.h */, 108 | 047FC5E01CCB72240062A943 /* YMCitySearch.m */, 109 | 047FC5EE1CCC11970062A943 /* YMTableViewCell.h */, 110 | 047FC5EF1CCC11970062A943 /* YMTableViewCell.m */, 111 | 04505A651CCCA0E100D0613A /* YMCollectionViewCell.h */, 112 | 04505A661CCCA0E100D0613A /* YMCollectionViewCell.m */, 113 | 047FC5E81CCBE9A00062A943 /* YMCityGroupsModel.h */, 114 | 047FC5E91CCBE9A00062A943 /* YMCityGroupsModel.m */, 115 | 04505A6C1CCD32AE00D0613A /* YMCityModel.h */, 116 | 04505A6D1CCD32AE00D0613A /* YMCityModel.m */, 117 | 047FC5E51CCBDA360062A943 /* YMSearchBar.h */, 118 | 047FC5E61CCBDA360062A943 /* YMSearchBar.m */, 119 | 047FC5E21CCB761E0062A943 /* UIView+ym_extension.h */, 120 | 047FC5E31CCB761E0062A943 /* UIView+ym_extension.m */, 121 | ); 122 | path = YMCitySelect; 123 | sourceTree = ""; 124 | }; 125 | /* End PBXGroup section */ 126 | 127 | /* Begin PBXNativeTarget section */ 128 | 047FC5AB1CCB690D0062A943 /* YMCitySelect */ = { 129 | isa = PBXNativeTarget; 130 | buildConfigurationList = 047FC5C31CCB690D0062A943 /* Build configuration list for PBXNativeTarget "YMCitySelect" */; 131 | buildPhases = ( 132 | 047FC5A81CCB690D0062A943 /* Sources */, 133 | 047FC5A91CCB690D0062A943 /* Frameworks */, 134 | 047FC5AA1CCB690D0062A943 /* Resources */, 135 | ); 136 | buildRules = ( 137 | ); 138 | dependencies = ( 139 | ); 140 | name = YMCitySelect; 141 | productName = YMCitySelect; 142 | productReference = 047FC5AC1CCB690D0062A943 /* YMCitySelect.app */; 143 | productType = "com.apple.product-type.application"; 144 | }; 145 | /* End PBXNativeTarget section */ 146 | 147 | /* Begin PBXProject section */ 148 | 047FC5A41CCB690D0062A943 /* Project object */ = { 149 | isa = PBXProject; 150 | attributes = { 151 | LastUpgradeCheck = 0730; 152 | ORGANIZATIONNAME = YiMin; 153 | TargetAttributes = { 154 | 047FC5AB1CCB690D0062A943 = { 155 | CreatedOnToolsVersion = 7.3; 156 | DevelopmentTeam = 3YYUCKAF23; 157 | }; 158 | }; 159 | }; 160 | buildConfigurationList = 047FC5A71CCB690D0062A943 /* Build configuration list for PBXProject "YMCitySelect" */; 161 | compatibilityVersion = "Xcode 3.2"; 162 | developmentRegion = English; 163 | hasScannedForEncodings = 0; 164 | knownRegions = ( 165 | en, 166 | Base, 167 | ); 168 | mainGroup = 047FC5A31CCB690D0062A943; 169 | productRefGroup = 047FC5AD1CCB690D0062A943 /* Products */; 170 | projectDirPath = ""; 171 | projectRoot = ""; 172 | targets = ( 173 | 047FC5AB1CCB690D0062A943 /* YMCitySelect */, 174 | ); 175 | }; 176 | /* End PBXProject section */ 177 | 178 | /* Begin PBXResourcesBuildPhase section */ 179 | 047FC5AA1CCB690D0062A943 /* Resources */ = { 180 | isa = PBXResourcesBuildPhase; 181 | buildActionMask = 2147483647; 182 | files = ( 183 | 047FC5D51CCB6C4F0062A943 /* LaunchScreen.storyboard in Resources */, 184 | 047FC5D41CCB6C4F0062A943 /* Assets.xcassets in Resources */, 185 | 047FC5DE1CCB6DA10062A943 /* YMCitySelect.bundle in Resources */, 186 | ); 187 | runOnlyForDeploymentPostprocessing = 0; 188 | }; 189 | /* End PBXResourcesBuildPhase section */ 190 | 191 | /* Begin PBXSourcesBuildPhase section */ 192 | 047FC5A81CCB690D0062A943 /* Sources */ = { 193 | isa = PBXSourcesBuildPhase; 194 | buildActionMask = 2147483647; 195 | files = ( 196 | 047FC5DC1CCB6D4E0062A943 /* YMCitySelect.m in Sources */, 197 | 047FC5D81CCB6C4F0062A943 /* YMViewController.m in Sources */, 198 | 04505A671CCCA0E100D0613A /* YMCollectionViewCell.m in Sources */, 199 | 047FC5F01CCC11970062A943 /* YMTableViewCell.m in Sources */, 200 | 047FC5E41CCB761E0062A943 /* UIView+ym_extension.m in Sources */, 201 | 047FC5D71CCB6C4F0062A943 /* main.m in Sources */, 202 | 04505A6E1CCD32AE00D0613A /* YMCityModel.m in Sources */, 203 | 047FC5E11CCB72240062A943 /* YMCitySearch.m in Sources */, 204 | 047FC5E71CCBDA360062A943 /* YMSearchBar.m in Sources */, 205 | 047FC5EA1CCBE9A00062A943 /* YMCityGroupsModel.m in Sources */, 206 | 047FC5D31CCB6C4F0062A943 /* AppDelegate.m in Sources */, 207 | 04505A6B1CCD0D4F00D0613A /* Foundation+Log.m in Sources */, 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | }; 211 | /* End PBXSourcesBuildPhase section */ 212 | 213 | /* Begin PBXVariantGroup section */ 214 | 047FC5CD1CCB6C4F0062A943 /* LaunchScreen.storyboard */ = { 215 | isa = PBXVariantGroup; 216 | children = ( 217 | 047FC5CE1CCB6C4F0062A943 /* Base */, 218 | ); 219 | name = LaunchScreen.storyboard; 220 | sourceTree = ""; 221 | }; 222 | /* End PBXVariantGroup section */ 223 | 224 | /* Begin XCBuildConfiguration section */ 225 | 047FC5C11CCB690D0062A943 /* Debug */ = { 226 | isa = XCBuildConfiguration; 227 | buildSettings = { 228 | ALWAYS_SEARCH_USER_PATHS = NO; 229 | CLANG_ANALYZER_NONNULL = YES; 230 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 231 | CLANG_CXX_LIBRARY = "libc++"; 232 | CLANG_ENABLE_MODULES = YES; 233 | CLANG_ENABLE_OBJC_ARC = YES; 234 | CLANG_WARN_BOOL_CONVERSION = YES; 235 | CLANG_WARN_CONSTANT_CONVERSION = YES; 236 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 237 | CLANG_WARN_EMPTY_BODY = YES; 238 | CLANG_WARN_ENUM_CONVERSION = YES; 239 | CLANG_WARN_INT_CONVERSION = YES; 240 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 241 | CLANG_WARN_UNREACHABLE_CODE = YES; 242 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 243 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 244 | COPY_PHASE_STRIP = NO; 245 | DEBUG_INFORMATION_FORMAT = dwarf; 246 | ENABLE_STRICT_OBJC_MSGSEND = YES; 247 | ENABLE_TESTABILITY = YES; 248 | GCC_C_LANGUAGE_STANDARD = gnu99; 249 | GCC_DYNAMIC_NO_PIC = NO; 250 | GCC_NO_COMMON_BLOCKS = YES; 251 | GCC_OPTIMIZATION_LEVEL = 0; 252 | GCC_PREPROCESSOR_DEFINITIONS = ( 253 | "DEBUG=1", 254 | "$(inherited)", 255 | ); 256 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 257 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 258 | GCC_WARN_UNDECLARED_SELECTOR = YES; 259 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 260 | GCC_WARN_UNUSED_FUNCTION = YES; 261 | GCC_WARN_UNUSED_VARIABLE = YES; 262 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 263 | MTL_ENABLE_DEBUG_INFO = YES; 264 | ONLY_ACTIVE_ARCH = YES; 265 | SDKROOT = iphoneos; 266 | }; 267 | name = Debug; 268 | }; 269 | 047FC5C21CCB690D0062A943 /* Release */ = { 270 | isa = XCBuildConfiguration; 271 | buildSettings = { 272 | ALWAYS_SEARCH_USER_PATHS = NO; 273 | CLANG_ANALYZER_NONNULL = YES; 274 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 275 | CLANG_CXX_LIBRARY = "libc++"; 276 | CLANG_ENABLE_MODULES = YES; 277 | CLANG_ENABLE_OBJC_ARC = YES; 278 | CLANG_WARN_BOOL_CONVERSION = YES; 279 | CLANG_WARN_CONSTANT_CONVERSION = YES; 280 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 281 | CLANG_WARN_EMPTY_BODY = YES; 282 | CLANG_WARN_ENUM_CONVERSION = YES; 283 | CLANG_WARN_INT_CONVERSION = YES; 284 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 285 | CLANG_WARN_UNREACHABLE_CODE = YES; 286 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 287 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 288 | COPY_PHASE_STRIP = NO; 289 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 290 | ENABLE_NS_ASSERTIONS = NO; 291 | ENABLE_STRICT_OBJC_MSGSEND = YES; 292 | GCC_C_LANGUAGE_STANDARD = gnu99; 293 | GCC_NO_COMMON_BLOCKS = YES; 294 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 295 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 296 | GCC_WARN_UNDECLARED_SELECTOR = YES; 297 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 298 | GCC_WARN_UNUSED_FUNCTION = YES; 299 | GCC_WARN_UNUSED_VARIABLE = YES; 300 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 301 | MTL_ENABLE_DEBUG_INFO = NO; 302 | SDKROOT = iphoneos; 303 | VALIDATE_PRODUCT = YES; 304 | }; 305 | name = Release; 306 | }; 307 | 047FC5C41CCB690D0062A943 /* Debug */ = { 308 | isa = XCBuildConfiguration; 309 | buildSettings = { 310 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 311 | INFOPLIST_FILE = YMCitySelectExample/Info.plist; 312 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 313 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 314 | PRODUCT_BUNDLE_IDENTIFIER = "Proficient-in-ios.YMCitySelect"; 315 | PRODUCT_NAME = "$(TARGET_NAME)"; 316 | }; 317 | name = Debug; 318 | }; 319 | 047FC5C51CCB690D0062A943 /* Release */ = { 320 | isa = XCBuildConfiguration; 321 | buildSettings = { 322 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 323 | INFOPLIST_FILE = YMCitySelectExample/Info.plist; 324 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 325 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 326 | PRODUCT_BUNDLE_IDENTIFIER = "Proficient-in-ios.YMCitySelect"; 327 | PRODUCT_NAME = "$(TARGET_NAME)"; 328 | }; 329 | name = Release; 330 | }; 331 | /* End XCBuildConfiguration section */ 332 | 333 | /* Begin XCConfigurationList section */ 334 | 047FC5A71CCB690D0062A943 /* Build configuration list for PBXProject "YMCitySelect" */ = { 335 | isa = XCConfigurationList; 336 | buildConfigurations = ( 337 | 047FC5C11CCB690D0062A943 /* Debug */, 338 | 047FC5C21CCB690D0062A943 /* Release */, 339 | ); 340 | defaultConfigurationIsVisible = 0; 341 | defaultConfigurationName = Release; 342 | }; 343 | 047FC5C31CCB690D0062A943 /* Build configuration list for PBXNativeTarget "YMCitySelect" */ = { 344 | isa = XCConfigurationList; 345 | buildConfigurations = ( 346 | 047FC5C41CCB690D0062A943 /* Debug */, 347 | 047FC5C51CCB690D0062A943 /* Release */, 348 | ); 349 | defaultConfigurationIsVisible = 0; 350 | defaultConfigurationName = Release; 351 | }; 352 | /* End XCConfigurationList section */ 353 | }; 354 | rootObject = 047FC5A41CCB690D0062A943 /* Project object */; 355 | } 356 | -------------------------------------------------------------------------------- /YMCitySelect.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /YMCitySelect.xcodeproj/project.xcworkspace/xcuserdata/mac.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yiminfe/YMCitySelect/b411f2741237b30a01aff5cecc721b1e79e7a5af/YMCitySelect.xcodeproj/project.xcworkspace/xcuserdata/mac.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /YMCitySelect.xcodeproj/xcuserdata/mac.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /YMCitySelect.xcodeproj/xcuserdata/mac.xcuserdatad/xcschemes/YMCitySelect.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /YMCitySelect.xcodeproj/xcuserdata/mac.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | YMCitySelect.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 047FC5AB1CCB690D0062A943 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /YMCitySelect/UIView+ym_extension.h: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // UIView+ym_extension.h 6 | // YMChannelSwitching 7 | // 8 | // Created by mac on 16/4/20. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import 13 | 14 | @interface UIView (ym_extension) 15 | 16 | @property (nonatomic, assign) CGFloat ym_x; 17 | @property (nonatomic, assign) CGFloat ym_y; 18 | @property (nonatomic, assign) CGFloat ym_centerX; 19 | @property (nonatomic, assign) CGFloat ym_centerY; 20 | @property (nonatomic, assign) CGFloat ym_width; 21 | @property (nonatomic, assign) CGFloat ym_height; 22 | @property (nonatomic, assign) CGSize ym_size; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /YMCitySelect/UIView+ym_extension.m: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // UIView+ym_extension.m 6 | // YMChannelSwitching 7 | // 8 | // Created by mac on 16/4/20. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import "UIView+ym_extension.h" 13 | 14 | @implementation UIView (ym_extension) 15 | 16 | -(void)setYm_x:(CGFloat)ym_x 17 | { 18 | CGRect frame = self.frame; 19 | frame.origin.x = ym_x; 20 | self.frame = frame; 21 | } 22 | 23 | -(CGFloat)ym_x 24 | { 25 | return self.frame.origin.x; 26 | } 27 | 28 | -(void)setYm_y:(CGFloat)ym_y 29 | { 30 | CGRect frame = self.frame; 31 | frame.origin.y = ym_y; 32 | self.frame = frame; 33 | } 34 | 35 | -(CGFloat)ym_y 36 | { 37 | return self.frame.origin.y; 38 | } 39 | 40 | -(void)setYm_width:(CGFloat)ym_width{ 41 | CGRect frame = self.frame; 42 | frame.size.width = ym_width; 43 | self.frame = frame; 44 | } 45 | 46 | -(CGFloat)ym_width 47 | { 48 | return self.frame.size.width; 49 | } 50 | 51 | -(void)setYm_height:(CGFloat)ym_height 52 | { 53 | CGRect frame = self.frame; 54 | frame.size.height = ym_height; 55 | self.frame = frame; 56 | } 57 | 58 | -(CGFloat)ym_height 59 | { 60 | return self.frame.size.height; 61 | } 62 | 63 | -(void)setYm_centerX:(CGFloat)ym_centerX 64 | { 65 | CGPoint tempP =self.center; 66 | tempP.x = ym_centerX; 67 | self.center = tempP; 68 | } 69 | 70 | -(CGFloat)ym_centerX 71 | { 72 | return self.center.x; 73 | } 74 | 75 | -(void)setYm_centerY:(CGFloat)ym_centerY 76 | { 77 | CGPoint tempP = self.center; 78 | tempP.y = ym_centerY; 79 | self.center = tempP; 80 | } 81 | 82 | -(CGFloat)ym_centerY 83 | { 84 | return self.center.y; 85 | } 86 | 87 | -(void)setYm_size:(CGSize)ym_size 88 | { 89 | CGRect frame = self.frame; 90 | frame.size = ym_size; 91 | self.frame = frame; 92 | } 93 | 94 | -(CGSize)ym_size 95 | { 96 | return self.frame.size; 97 | } 98 | 99 | 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /YMCitySelect/YMCityGroupsModel.h: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // YMCityGroupsModel.h 6 | // YMCitySelect 7 | // 8 | // Created by mac on 16/4/24. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import 13 | 14 | @interface YMCityGroupsModel : NSObject 15 | 16 | /** 城市数组*/ 17 | @property (nonatomic, strong) NSArray *cities; 18 | 19 | /** 分类标题*/ 20 | @property (nonatomic, copy) NSString *title; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /YMCitySelect/YMCityGroupsModel.m: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // YMCityGroupsModel.m 6 | // YMCitySelect 7 | // 8 | // Created by mac on 16/4/24. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import "YMCityGroupsModel.h" 13 | 14 | @implementation YMCityGroupsModel 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /YMCitySelect/YMCityModel.h: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // YMCityModel.h 6 | // YMCitySelect 7 | // 8 | // Created by mac on 16/4/25. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import 13 | 14 | @interface YMCityModel : NSObject 15 | 16 | @property (nonatomic, copy) NSString *name; 17 | 18 | @property (nonatomic, copy) NSString *pinYin; 19 | 20 | @property (nonatomic, copy) NSString *pinYinHead; 21 | 22 | @property (nonatomic, strong) NSArray *districts; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /YMCitySelect/YMCityModel.m: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // YMCityModel.m 6 | // YMCitySelect 7 | // 8 | // Created by mac on 16/4/25. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import "YMCityModel.h" 13 | 14 | @implementation YMCityModel 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /YMCitySelect/YMCitySearch.h: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // YMCitySearch.h 6 | // YMCitySelect 7 | // 8 | // Created by mac on 16/4/23. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import 13 | 14 | @interface YMCitySearch : UITableViewController 15 | /** 搜索文字*/ 16 | @property (nonatomic, copy) NSString *ym_searchText; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /YMCitySelect/YMCitySearch.m: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // YMCitySearch.m 6 | // YMCitySelect 7 | // 8 | // Created by mac on 16/4/23. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import "YMCitySearch.h" 13 | #import "YMCityModel.h" 14 | 15 | @interface YMCitySearch () 16 | 17 | @end 18 | 19 | @implementation YMCitySearch{ 20 | NSMutableArray *_ym_cityArray; 21 | NSMutableArray *_ym_resultArray; 22 | } 23 | 24 | - (void)viewDidLoad { 25 | [super viewDidLoad]; 26 | [self ym_setCitys]; 27 | _ym_resultArray = [NSMutableArray array]; 28 | } 29 | 30 | -(void)ym_setCitys{ 31 | NSString *path = [[NSBundle mainBundle] pathForResource:@"YMCitySelect.bundle/cities.plist" ofType:nil]; 32 | NSArray *tempArray = [NSArray arrayWithContentsOfFile:path]; 33 | _ym_cityArray = [NSMutableArray arrayWithCapacity:tempArray.count]; 34 | [tempArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 35 | YMCityModel *cityModel = [[YMCityModel alloc] init]; 36 | [cityModel setValuesForKeysWithDictionary:obj]; 37 | [_ym_cityArray addObject:cityModel]; 38 | }]; 39 | } 40 | 41 | -(void)setYm_searchText:(NSString *)ym_searchText{ 42 | _ym_searchText = ym_searchText; 43 | ym_searchText = [ym_searchText copy]; 44 | ym_searchText = ym_searchText.lowercaseString; 45 | [_ym_resultArray removeAllObjects]; 46 | for (YMCityModel *cityModel in _ym_cityArray) { 47 | if ([cityModel.name containsString:ym_searchText] || [cityModel.pinYin containsString:ym_searchText] || [cityModel.pinYinHead containsString:ym_searchText]) { 48 | [_ym_resultArray addObject:cityModel]; 49 | } 50 | } 51 | [self.tableView reloadData]; 52 | } 53 | 54 | #pragma mark - 数据源方法 55 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 56 | return _ym_resultArray.count; 57 | } 58 | 59 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 60 | static NSString *ID = @"ym_resultCitycell"; 61 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; 62 | if (cell == nil) { 63 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; 64 | } 65 | YMCityModel *cityModel = _ym_resultArray[indexPath.row]; 66 | cell.textLabel.text = cityModel.name; 67 | return cell; 68 | } 69 | 70 | - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 71 | { 72 | return [NSString stringWithFormat:@"有%zd个搜索结果",_ym_resultArray.count]; 73 | } 74 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 75 | { 76 | YMCityModel *cityModel = _ym_resultArray[indexPath.row]; 77 | [[NSNotificationCenter defaultCenter] postNotificationName:@"ym_searchCityResult" object:nil userInfo:@{@"ym_searchCityResultKey": cityModel.name}]; 78 | [self dismissViewControllerAnimated:YES completion:nil]; 79 | } 80 | 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /YMCitySelect/YMCitySelect.bundle/btn_navigation_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yiminfe/YMCitySelect/b411f2741237b30a01aff5cecc721b1e79e7a5af/YMCitySelect/YMCitySelect.bundle/btn_navigation_close.png -------------------------------------------------------------------------------- /YMCitySelect/YMCitySelect.bundle/btn_navigation_close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yiminfe/YMCitySelect/b411f2741237b30a01aff5cecc721b1e79e7a5af/YMCitySelect/YMCitySelect.bundle/btn_navigation_close@2x.png -------------------------------------------------------------------------------- /YMCitySelect/YMCitySelect.bundle/btn_navigation_close_hl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yiminfe/YMCitySelect/b411f2741237b30a01aff5cecc721b1e79e7a5af/YMCitySelect/YMCitySelect.bundle/btn_navigation_close_hl.png -------------------------------------------------------------------------------- /YMCitySelect/YMCitySelect.bundle/btn_navigation_close_hl@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yiminfe/YMCitySelect/b411f2741237b30a01aff5cecc721b1e79e7a5af/YMCitySelect/YMCitySelect.bundle/btn_navigation_close_hl@2x.png -------------------------------------------------------------------------------- /YMCitySelect/YMCitySelect.bundle/cityGroups.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | cities 7 | 8 | 北京 9 | 成都 10 | 广州 11 | 杭州 12 | 南京 13 | 上海 14 | 深圳 15 | 天津 16 | 武汉 17 | 西安 18 | 重庆 19 | 20 | title 21 | 热门 22 | 23 | 24 | cities 25 | 26 | 阿坝 27 | 阿克苏地区 28 | 阿拉善 29 | 阿勒泰地区 30 | 阿里 31 | 安康 32 | 安庆 33 | 鞍山 34 | 安顺 35 | 安阳 36 | 37 | title 38 | A 39 | 40 | 41 | cities 42 | 43 | 白城 44 | 百色 45 | 白山 46 | 白银 47 | 蚌埠 48 | 保定 49 | 宝鸡 50 | 保山 51 | 包头 52 | 巴彦淖尔 53 | 巴音郭楞 54 | 巴中 55 | 北海 56 | 北京 57 | 本溪 58 | 毕节地区 59 | 滨州 60 | 亳州 61 | 62 | title 63 | B 64 | 65 | 66 | cities 67 | 68 | 沧州 69 | 常德 70 | 昌吉州 71 | 常熟市 72 | 常州 73 | 朝阳 74 | 潮州 75 | 承德 76 | 成都 77 | 郴州 78 | 赤峰 79 | 池州 80 | 崇左 81 | 楚雄州 82 | 滁州 83 | 慈溪 84 | 85 | title 86 | C 87 | 88 | 89 | cities 90 | 91 | 大理 92 | 大连 93 | 丹东 94 | 儋州 95 | 大庆 96 | 大同 97 | 达州 98 | 德宏 99 | 德阳 100 | 德州 101 | 定西 102 | 迪庆 103 | 东莞 104 | 东营 105 | 106 | title 107 | D 108 | 109 | 110 | cities 111 | 112 | 鄂尔多斯 113 | 恩施州 114 | 鄂州 115 | 116 | title 117 | E 118 | 119 | 120 | cities 121 | 122 | 防城港 123 | 番禺 124 | 佛山 125 | 福清市 126 | 抚顺 127 | 阜新 128 | 阜阳 129 | 福州 130 | 抚州 131 | 132 | title 133 | F 134 | 135 | 136 | cities 137 | 138 | 赣州 139 | 甘孜州 140 | 广安 141 | 广元 142 | 广州 143 | 贵港 144 | 桂林 145 | 贵阳 146 | 147 | title 148 | G 149 | 150 | 151 | cities 152 | 153 | 哈尔滨 154 | 海口 155 | 海西 156 | 哈密地区 157 | 邯郸 158 | 杭州 159 | 汉中 160 | 鹤壁 161 | 河池 162 | 合肥 163 | 鹤岗 164 | 黑河 165 | 衡水 166 | 衡阳 167 | 和田地区 168 | 河源 169 | 菏泽 170 | 贺州 171 | 红河 172 | 淮安 173 | 淮北 174 | 怀化 175 | 淮南 176 | 黄岛 177 | 黄冈 178 | 黄山 179 | 黄石 180 | 呼和浩特 181 | 惠州 182 | 葫芦岛 183 | 呼伦贝尔 184 | 湖州 185 | 186 | title 187 | H 188 | 189 | 190 | cities 191 | 192 | 佳木斯 193 | 吉安 194 | 江门 195 | 江阴 196 | 焦作 197 | 嘉兴 198 | 嘉峪关 199 | 揭阳 200 | 吉林 201 | 济南 202 | 晋城 203 | 景德镇 204 | 荆门 205 | 荆州 206 | 金华 207 | 济宁 208 | 晋江 209 | 晋中 210 | 锦州 211 | 九江 212 | 酒泉 213 | 鸡西 214 | 济源 215 | 216 | title 217 | J 218 | 219 | 220 | cities 221 | 222 | 开封 223 | 喀什地区 224 | 克拉玛依 225 | 昆明 226 | 昆山 227 | 228 | title 229 | K 230 | 231 | 232 | cities 233 | 234 | 来宾 235 | 莱芜 236 | 廊坊 237 | 兰州 238 | 拉萨 239 | 乐山 240 | 凉山 241 | 连云港 242 | 聊城 243 | 辽阳 244 | 辽源 245 | 丽江 246 | 临沧 247 | 临汾 248 | 陵水 249 | 临沂 250 | 丽水 251 | 六安 252 | 六盘水 253 | 柳州 254 | 溧阳市 255 | 陇南 256 | 龙岩 257 | 娄底 258 | 漯河 259 | 洛阳 260 | 泸州 261 | 吕梁 262 | 263 | title 264 | L 265 | 266 | 267 | cities 268 | 269 | 马鞍山 270 | 茂名 271 | 眉山 272 | 梅州 273 | 绵阳 274 | 牡丹江 275 | 276 | title 277 | M 278 | 279 | 280 | cities 281 | 282 | 南昌 283 | 南充 284 | 南京 285 | 南宁 286 | 南平 287 | 南通 288 | 南阳 289 | 内江 290 | 宁波 291 | 宁德 292 | 293 | title 294 | N 295 | 296 | 297 | cities 298 | 299 | 盘锦 300 | 攀枝花 301 | 平顶山 302 | 平凉 303 | 萍乡 304 | 普洱 305 | 莆田 306 | 濮阳 307 | 308 | title 309 | P 310 | 311 | 312 | cities 313 | 314 | 黔东南 315 | 潜江 316 | 黔南 317 | 黔西南 318 | 青岛 319 | 庆阳 320 | 清远 321 | 秦皇岛 322 | 钦州 323 | 琼海 324 | 齐齐哈尔 325 | 七台河 326 | 泉州 327 | 曲靖 328 | 衢州 329 | 330 | title 331 | Q 332 | 333 | 334 | cities 335 | 336 | 日照 337 | 338 | title 339 | R 340 | 341 | 342 | cities 343 | 344 | 三门峡 345 | 三明 346 | 三亚 347 | 厦门 348 | 上海 349 | 商洛 350 | 商丘 351 | 上饶 352 | 汕头 353 | 汕尾 354 | 韶关 355 | 绍兴 356 | 邵阳 357 | 沈阳 358 | 深圳 359 | 石河子 360 | 石家庄 361 | 十堰 362 | 石嘴山 363 | 双鸭山 364 | 朔州 365 | 四平 366 | 松原 367 | 绥化 368 | 遂宁 369 | 随州 370 | 宿迁 371 | 苏州 372 | 宿州 373 | 374 | title 375 | S 376 | 377 | 378 | cities 379 | 380 | 塔城地区 381 | 泰安 382 | 太仓市 383 | 台山市 384 | 太原 385 | 泰州 386 | 台州 387 | 唐山 388 | 天津 389 | 天门 390 | 天水 391 | 铁岭 392 | 铜川 393 | 通化 394 | 通辽 395 | 铜陵 396 | 铜仁地区 397 | 398 | title 399 | T 400 | 401 | 402 | cities 403 | 404 | 万宁 405 | 潍坊 406 | 威海 407 | 渭南 408 | 文昌 409 | 文山州 410 | 温州 411 | 乌海 412 | 武汉 413 | 芜湖 414 | 吴江 415 | 乌兰察布 416 | 乌鲁木齐 417 | 武威 418 | 无锡 419 | 吴忠 420 | 梧州 421 | 422 | title 423 | W 424 | 425 | 426 | cities 427 | 428 | 西安 429 | 香港 430 | 湘潭 431 | 湘西 432 | 襄阳 433 | 咸宁 434 | 仙桃 435 | 咸阳 436 | 孝感 437 | 锡林郭勒 438 | 兴安盟 439 | 邢台 440 | 西宁 441 | 新乡 442 | 信阳 443 | 新余 444 | 忻州 445 | 西双版纳 446 | 宣城 447 | 许昌 448 | 徐州 449 | 450 | title 451 | X 452 | 453 | 454 | cities 455 | 456 | 雅安 457 | 延安 458 | 延边 459 | 盐城 460 | 阳江 461 | 阳泉 462 | 扬州 463 | 烟台 464 | 宜宾 465 | 宜昌 466 | 伊春 467 | 宜春 468 | 伊犁 469 | 银川 470 | 营口 471 | 鹰潭 472 | 义乌 473 | 宜兴 474 | 益阳 475 | 永州 476 | 岳阳 477 | 玉林 478 | 榆林 479 | 运城 480 | 云浮 481 | 玉溪 482 | 余姚市 483 | 484 | title 485 | Y 486 | 487 | 488 | cities 489 | 490 | 枣庄 491 | 长春 492 | 张家港市 493 | 张家界 494 | 张家口 495 | 章丘市 496 | 长沙 497 | 张掖 498 | 长治 499 | 漳州 500 | 湛江 501 | 肇庆 502 | 昭通 503 | 郑州 504 | 镇江 505 | 重庆 506 | 中山 507 | 中卫 508 | 周口 509 | 舟山 510 | 珠海 511 | 驻马店 512 | 株洲 513 | 淄博 514 | 自贡 515 | 资阳 516 | 遵义 517 | 518 | title 519 | Z 520 | 521 | 522 | 523 | -------------------------------------------------------------------------------- /YMCitySelect/YMCitySelect.h: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // YMCitySelect.h 6 | // YMCitySelect 7 | // 8 | // Created by mac on 16/4/23. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | #import 12 | 13 | @protocol YMCitySelectDelegate 14 | 15 | - (void)ym_ymCitySelectCityName:(NSString *)cityName; 16 | 17 | @end 18 | 19 | @interface YMCitySelect : UIViewController 20 | 21 | -(instancetype)initWithDelegate:(id)targe; 22 | 23 | @property (nonatomic,weak) id ymDelegate; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /YMCitySelect/YMCitySelect.m: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // YMCitySelect.m 6 | // YMCitySelect 7 | // 8 | // Created by mac on 16/4/23. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import "YMCitySelect.h" 13 | #import "YMCitySearch.h" 14 | #import "YMSearchBar.h" 15 | #import "UIView+ym_extension.h" 16 | #import "YMCityGroupsModel.h" 17 | #import "YMTableViewCell.h" 18 | #import 19 | 20 | @interface YMCitySelect () 21 | @property (nonatomic,strong) NSMutableArray *ym_cityNames; 22 | @property (nonatomic,strong) YMCitySearch *ym_citySearch; 23 | 24 | @end 25 | 26 | @implementation YMCitySelect{ 27 | YMSearchBar *_ym_searchBar; 28 | UITableView *_ym_tableView; 29 | UIButton *_ym_cover; 30 | UILabel *_ym_selectCity; 31 | UIView *_ym_navView; 32 | NSMutableArray *_ym_ctiyGroups; 33 | NSUserDefaults *_ym_userDefaults; 34 | CLLocationManager *_ym_locationManager; 35 | UIButton *_ym_locationCityName; 36 | NSMutableArray *_ym_locationcityArry; 37 | } 38 | 39 | static NSString *reuseIdentifier = @"ym_cellTwo"; 40 | 41 | -(NSMutableArray *)ym_cityNames{ 42 | if (!_ym_cityNames) { 43 | _ym_cityNames = [NSMutableArray array]; 44 | } 45 | return _ym_cityNames; 46 | } 47 | 48 | -(YMCitySearch *)ym_citySearch{ 49 | if (!_ym_citySearch) { 50 | YMCitySearch *ym_citySearchCtrl = [YMCitySearch new]; 51 | [self addChildViewController:ym_citySearchCtrl]; 52 | [self.view addSubview:ym_citySearchCtrl.view]; 53 | ym_citySearchCtrl.view.frame = CGRectMake(0, 64, self.view.ym_width, self.view.ym_height - 64); 54 | _ym_citySearch = ym_citySearchCtrl; 55 | } 56 | return _ym_citySearch; 57 | } 58 | 59 | -(instancetype)initWithDelegate:(id)targe{ 60 | self = [super init]; 61 | if (self) { 62 | self.ymDelegate = targe; 63 | } 64 | return self; 65 | } 66 | 67 | - (void)viewDidLoad { 68 | [super viewDidLoad]; 69 | self.view.backgroundColor = [UIColor whiteColor]; 70 | [self ym_setSearchBar]; 71 | [self ym_setNavView]; 72 | [self ym_setCityGroups]; 73 | [self ym_setCityNames]; 74 | [self ym_setTableView]; 75 | [self ym_setLocationManager]; 76 | [self ym_setcationCityName]; 77 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ym_setLocationManager) name:@"ym_updateLocation" object:nil]; 78 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ym_setSearchCityResult:) name:@"ym_searchCityResult" object:nil]; 79 | } 80 | 81 | -(void)ym_setSearchBar{ 82 | _ym_searchBar = [[YMSearchBar alloc] initWithFrame:CGRectMake(0, 44, self.view.ym_width, 64)]; 83 | _ym_searchBar.placeholder = @"请输入城市名/拼音/首字母拼音"; 84 | _ym_searchBar.delegate = self; 85 | [self.view addSubview:_ym_searchBar]; 86 | } 87 | 88 | -(void)ym_setNavView{ 89 | _ym_navView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 64)]; 90 | _ym_navView.backgroundColor = [UIColor colorWithRed:247.0/255.0 green:247.0/255.0 blue:247.0/255.0 alpha:1.0]; 91 | UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 63.5, _ym_navView.ym_width, 0.5)]; 92 | lineView.backgroundColor = [UIColor colorWithRed:171.0/255.0 green:172.0/255.0 blue:171.0/255.0 alpha:1.0]; 93 | [_ym_navView addSubview:lineView]; 94 | UIButton *closeBtn = [[UIButton alloc] init]; 95 | [closeBtn setImage:[UIImage imageNamed:@"YMCitySelect.bundle/btn_navigation_close_hl"] forState:UIControlStateNormal]; 96 | [closeBtn setImage:[UIImage imageNamed:@"YMCitySelect.bundle/btn_navigation_close"] forState:UIControlStateHighlighted]; 97 | [closeBtn addTarget:self action:@selector(closeBtnClick) forControlEvents:UIControlEventTouchUpInside]; 98 | [closeBtn sizeToFit]; 99 | closeBtn.ym_x = 5; 100 | closeBtn.ym_centerY = _ym_navView.ym_centerY + 10; 101 | [_ym_navView addSubview:closeBtn]; 102 | _ym_selectCity = [[UILabel alloc] init]; 103 | _ym_selectCity.text = @"选择城市"; 104 | _ym_selectCity.font = [UIFont fontWithName:@"HelVetica-Bold" size:16]; 105 | _ym_selectCity.textColor = [UIColor blackColor]; 106 | [_ym_selectCity sizeToFit]; 107 | _ym_selectCity.ym_centerX = _ym_navView.ym_centerX; 108 | _ym_selectCity.ym_centerY = _ym_navView.ym_centerY + 10; 109 | [_ym_navView addSubview:_ym_selectCity]; 110 | [self.view addSubview:_ym_navView]; 111 | } 112 | 113 | -(void)closeBtnClick{ 114 | [self dismissViewControllerAnimated:YES completion:nil]; 115 | } 116 | 117 | -(void)ym_setCityGroups{ 118 | NSString *path = [[NSBundle mainBundle] pathForResource:@"YMCitySelect.bundle/cityGroups.plist" ofType:nil]; 119 | NSArray *tempArray = [NSArray arrayWithContentsOfFile:path]; 120 | _ym_ctiyGroups = [NSMutableArray arrayWithCapacity:tempArray.count]; 121 | [tempArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 122 | YMCityGroupsModel *cityGroupModel = [[YMCityGroupsModel alloc] init]; 123 | [cityGroupModel setValuesForKeysWithDictionary:obj]; 124 | [_ym_ctiyGroups addObject:cityGroupModel]; 125 | }]; 126 | } 127 | -(void)ym_setCityNames{ 128 | [self setUpCityNames]; 129 | if (self.ym_cityNames.count) { 130 | YMCityGroupsModel *ymcityGroupsModel = [[YMCityGroupsModel alloc] init]; 131 | ymcityGroupsModel.title = @"最近"; 132 | ymcityGroupsModel.cities = self.ym_cityNames; 133 | _ym_selectCity.text = [NSString stringWithFormat:@"当前城市-%@",ymcityGroupsModel.cities[0]]; 134 | [_ym_selectCity sizeToFit]; 135 | _ym_selectCity.ym_centerX = _ym_navView.ym_centerX; 136 | for (YMCityGroupsModel *tempModel in _ym_ctiyGroups) { 137 | if ([tempModel.title isEqualToString: ymcityGroupsModel.title]) { 138 | tempModel.cities = ymcityGroupsModel.cities; 139 | return; 140 | } 141 | } 142 | if (_ym_locationcityArry) { 143 | [_ym_ctiyGroups insertObject:ymcityGroupsModel atIndex:1]; 144 | }else{ 145 | [_ym_ctiyGroups insertObject:ymcityGroupsModel atIndex:0]; 146 | } 147 | } 148 | } 149 | 150 | -(void)ym_setTableView{ 151 | _ym_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(_ym_searchBar.frame), self.view.ym_width, self.view.ym_height - CGRectGetMaxY(_ym_searchBar.frame))]; 152 | _ym_tableView.delegate = self; 153 | _ym_tableView.dataSource = self; 154 | _ym_tableView.tintColor = [UIColor blackColor]; 155 | [_ym_tableView registerClass:[YMTableViewCell class] forCellReuseIdentifier:reuseIdentifier]; 156 | [self.view addSubview:_ym_tableView]; 157 | if([_ym_tableView respondsToSelector:@selector(setSectionIndexColor:)]) { 158 | _ym_tableView.sectionIndexBackgroundColor = [UIColor clearColor]; 159 | _ym_tableView.sectionIndexTrackingBackgroundColor = [UIColor clearColor]; 160 | } 161 | } 162 | 163 | -(void)ym_setLocationManager{ 164 | _ym_locationManager = [CLLocationManager new]; 165 | if ([_ym_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { 166 | [_ym_locationManager requestWhenInUseAuthorization]; 167 | } 168 | _ym_locationManager.delegate = self; 169 | [_ym_locationManager startUpdatingLocation]; 170 | } 171 | 172 | -(void)ym_setcationCityName{ 173 | YMCityGroupsModel *ymcityGroupsModel = [[YMCityGroupsModel alloc] init]; 174 | ymcityGroupsModel.title = @"定位"; 175 | _ym_locationcityArry = [NSMutableArray array]; 176 | [_ym_locationcityArry addObject:@"正在定位中..."]; 177 | ymcityGroupsModel.cities = _ym_locationcityArry; 178 | [_ym_ctiyGroups insertObject:ymcityGroupsModel atIndex:0]; 179 | } 180 | 181 | - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar 182 | { 183 | if (_ym_cover) { 184 | _ym_cover.alpha = 0; 185 | } 186 | [self ym_setCover]; 187 | [UIView animateWithDuration:0.5 animations:^{ 188 | _ym_navView.ym_y = -64; 189 | _ym_searchBar.ym_y = 0; 190 | _ym_tableView.ym_y = 64; 191 | _ym_tableView.ym_height = self.view.ym_height - 64; 192 | _ym_cover.frame = _ym_tableView.frame; 193 | [_ym_searchBar setShowsCancelButton:YES animated:YES]; 194 | 195 | } completion:^(BOOL finished) { 196 | _ym_navView.hidden = YES; 197 | }]; 198 | } 199 | 200 | -(void)ym_setCover{ 201 | if (!_ym_cover) { 202 | _ym_cover = [[UIButton alloc] init]; 203 | _ym_cover.backgroundColor = [UIColor blackColor]; 204 | [_ym_cover addTarget:self action:@selector(ym_coverClick) forControlEvents:UIControlEventTouchUpInside]; 205 | _ym_cover.frame = _ym_tableView.frame; 206 | [self.view addSubview:_ym_cover]; 207 | } 208 | _ym_cover.hidden = NO; 209 | _ym_cover.alpha = 0.5; 210 | } 211 | 212 | -(void)ym_coverClick{ 213 | [self ym_cancelBtnClick]; 214 | } 215 | 216 | #pragma mark searchBar取消按钮调用 217 | - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar 218 | { 219 | searchBar.text = nil; 220 | self.ym_citySearch.view.hidden = YES; 221 | [self ym_cancelBtnClick]; 222 | } 223 | 224 | -(void)ym_cancelBtnClick{ 225 | _ym_navView.hidden = NO; 226 | [UIView animateWithDuration:0.5 animations:^{ 227 | _ym_cover.hidden = YES; 228 | _ym_navView.ym_y = 0; 229 | _ym_searchBar.ym_y = 44; 230 | [_ym_searchBar setShowsCancelButton:NO animated:YES]; 231 | _ym_tableView.ym_y = CGRectGetMaxY(_ym_searchBar.frame); 232 | _ym_tableView.ym_height = self.view.ym_height - _ym_tableView.ym_y; 233 | _ym_cover.frame = _ym_tableView.frame; 234 | }completion:^(BOOL finished) { 235 | _ym_cover.hidden = YES; 236 | }]; 237 | [_ym_searchBar resignFirstResponder]; 238 | } 239 | 240 | #pragma mark searchBar编辑的时候调用 241 | - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 242 | { 243 | if (searchText.length) { 244 | self.ym_citySearch.view.hidden = NO; 245 | self.ym_citySearch.ym_searchText = searchText; 246 | } else { 247 | self.ym_citySearch.view.hidden = YES; 248 | } 249 | } 250 | 251 | #pragma mark - UITableView的数据源方法 252 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 253 | { 254 | return _ym_ctiyGroups.count; 255 | } 256 | 257 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 258 | YMCityGroupsModel *cityGroupModel = _ym_ctiyGroups[section]; 259 | if (cityGroupModel.title.length > 1) { 260 | return 1; 261 | } 262 | return cityGroupModel.cities.count; 263 | 264 | } 265 | 266 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 267 | static NSString *ID = @"ym_cell"; 268 | YMCityGroupsModel *cityGroupModel = _ym_ctiyGroups[indexPath.section]; 269 | UITableViewCell *cell; 270 | if (cityGroupModel.title.length> 1) { 271 | YMTableViewCell *ym_cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; 272 | ym_cell.citys = cityGroupModel.cities; 273 | ym_cell.ym_cellHeight = [self ym_setcellHeightForRowAtIndexPath:indexPath]; 274 | ym_cell.ym_cellDelegate = self; 275 | return ym_cell; 276 | }else{ 277 | cell = [tableView dequeueReusableCellWithIdentifier:ID]; 278 | if (cell == nil) { 279 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; 280 | } 281 | cell.textLabel.text = cityGroupModel.cities[indexPath.row]; 282 | } 283 | return cell; 284 | } 285 | 286 | - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 287 | { 288 | YMCityGroupsModel *model = _ym_ctiyGroups[section]; 289 | return model.title; 290 | } 291 | 292 | - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{ 293 | return [_ym_ctiyGroups valueForKeyPath:@"title"]; 294 | } 295 | 296 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ 297 | UIView *ym_view = [[UIView alloc] init]; 298 | ym_view.backgroundColor = [UIColor colorWithRed:229/255.0 green:229/255.0 blue:229/255.0 alpha:1.0]; 299 | UILabel *ym_label = [[UILabel alloc] init]; 300 | ym_label.textAlignment = NSTextAlignmentLeft; 301 | ym_label.textColor = [UIColor blackColor]; 302 | ym_label.font = [UIFont systemFontOfSize:16]; 303 | YMCityGroupsModel *cityGroupModel = _ym_ctiyGroups[section]; 304 | NSString *ym_title = cityGroupModel.title; 305 | if ([cityGroupModel.title isEqualToString:@"热门"]) { 306 | ym_title = @"中国热门城市"; 307 | } 308 | if ([cityGroupModel.title isEqualToString:@"最近"]) { 309 | ym_title = @"最近选择过的城市"; 310 | } 311 | if ([cityGroupModel.title isEqualToString:@"定位"]) { 312 | ym_title = @"定位的城市"; 313 | } 314 | ym_label.text = ym_title; 315 | [ym_label sizeToFit]; 316 | ym_label.ym_x = 10; 317 | ym_label.ym_y = 5; 318 | [ym_view addSubview:ym_label]; 319 | return ym_view; 320 | } 321 | 322 | #pragma mark - 选中cell 323 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 324 | { 325 | YMCityGroupsModel *model = _ym_ctiyGroups[indexPath.section]; 326 | NSString *cityName = model.cities[indexPath.row]; 327 | [self ym_setSelectCityName:cityName]; 328 | } 329 | 330 | #pragma mark YMTableViewCell自定义的代理方法 331 | -(void)ymcollectionView:(UICollectionView *)collectionView didSelectItemAtCityName:(NSString *)cityName{ 332 | [self ym_setSelectCityName:cityName]; 333 | } 334 | 335 | #pragma mark 搜索城市的结果返回 336 | -(void)ym_setSearchCityResult:(NSNotification *)noti{ 337 | NSString *cityName = noti.userInfo[@"ym_searchCityResultKey"]; 338 | [self ym_setSelectCityName:cityName]; 339 | } 340 | 341 | #pragma mark 保存最近城市逻辑判断 342 | -(void)ym_setSelectCityName:(NSString *)cityName{ 343 | if ([self.ymDelegate respondsToSelector:@selector(ym_ymCitySelectCityName:)]) { 344 | [self.ymDelegate ym_ymCitySelectCityName:cityName]; 345 | } 346 | NSMutableArray *tempCityNames = [NSMutableArray array]; 347 | for (NSString *tempCityName in self.ym_cityNames) { 348 | if ([tempCityName isEqualToString:cityName]) { 349 | [tempCityNames addObject:tempCityName]; 350 | } 351 | } 352 | [self.ym_cityNames removeObjectsInArray:tempCityNames]; 353 | if (self.ym_cityNames.count == 3) { 354 | [self.ym_cityNames removeLastObject]; 355 | } 356 | [self.ym_cityNames insertObject:cityName atIndex:0]; 357 | [self addSaveCityNames]; 358 | if (!_ym_citySearch) { 359 | [self dismissViewControllerAnimated:YES completion:nil]; 360 | } 361 | } 362 | 363 | 364 | #pragma mark - UITableView的代理方法 365 | -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 366 | return [self ym_setcellHeightForRowAtIndexPath:indexPath]; 367 | } 368 | 369 | -(CGFloat)ym_setcellHeightForRowAtIndexPath:(NSIndexPath *)indexPath{ 370 | CGFloat ym_height = 44; 371 | YMCityGroupsModel *cityGroupModel = _ym_ctiyGroups[indexPath.section]; 372 | CGFloat ym_w = ([UIScreen mainScreen].bounds.size.width - 72) / 3; 373 | CGFloat ym_h = ym_w / 3; 374 | if (cityGroupModel.title.length > 1) { 375 | NSInteger count = cityGroupModel.cities.count; 376 | ym_height = (count / 3 + (count % 3 == 0?0:1)) * (ym_h + 15) + 15; 377 | } 378 | return ym_height; 379 | } 380 | 381 | #pragma mark - 保存最近城市到偏好设置 382 | -(void)addSaveCityNames{ 383 | [_ym_userDefaults setObject:_ym_cityNames forKey:@"ym_cityNames"]; 384 | [_ym_userDefaults synchronize]; 385 | [self ym_setCityNames]; 386 | [_ym_tableView reloadData]; 387 | } 388 | 389 | #pragma mark 获取最近城市 390 | -(void)setUpCityNames{ 391 | if (!_ym_userDefaults) { 392 | _ym_userDefaults = [NSUserDefaults standardUserDefaults]; 393 | } 394 | self.ym_cityNames = [[_ym_userDefaults objectForKey:@"ym_cityNames"] mutableCopy]; 395 | } 396 | 397 | #pragma mark 城市定位 398 | - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 399 | { 400 | CLLocation *ym_location =[locations firstObject]; 401 | [_ym_locationManager stopUpdatingLocation]; 402 | CLGeocoder *geocoder = [CLGeocoder new]; 403 | CLLocation *location = [[CLLocation alloc] initWithLatitude:ym_location.coordinate.latitude longitude:ym_location.coordinate.longitude]; 404 | [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray * _Nullable placemarks, NSError * _Nullable error) { 405 | if (placemarks.count == 0 || error) { 406 | _ym_locationcityArry[0] = @"定位失败,请点击重试"; 407 | } 408 | else{ 409 | CLPlacemark *placemark = placemarks.lastObject; 410 | if (placemark.locality) { 411 | NSString * cityName = [placemark.locality substringWithRange:NSMakeRange(0, [placemark.locality length] - 1)]; 412 | _ym_locationcityArry[0] = cityName; 413 | [[NSNotificationCenter defaultCenter] postNotificationName:@"ym_locationReloadData" object:nil]; 414 | } 415 | } 416 | [[NSNotificationCenter defaultCenter] postNotificationName:@"ym_locationReloadData" object:nil]; 417 | }]; 418 | 419 | } 420 | 421 | @end 422 | -------------------------------------------------------------------------------- /YMCitySelect/YMCollectionViewCell.h: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // YMCollectionViewCell.h 6 | // YMCitySelect 7 | // 8 | // Created by mac on 16/4/24. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import 13 | 14 | @interface YMCollectionViewCell : UICollectionViewCell 15 | 16 | @property (nonatomic,copy) NSString *cityName; 17 | 18 | @property (nonatomic,assign) CGFloat ym_cellWidth; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /YMCitySelect/YMCollectionViewCell.m: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // YMCollectionViewCell.m 6 | // YMCitySelect 7 | // 8 | // Created by mac on 16/4/24. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import "YMCollectionViewCell.h" 13 | #import "UIView+ym_extension.h" 14 | 15 | @implementation YMCollectionViewCell{ 16 | UILabel *_ym_cityLabel; 17 | } 18 | 19 | - (instancetype)initWithFrame:(CGRect)frame 20 | { 21 | self = [super initWithFrame:frame]; 22 | if (self) { 23 | self.backgroundColor = [UIColor whiteColor]; 24 | _ym_cityLabel = [[UILabel alloc] init]; 25 | _ym_cityLabel.textColor = [UIColor blackColor]; 26 | [self.contentView addSubview:_ym_cityLabel]; 27 | } 28 | return self; 29 | } 30 | 31 | -(void)setCityName:(NSString *)cityName{ 32 | _cityName = cityName; 33 | _ym_cityLabel.text = cityName; 34 | [_ym_cityLabel sizeToFit]; 35 | if (_ym_cityLabel.ym_width > self.ym_width) { 36 | self.contentView.ym_width = _ym_cityLabel.ym_width; 37 | self.ym_width = _ym_cityLabel.ym_width; 38 | } 39 | _ym_cityLabel.center = self.contentView.center; 40 | } 41 | 42 | -(void)setYm_cellWidth:(CGFloat)ym_cellWidth{ 43 | _ym_cellWidth = ym_cellWidth; 44 | self.contentView.ym_width = ym_cellWidth; 45 | self.ym_width = _ym_cellWidth; 46 | _ym_cityLabel.center = self.contentView.center; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /YMCitySelect/YMSearchBar.h: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // YMSearchBar.h 6 | // YMCitySelect 7 | // 8 | // Created by mac on 16/4/24. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import 13 | 14 | @interface YMSearchBar : UISearchBar 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /YMCitySelect/YMSearchBar.m: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // YMSearchBar.m 6 | // YMCitySelect 7 | // 8 | // Created by mac on 16/4/24. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import "YMSearchBar.h" 13 | #import "UIView+ym_extension.h" 14 | 15 | @implementation YMSearchBar 16 | 17 | -(void)layoutSubviews{ 18 | [super layoutSubviews]; 19 | for (UIView *view in self.subviews) { 20 | for (UIView *tempView in view.subviews) { 21 | if ([tempView isKindOfClass:NSClassFromString(@"UISearchBarTextField")]) { 22 | tempView.ym_y = 28; 23 | } 24 | if ([tempView isKindOfClass:NSClassFromString(@"UINavigationButton")]) { 25 | UIButton *ym_btn = (UIButton *)tempView; 26 | [ym_btn setTitle:@"取消" forState:UIControlStateNormal]; 27 | [ym_btn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal]; 28 | ym_btn.ym_y = 26; 29 | } 30 | } 31 | } 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /YMCitySelect/YMTableViewCell.h: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // YMTableViewCell.h 6 | // YMCitySelect 7 | // 8 | // Created by mac on 16/4/24. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import 13 | 14 | @protocol YMTableViewCellDelegate 15 | 16 | -(void)ymcollectionView:(UICollectionView *)collectionView didSelectItemAtCityName:(NSString *)cityName; 17 | 18 | @end 19 | 20 | @interface YMTableViewCell : UITableViewCell 21 | 22 | @property (nonatomic,strong) NSArray *citys; 23 | 24 | @property (nonatomic,assign) CGFloat ym_cellHeight; 25 | 26 | @property (nonatomic,weak) id ym_cellDelegate; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /YMCitySelect/YMTableViewCell.m: -------------------------------------------------------------------------------- 1 | //代码地址:https://github.com/iosdeveloperSVIP/YMCitySelect 2 | //原创:iosdeveloper赵依民 3 | //邮箱:iosdeveloper@vip.163.com 4 | // 5 | // YMTableViewCell.m 6 | // YMCitySelect 7 | // 8 | // Created by mac on 16/4/24. 9 | // Copyright © 2016年 YiMin. All rights reserved. 10 | // 11 | 12 | #import "YMTableViewCell.h" 13 | #import "UIView+ym_extension.h" 14 | #import "YMCollectionViewCell.h" 15 | 16 | @interface YMTableViewCell() 17 | 18 | @end 19 | 20 | @implementation YMTableViewCell{ 21 | UICollectionView *_ym_collectionView; 22 | CGFloat ym_w; 23 | } 24 | 25 | static NSString *identifier = @"ym_collectionViewCell"; 26 | 27 | -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ 28 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 29 | if (self) { 30 | self.ym_width = [UIScreen mainScreen].bounds.size.width; 31 | self.selectionStyle = UITableViewCellSelectionStyleBlue; 32 | self.backgroundColor =[UIColor colorWithRed:243/255.0 green:243/255.0 blue:243/255.0 alpha:1.0]; 33 | UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; 34 | ym_w = ([UIScreen mainScreen].bounds.size.width - 72) / 3; 35 | CGFloat ym_h = ym_w / 3; 36 | layout.itemSize = CGSizeMake(ym_w, ym_h); 37 | layout.sectionInset = UIEdgeInsetsMake(15, 15, 0, 0); 38 | layout.minimumLineSpacing = 15; 39 | _ym_collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.ym_width - 27, self.ym_height) collectionViewLayout:layout]; 40 | [_ym_collectionView registerClass:[YMCollectionViewCell 41 | class] forCellWithReuseIdentifier:identifier]; 42 | _ym_collectionView.delegate = self; 43 | _ym_collectionView.dataSource = self; 44 | _ym_collectionView.backgroundColor = [UIColor colorWithRed:243/255.0 green:243/255.0 blue:243/255.0 alpha:1.0]; 45 | _ym_collectionView.scrollEnabled = NO; 46 | [self.contentView addSubview:_ym_collectionView]; 47 | self.layer.shouldRasterize = YES; 48 | self.layer.rasterizationScale = [UIScreen mainScreen].scale; 49 | self.layer.drawsAsynchronously = YES; 50 | //注册通知 51 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ym_setReloadData) name:@"ym_locationReloadData" object:nil]; 52 | } 53 | return self; 54 | } 55 | 56 | -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ 57 | return self.citys.count; 58 | } 59 | 60 | -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ 61 | YMCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; 62 | cell.cityName = self.citys[indexPath.item]; 63 | return cell; 64 | } 65 | 66 | -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ 67 | NSString *cityName = self.citys[indexPath.item]; 68 | if ([cityName isEqualToString:@"定位失败,请点击重试"]) { 69 | [[NSNotificationCenter defaultCenter] postNotificationName:@"ym_updateLocation" object:nil]; 70 | YMCollectionViewCell *cell = (YMCollectionViewCell *)[_ym_collectionView cellForItemAtIndexPath:indexPath]; 71 | cell.cityName = @"正在定位中..."; 72 | cell.ym_cellWidth = ym_w; 73 | return; 74 | } 75 | if ([cityName isEqualToString:@"正在定位中..."]) { 76 | return; 77 | } 78 | if ([self.ym_cellDelegate respondsToSelector:@selector(ymcollectionView:didSelectItemAtCityName:)]) { 79 | [self.ym_cellDelegate ymcollectionView:collectionView didSelectItemAtCityName:cityName]; 80 | } 81 | } 82 | 83 | -(void)setCitys:(NSArray *)citys{ 84 | _citys = citys; 85 | [_ym_collectionView reloadData]; 86 | } 87 | 88 | -(void)setYm_cellHeight:(CGFloat)ym_cellHeight{ 89 | _ym_cellHeight = ym_cellHeight; 90 | _ym_collectionView.ym_height = _ym_cellHeight; 91 | } 92 | 93 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 94 | [super setSelected:selected animated:animated]; 95 | // Configure the view for the selected state 96 | } 97 | 98 | 99 | - (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath{ 100 | return YES; 101 | } 102 | - (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath{ 103 | UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; 104 | cell.backgroundColor = [UIColor lightGrayColor]; 105 | } 106 | - (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath{ 107 | UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; 108 | cell.backgroundColor = [UIColor whiteColor]; 109 | } 110 | 111 | -(void)ym_setReloadData{ 112 | NSIndexPath *index = [NSIndexPath indexPathForRow:0 inSection:0]; 113 | YMCollectionViewCell *cell = (YMCollectionViewCell *)[_ym_collectionView cellForItemAtIndexPath:index]; 114 | cell.cityName = self.citys[index.row]; 115 | if (![self.citys[index.row] isEqualToString:@"定位失败,请点击重试"]) { 116 | cell.ym_cellWidth = ym_w; 117 | } 118 | } 119 | 120 | @end 121 | -------------------------------------------------------------------------------- /YMCitySelectExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // YMCitySelect 4 | // 5 | // Created by mac on 16/4/23. 6 | // Copyright © 2016年 YiMin. 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 | -------------------------------------------------------------------------------- /YMCitySelectExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // YMCitySelect 4 | // 5 | // Created by mac on 16/4/23. 6 | // Copyright © 2016年 YiMin. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "YMViewController.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 21 | UINavigationController *nav =[[UINavigationController alloc] initWithRootViewController:[YMViewController new]]; 22 | self.window.rootViewController = nav; 23 | [self.window makeKeyAndVisible]; 24 | return YES; 25 | } 26 | 27 | - (void)applicationWillResignActive:(UIApplication *)application { 28 | // 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. 29 | // 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. 30 | } 31 | 32 | - (void)applicationDidEnterBackground:(UIApplication *)application { 33 | // 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. 34 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 35 | } 36 | 37 | - (void)applicationWillEnterForeground:(UIApplication *)application { 38 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 39 | } 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | - (void)applicationWillTerminate:(UIApplication *)application { 46 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /YMCitySelectExample/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 | } -------------------------------------------------------------------------------- /YMCitySelectExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /YMCitySelectExample/Assets.xcassets/ym_iosdeveloper.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ym_iosdeveloper.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /YMCitySelectExample/Assets.xcassets/ym_iosdeveloper.imageset/ym_iosdeveloper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yiminfe/YMCitySelect/b411f2741237b30a01aff5cecc721b1e79e7a5af/YMCitySelectExample/Assets.xcassets/ym_iosdeveloper.imageset/ym_iosdeveloper.jpg -------------------------------------------------------------------------------- /YMCitySelectExample/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 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /YMCitySelectExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSLocationWhenInUseUsageDescription 6 | 授权时添加 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /YMCitySelectExample/YMViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // YMViewController.h 3 | // YMCitySelect 4 | // 5 | // Created by mac on 16/4/23. 6 | // Copyright © 2016年 YiMin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface YMViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /YMCitySelectExample/YMViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // YMViewController.m 3 | // YMCitySelect 4 | // 5 | // Created by mac on 16/4/23. 6 | // Copyright © 2016年 YiMin. All rights reserved. 7 | // 8 | 9 | #import "YMViewController.h" 10 | #import "YMCitySelect.h" 11 | #import "UIView+ym_extension.h" 12 | 13 | @interface YMViewController () 14 | 15 | @end 16 | 17 | @implementation YMViewController{ 18 | UILabel *_cityLabel; 19 | } 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | self.title = @"选择城市"; 24 | self.view.backgroundColor = [UIColor whiteColor]; 25 | UIButton *cityBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 94, 100, 30)]; 26 | cityBtn.ym_centerX = self.view.ym_centerX; 27 | [cityBtn setTitle:@"请选择城市" forState:UIControlStateNormal]; 28 | [cityBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 29 | cityBtn.backgroundColor = [UIColor grayColor]; 30 | [cityBtn addTarget:self action:@selector(cityBtnClick:) forControlEvents:UIControlEventTouchUpInside]; 31 | [self.view addSubview:cityBtn]; 32 | _cityLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 150, 100, 30)]; 33 | _cityLabel.ym_centerX = self.view.ym_centerX; 34 | _cityLabel.text = @"北京"; 35 | _cityLabel.textAlignment = NSTextAlignmentCenter; 36 | [self.view addSubview:_cityLabel]; 37 | 38 | UIButton *clearBtn = [[UIButton alloc] init]; 39 | [clearBtn setTitle:@"清理缓存" forState:UIControlStateNormal]; 40 | [clearBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; 41 | [clearBtn sizeToFit]; 42 | clearBtn.center = self.view.center; 43 | [self.view addSubview:clearBtn]; 44 | [clearBtn addTarget:self action:@selector(clearBtnClick) forControlEvents:UIControlEventTouchUpInside]; 45 | } 46 | 47 | -(void)cityBtnClick:(UIButton *)btn{ 48 | [self presentViewController:[[YMCitySelect alloc] initWithDelegate:self] animated:YES completion:nil]; 49 | } 50 | 51 | -(void)clearBtnClick{ 52 | NSUserDefaults *clear = [NSUserDefaults standardUserDefaults]; 53 | [clear removeObjectForKey:@"ym_cityNames"]; 54 | } 55 | 56 | - (void)didReceiveMemoryWarning { 57 | [super didReceiveMemoryWarning]; 58 | // Dispose of any resources that can be recreated. 59 | } 60 | 61 | -(void)ym_ymCitySelectCityName:(NSString *)cityName{ 62 | _cityLabel.text = cityName; 63 | } 64 | 65 | /* 66 | #pragma mark - Navigation 67 | 68 | // In a storyboard-based application, you will often want to do a little preparation before navigation 69 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 70 | // Get the new view controller using [segue destinationViewController]. 71 | // Pass the selected object to the new view controller. 72 | } 73 | */ 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /YMCitySelectExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // YMCitySelect 4 | // 5 | // Created by mac on 16/4/23. 6 | // Copyright © 2016年 YiMin. 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 | -------------------------------------------------------------------------------- /ymcityselect.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yiminfe/YMCitySelect/b411f2741237b30a01aff5cecc721b1e79e7a5af/ymcityselect.gif --------------------------------------------------------------------------------