├── CityListDemo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── ray.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── ray.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── CityListDemo.xcscheme │ └── xcschememanagement.plist ├── CityListDemo ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ └── LaunchScreen.storyboard ├── CityListDemo-Bridging-Header.h ├── Info.plist ├── LocationManager.swift ├── MainViewController.swift └── MainViewController.xib ├── CityListDemoTests ├── CityListDemoTests.swift └── Info.plist ├── CityListDemoUITests ├── CityListDemoUITests.swift └── Info.plist ├── CityListView ├── CityButton.swift ├── CityViewController.swift ├── CityViewController.xib ├── CollectionViewCell.swift ├── CollectionViewCell.xib ├── Resource │ └── citydict.plist ├── SectionView.swift ├── SectionView.xib ├── TableViewCell.swift ├── TableViewCell.xib ├── TableViewHeadSectionCell.swift ├── TableViewHeadSectionCell.xib └── Util │ └── SpecifyArray.swift ├── README.md ├── ZYPinYinSearchLib ├── ChineseInclude.h ├── ChineseInclude.m ├── ChineseToPinyinResource.h ├── ChineseToPinyinResource.m ├── HanyuPinyinOutputFormat.h ├── HanyuPinyinOutputFormat.m ├── NSString+PinYin4Cocoa.h ├── NSString+PinYin4Cocoa.m ├── PinYinForObjc.h ├── PinYinForObjc.m ├── PinyinFormatter.h ├── PinyinFormatter.m ├── PinyinHelper.h ├── PinyinHelper.m ├── ZYPinYinSearch.h ├── ZYPinYinSearch.m └── unicode_to_hanyu_pinyin.txt └── 效果图 ├── 01.gif ├── 02.png └── 03.png /CityListDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7105B4651C1673C100A5952C /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7105B4641C1673C100A5952C /* LocationManager.swift */; settings = {ASSET_TAGS = (); }; }; 11 | 7154FBD81C0FE9B800F2A3AF /* ChineseInclude.m in Sources */ = {isa = PBXBuildFile; fileRef = 7154FBC81C0FE9B800F2A3AF /* ChineseInclude.m */; settings = {ASSET_TAGS = (); }; }; 12 | 7154FBD91C0FE9B800F2A3AF /* ChineseToPinyinResource.m in Sources */ = {isa = PBXBuildFile; fileRef = 7154FBCA1C0FE9B800F2A3AF /* ChineseToPinyinResource.m */; settings = {ASSET_TAGS = (); }; }; 13 | 7154FBDA1C0FE9B800F2A3AF /* HanyuPinyinOutputFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 7154FBCC1C0FE9B800F2A3AF /* HanyuPinyinOutputFormat.m */; settings = {ASSET_TAGS = (); }; }; 14 | 7154FBDB1C0FE9B800F2A3AF /* NSString+PinYin4Cocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = 7154FBCE1C0FE9B800F2A3AF /* NSString+PinYin4Cocoa.m */; settings = {ASSET_TAGS = (); }; }; 15 | 7154FBDC1C0FE9B800F2A3AF /* PinyinFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 7154FBD01C0FE9B800F2A3AF /* PinyinFormatter.m */; settings = {ASSET_TAGS = (); }; }; 16 | 7154FBDD1C0FE9B800F2A3AF /* PinYinForObjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 7154FBD21C0FE9B800F2A3AF /* PinYinForObjc.m */; settings = {ASSET_TAGS = (); }; }; 17 | 7154FBDE1C0FE9B800F2A3AF /* PinyinHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 7154FBD41C0FE9B800F2A3AF /* PinyinHelper.m */; settings = {ASSET_TAGS = (); }; }; 18 | 7154FBDF1C0FE9B800F2A3AF /* unicode_to_hanyu_pinyin.txt in Resources */ = {isa = PBXBuildFile; fileRef = 7154FBD51C0FE9B800F2A3AF /* unicode_to_hanyu_pinyin.txt */; settings = {ASSET_TAGS = (); }; }; 19 | 7154FBE01C0FE9B800F2A3AF /* ZYPinYinSearch.m in Sources */ = {isa = PBXBuildFile; fileRef = 7154FBD71C0FE9B800F2A3AF /* ZYPinYinSearch.m */; settings = {ASSET_TAGS = (); }; }; 20 | 716E09511C0EC62E009C696C /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 716E09441C0EC62E009C696C /* CollectionViewCell.swift */; settings = {ASSET_TAGS = (); }; }; 21 | 716E09521C0EC62E009C696C /* CollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 716E09451C0EC62E009C696C /* CollectionViewCell.xib */; settings = {ASSET_TAGS = (); }; }; 22 | 716E09531C0EC62E009C696C /* TableViewHeadSectionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 716E09461C0EC62E009C696C /* TableViewHeadSectionCell.swift */; settings = {ASSET_TAGS = (); }; }; 23 | 716E09541C0EC62E009C696C /* TableViewHeadSectionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 716E09471C0EC62E009C696C /* TableViewHeadSectionCell.xib */; settings = {ASSET_TAGS = (); }; }; 24 | 716E09551C0EC62E009C696C /* CityButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 716E09481C0EC62E009C696C /* CityButton.swift */; settings = {ASSET_TAGS = (); }; }; 25 | 716E09561C0EC62E009C696C /* CityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 716E09491C0EC62E009C696C /* CityViewController.swift */; settings = {ASSET_TAGS = (); }; }; 26 | 716E09571C0EC62E009C696C /* CityViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 716E094A1C0EC62E009C696C /* CityViewController.xib */; settings = {ASSET_TAGS = (); }; }; 27 | 716E095A1C0EC62E009C696C /* SectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 716E094D1C0EC62E009C696C /* SectionView.swift */; settings = {ASSET_TAGS = (); }; }; 28 | 716E095B1C0EC62E009C696C /* SectionView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 716E094E1C0EC62E009C696C /* SectionView.xib */; settings = {ASSET_TAGS = (); }; }; 29 | 716E095C1C0EC62E009C696C /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 716E094F1C0EC62E009C696C /* TableViewCell.swift */; settings = {ASSET_TAGS = (); }; }; 30 | 716E095D1C0EC62E009C696C /* TableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 716E09501C0EC62E009C696C /* TableViewCell.xib */; settings = {ASSET_TAGS = (); }; }; 31 | 7177F9D11C03F14900544DBE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7177F9D01C03F14900544DBE /* AppDelegate.swift */; }; 32 | 7177F9D81C03F14900544DBE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7177F9D71C03F14900544DBE /* Assets.xcassets */; }; 33 | 7177F9DB1C03F14900544DBE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7177F9D91C03F14900544DBE /* LaunchScreen.storyboard */; }; 34 | 7177F9E61C03F14900544DBE /* CityListDemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7177F9E51C03F14900544DBE /* CityListDemoTests.swift */; }; 35 | 7177F9F11C03F14900544DBE /* CityListDemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7177F9F01C03F14900544DBE /* CityListDemoUITests.swift */; }; 36 | 71872D831C113A2600FA1DD5 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 71872D821C113A2600FA1DD5 /* CoreLocation.framework */; }; 37 | 71872D841C113A4300FA1DD5 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 71872D801C113A1800FA1DD5 /* MapKit.framework */; }; 38 | 719365FE1C1812FE008B54C0 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 719365FC1C1812FE008B54C0 /* MainViewController.swift */; settings = {ASSET_TAGS = (); }; }; 39 | 719365FF1C1812FE008B54C0 /* MainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 719365FD1C1812FE008B54C0 /* MainViewController.xib */; settings = {ASSET_TAGS = (); }; }; 40 | 71B61A3D1C2BCB7900508011 /* citydict.plist in Resources */ = {isa = PBXBuildFile; fileRef = 71B61A3C1C2BCB7900508011 /* citydict.plist */; settings = {ASSET_TAGS = (); }; }; 41 | 71B61A3F1C2BCBCC00508011 /* SpecifyArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71B61A3E1C2BCBCC00508011 /* SpecifyArray.swift */; settings = {ASSET_TAGS = (); }; }; 42 | /* End PBXBuildFile section */ 43 | 44 | /* Begin PBXContainerItemProxy section */ 45 | 7177F9E21C03F14900544DBE /* PBXContainerItemProxy */ = { 46 | isa = PBXContainerItemProxy; 47 | containerPortal = 7177F9C51C03F14900544DBE /* Project object */; 48 | proxyType = 1; 49 | remoteGlobalIDString = 7177F9CC1C03F14900544DBE; 50 | remoteInfo = CityListDemo; 51 | }; 52 | 7177F9ED1C03F14900544DBE /* PBXContainerItemProxy */ = { 53 | isa = PBXContainerItemProxy; 54 | containerPortal = 7177F9C51C03F14900544DBE /* Project object */; 55 | proxyType = 1; 56 | remoteGlobalIDString = 7177F9CC1C03F14900544DBE; 57 | remoteInfo = CityListDemo; 58 | }; 59 | /* End PBXContainerItemProxy section */ 60 | 61 | /* Begin PBXFileReference section */ 62 | 7105B4641C1673C100A5952C /* LocationManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = ""; }; 63 | 7154FBC61C0FE9B700F2A3AF /* CityListDemo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CityListDemo-Bridging-Header.h"; sourceTree = ""; }; 64 | 7154FBC71C0FE9B800F2A3AF /* ChineseInclude.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ChineseInclude.h; path = ZYPinYinSearchLib/ChineseInclude.h; sourceTree = SOURCE_ROOT; }; 65 | 7154FBC81C0FE9B800F2A3AF /* ChineseInclude.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ChineseInclude.m; path = ZYPinYinSearchLib/ChineseInclude.m; sourceTree = SOURCE_ROOT; }; 66 | 7154FBC91C0FE9B800F2A3AF /* ChineseToPinyinResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ChineseToPinyinResource.h; path = ZYPinYinSearchLib/ChineseToPinyinResource.h; sourceTree = SOURCE_ROOT; }; 67 | 7154FBCA1C0FE9B800F2A3AF /* ChineseToPinyinResource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ChineseToPinyinResource.m; path = ZYPinYinSearchLib/ChineseToPinyinResource.m; sourceTree = SOURCE_ROOT; }; 68 | 7154FBCB1C0FE9B800F2A3AF /* HanyuPinyinOutputFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HanyuPinyinOutputFormat.h; path = ZYPinYinSearchLib/HanyuPinyinOutputFormat.h; sourceTree = SOURCE_ROOT; }; 69 | 7154FBCC1C0FE9B800F2A3AF /* HanyuPinyinOutputFormat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HanyuPinyinOutputFormat.m; path = ZYPinYinSearchLib/HanyuPinyinOutputFormat.m; sourceTree = SOURCE_ROOT; }; 70 | 7154FBCD1C0FE9B800F2A3AF /* NSString+PinYin4Cocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSString+PinYin4Cocoa.h"; path = "ZYPinYinSearchLib/NSString+PinYin4Cocoa.h"; sourceTree = SOURCE_ROOT; }; 71 | 7154FBCE1C0FE9B800F2A3AF /* NSString+PinYin4Cocoa.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSString+PinYin4Cocoa.m"; path = "ZYPinYinSearchLib/NSString+PinYin4Cocoa.m"; sourceTree = SOURCE_ROOT; }; 72 | 7154FBCF1C0FE9B800F2A3AF /* PinyinFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PinyinFormatter.h; path = ZYPinYinSearchLib/PinyinFormatter.h; sourceTree = SOURCE_ROOT; }; 73 | 7154FBD01C0FE9B800F2A3AF /* PinyinFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PinyinFormatter.m; path = ZYPinYinSearchLib/PinyinFormatter.m; sourceTree = SOURCE_ROOT; }; 74 | 7154FBD11C0FE9B800F2A3AF /* PinYinForObjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PinYinForObjc.h; path = ZYPinYinSearchLib/PinYinForObjc.h; sourceTree = SOURCE_ROOT; }; 75 | 7154FBD21C0FE9B800F2A3AF /* PinYinForObjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PinYinForObjc.m; path = ZYPinYinSearchLib/PinYinForObjc.m; sourceTree = SOURCE_ROOT; }; 76 | 7154FBD31C0FE9B800F2A3AF /* PinyinHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PinyinHelper.h; path = ZYPinYinSearchLib/PinyinHelper.h; sourceTree = SOURCE_ROOT; }; 77 | 7154FBD41C0FE9B800F2A3AF /* PinyinHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PinyinHelper.m; path = ZYPinYinSearchLib/PinyinHelper.m; sourceTree = SOURCE_ROOT; }; 78 | 7154FBD51C0FE9B800F2A3AF /* unicode_to_hanyu_pinyin.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = unicode_to_hanyu_pinyin.txt; path = ZYPinYinSearchLib/unicode_to_hanyu_pinyin.txt; sourceTree = SOURCE_ROOT; }; 79 | 7154FBD61C0FE9B800F2A3AF /* ZYPinYinSearch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZYPinYinSearch.h; path = ZYPinYinSearchLib/ZYPinYinSearch.h; sourceTree = SOURCE_ROOT; }; 80 | 7154FBD71C0FE9B800F2A3AF /* ZYPinYinSearch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZYPinYinSearch.m; path = ZYPinYinSearchLib/ZYPinYinSearch.m; sourceTree = SOURCE_ROOT; }; 81 | 716E09441C0EC62E009C696C /* CollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CollectionViewCell.swift; path = CityListView/CollectionViewCell.swift; sourceTree = SOURCE_ROOT; }; 82 | 716E09451C0EC62E009C696C /* CollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = CollectionViewCell.xib; path = CityListView/CollectionViewCell.xib; sourceTree = SOURCE_ROOT; }; 83 | 716E09461C0EC62E009C696C /* TableViewHeadSectionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TableViewHeadSectionCell.swift; path = CityListView/TableViewHeadSectionCell.swift; sourceTree = SOURCE_ROOT; }; 84 | 716E09471C0EC62E009C696C /* TableViewHeadSectionCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = TableViewHeadSectionCell.xib; path = CityListView/TableViewHeadSectionCell.xib; sourceTree = SOURCE_ROOT; }; 85 | 716E09481C0EC62E009C696C /* CityButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CityButton.swift; path = CityListView/CityButton.swift; sourceTree = SOURCE_ROOT; }; 86 | 716E09491C0EC62E009C696C /* CityViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CityViewController.swift; path = CityListView/CityViewController.swift; sourceTree = SOURCE_ROOT; }; 87 | 716E094A1C0EC62E009C696C /* CityViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = CityViewController.xib; path = CityListView/CityViewController.xib; sourceTree = SOURCE_ROOT; }; 88 | 716E094D1C0EC62E009C696C /* SectionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SectionView.swift; path = CityListView/SectionView.swift; sourceTree = SOURCE_ROOT; }; 89 | 716E094E1C0EC62E009C696C /* SectionView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = SectionView.xib; path = CityListView/SectionView.xib; sourceTree = SOURCE_ROOT; }; 90 | 716E094F1C0EC62E009C696C /* TableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TableViewCell.swift; path = CityListView/TableViewCell.swift; sourceTree = SOURCE_ROOT; }; 91 | 716E09501C0EC62E009C696C /* TableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = TableViewCell.xib; path = CityListView/TableViewCell.xib; sourceTree = SOURCE_ROOT; }; 92 | 7177F9CD1C03F14900544DBE /* CityListDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CityListDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 93 | 7177F9D01C03F14900544DBE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 94 | 7177F9D71C03F14900544DBE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 95 | 7177F9DA1C03F14900544DBE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 96 | 7177F9DC1C03F14900544DBE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 97 | 7177F9E11C03F14900544DBE /* CityListDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CityListDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 98 | 7177F9E51C03F14900544DBE /* CityListDemoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CityListDemoTests.swift; sourceTree = ""; }; 99 | 7177F9E71C03F14900544DBE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 100 | 7177F9EC1C03F14900544DBE /* CityListDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CityListDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 101 | 7177F9F01C03F14900544DBE /* CityListDemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CityListDemoUITests.swift; sourceTree = ""; }; 102 | 7177F9F21C03F14900544DBE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 103 | 71872D801C113A1800FA1DD5 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; 104 | 71872D821C113A2600FA1DD5 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; 105 | 719365FC1C1812FE008B54C0 /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; 106 | 719365FD1C1812FE008B54C0 /* MainViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainViewController.xib; sourceTree = ""; }; 107 | 71B61A3C1C2BCB7900508011 /* citydict.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = citydict.plist; path = CityListView/Resource/citydict.plist; sourceTree = SOURCE_ROOT; }; 108 | 71B61A3E1C2BCBCC00508011 /* SpecifyArray.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SpecifyArray.swift; path = CityListView/Util/SpecifyArray.swift; sourceTree = SOURCE_ROOT; }; 109 | /* End PBXFileReference section */ 110 | 111 | /* Begin PBXFrameworksBuildPhase section */ 112 | 7177F9CA1C03F14900544DBE /* Frameworks */ = { 113 | isa = PBXFrameworksBuildPhase; 114 | buildActionMask = 2147483647; 115 | files = ( 116 | 71872D841C113A4300FA1DD5 /* MapKit.framework in Frameworks */, 117 | 71872D831C113A2600FA1DD5 /* CoreLocation.framework in Frameworks */, 118 | ); 119 | runOnlyForDeploymentPostprocessing = 0; 120 | }; 121 | 7177F9DE1C03F14900544DBE /* Frameworks */ = { 122 | isa = PBXFrameworksBuildPhase; 123 | buildActionMask = 2147483647; 124 | files = ( 125 | ); 126 | runOnlyForDeploymentPostprocessing = 0; 127 | }; 128 | 7177F9E91C03F14900544DBE /* Frameworks */ = { 129 | isa = PBXFrameworksBuildPhase; 130 | buildActionMask = 2147483647; 131 | files = ( 132 | ); 133 | runOnlyForDeploymentPostprocessing = 0; 134 | }; 135 | /* End PBXFrameworksBuildPhase section */ 136 | 137 | /* Begin PBXGroup section */ 138 | 7154FBC51C0FE99200F2A3AF /* ZYPinYinSearchLib */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | 7154FBC71C0FE9B800F2A3AF /* ChineseInclude.h */, 142 | 7154FBC81C0FE9B800F2A3AF /* ChineseInclude.m */, 143 | 7154FBC91C0FE9B800F2A3AF /* ChineseToPinyinResource.h */, 144 | 7154FBCA1C0FE9B800F2A3AF /* ChineseToPinyinResource.m */, 145 | 7154FBCB1C0FE9B800F2A3AF /* HanyuPinyinOutputFormat.h */, 146 | 7154FBCC1C0FE9B800F2A3AF /* HanyuPinyinOutputFormat.m */, 147 | 7154FBCD1C0FE9B800F2A3AF /* NSString+PinYin4Cocoa.h */, 148 | 7154FBCE1C0FE9B800F2A3AF /* NSString+PinYin4Cocoa.m */, 149 | 7154FBCF1C0FE9B800F2A3AF /* PinyinFormatter.h */, 150 | 7154FBD01C0FE9B800F2A3AF /* PinyinFormatter.m */, 151 | 7154FBD11C0FE9B800F2A3AF /* PinYinForObjc.h */, 152 | 7154FBD21C0FE9B800F2A3AF /* PinYinForObjc.m */, 153 | 7154FBD31C0FE9B800F2A3AF /* PinyinHelper.h */, 154 | 7154FBD41C0FE9B800F2A3AF /* PinyinHelper.m */, 155 | 7154FBD51C0FE9B800F2A3AF /* unicode_to_hanyu_pinyin.txt */, 156 | 7154FBD61C0FE9B800F2A3AF /* ZYPinYinSearch.h */, 157 | 7154FBD71C0FE9B800F2A3AF /* ZYPinYinSearch.m */, 158 | ); 159 | name = ZYPinYinSearchLib; 160 | sourceTree = ""; 161 | }; 162 | 716E09431C0EC5B0009C696C /* CityListView */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 719845A11C191E2900225577 /* Util */, 166 | 7177FA041C0436EA00544DBE /* Resource */, 167 | 716E09491C0EC62E009C696C /* CityViewController.swift */, 168 | 716E094A1C0EC62E009C696C /* CityViewController.xib */, 169 | 716E09441C0EC62E009C696C /* CollectionViewCell.swift */, 170 | 716E09451C0EC62E009C696C /* CollectionViewCell.xib */, 171 | 716E09461C0EC62E009C696C /* TableViewHeadSectionCell.swift */, 172 | 716E09471C0EC62E009C696C /* TableViewHeadSectionCell.xib */, 173 | 716E09481C0EC62E009C696C /* CityButton.swift */, 174 | 716E094D1C0EC62E009C696C /* SectionView.swift */, 175 | 716E094E1C0EC62E009C696C /* SectionView.xib */, 176 | 716E094F1C0EC62E009C696C /* TableViewCell.swift */, 177 | 716E09501C0EC62E009C696C /* TableViewCell.xib */, 178 | 7105B4641C1673C100A5952C /* LocationManager.swift */, 179 | ); 180 | name = CityListView; 181 | sourceTree = ""; 182 | }; 183 | 7177F9C41C03F14900544DBE = { 184 | isa = PBXGroup; 185 | children = ( 186 | 7177F9CF1C03F14900544DBE /* CityListDemo */, 187 | 7177F9E41C03F14900544DBE /* CityListDemoTests */, 188 | 7177F9EF1C03F14900544DBE /* CityListDemoUITests */, 189 | 7177F9CE1C03F14900544DBE /* Products */, 190 | 71872D851C117E3600FA1DD5 /* Framework */, 191 | ); 192 | sourceTree = ""; 193 | }; 194 | 7177F9CE1C03F14900544DBE /* Products */ = { 195 | isa = PBXGroup; 196 | children = ( 197 | 7177F9CD1C03F14900544DBE /* CityListDemo.app */, 198 | 7177F9E11C03F14900544DBE /* CityListDemoTests.xctest */, 199 | 7177F9EC1C03F14900544DBE /* CityListDemoUITests.xctest */, 200 | ); 201 | name = Products; 202 | sourceTree = ""; 203 | }; 204 | 7177F9CF1C03F14900544DBE /* CityListDemo */ = { 205 | isa = PBXGroup; 206 | children = ( 207 | 7154FBC51C0FE99200F2A3AF /* ZYPinYinSearchLib */, 208 | 716E09431C0EC5B0009C696C /* CityListView */, 209 | 7177F9D01C03F14900544DBE /* AppDelegate.swift */, 210 | 7177F9D71C03F14900544DBE /* Assets.xcassets */, 211 | 7177F9D91C03F14900544DBE /* LaunchScreen.storyboard */, 212 | 7154FBC61C0FE9B700F2A3AF /* CityListDemo-Bridging-Header.h */, 213 | 7177F9DC1C03F14900544DBE /* Info.plist */, 214 | 719365FC1C1812FE008B54C0 /* MainViewController.swift */, 215 | 719365FD1C1812FE008B54C0 /* MainViewController.xib */, 216 | ); 217 | path = CityListDemo; 218 | sourceTree = ""; 219 | }; 220 | 7177F9E41C03F14900544DBE /* CityListDemoTests */ = { 221 | isa = PBXGroup; 222 | children = ( 223 | 7177F9E51C03F14900544DBE /* CityListDemoTests.swift */, 224 | 7177F9E71C03F14900544DBE /* Info.plist */, 225 | ); 226 | path = CityListDemoTests; 227 | sourceTree = ""; 228 | }; 229 | 7177F9EF1C03F14900544DBE /* CityListDemoUITests */ = { 230 | isa = PBXGroup; 231 | children = ( 232 | 7177F9F01C03F14900544DBE /* CityListDemoUITests.swift */, 233 | 7177F9F21C03F14900544DBE /* Info.plist */, 234 | ); 235 | path = CityListDemoUITests; 236 | sourceTree = ""; 237 | }; 238 | 7177FA041C0436EA00544DBE /* Resource */ = { 239 | isa = PBXGroup; 240 | children = ( 241 | 71B61A3C1C2BCB7900508011 /* citydict.plist */, 242 | ); 243 | name = Resource; 244 | sourceTree = ""; 245 | }; 246 | 71872D851C117E3600FA1DD5 /* Framework */ = { 247 | isa = PBXGroup; 248 | children = ( 249 | 71872D821C113A2600FA1DD5 /* CoreLocation.framework */, 250 | 71872D801C113A1800FA1DD5 /* MapKit.framework */, 251 | ); 252 | name = Framework; 253 | sourceTree = ""; 254 | }; 255 | 719845A11C191E2900225577 /* Util */ = { 256 | isa = PBXGroup; 257 | children = ( 258 | 71B61A3E1C2BCBCC00508011 /* SpecifyArray.swift */, 259 | ); 260 | name = Util; 261 | sourceTree = ""; 262 | }; 263 | /* End PBXGroup section */ 264 | 265 | /* Begin PBXNativeTarget section */ 266 | 7177F9CC1C03F14900544DBE /* CityListDemo */ = { 267 | isa = PBXNativeTarget; 268 | buildConfigurationList = 7177F9F51C03F14900544DBE /* Build configuration list for PBXNativeTarget "CityListDemo" */; 269 | buildPhases = ( 270 | 7177F9C91C03F14900544DBE /* Sources */, 271 | 7177F9CA1C03F14900544DBE /* Frameworks */, 272 | 7177F9CB1C03F14900544DBE /* Resources */, 273 | ); 274 | buildRules = ( 275 | ); 276 | dependencies = ( 277 | ); 278 | name = CityListDemo; 279 | productName = CityListDemo; 280 | productReference = 7177F9CD1C03F14900544DBE /* CityListDemo.app */; 281 | productType = "com.apple.product-type.application"; 282 | }; 283 | 7177F9E01C03F14900544DBE /* CityListDemoTests */ = { 284 | isa = PBXNativeTarget; 285 | buildConfigurationList = 7177F9F81C03F14900544DBE /* Build configuration list for PBXNativeTarget "CityListDemoTests" */; 286 | buildPhases = ( 287 | 7177F9DD1C03F14900544DBE /* Sources */, 288 | 7177F9DE1C03F14900544DBE /* Frameworks */, 289 | 7177F9DF1C03F14900544DBE /* Resources */, 290 | ); 291 | buildRules = ( 292 | ); 293 | dependencies = ( 294 | 7177F9E31C03F14900544DBE /* PBXTargetDependency */, 295 | ); 296 | name = CityListDemoTests; 297 | productName = CityListDemoTests; 298 | productReference = 7177F9E11C03F14900544DBE /* CityListDemoTests.xctest */; 299 | productType = "com.apple.product-type.bundle.unit-test"; 300 | }; 301 | 7177F9EB1C03F14900544DBE /* CityListDemoUITests */ = { 302 | isa = PBXNativeTarget; 303 | buildConfigurationList = 7177F9FB1C03F14900544DBE /* Build configuration list for PBXNativeTarget "CityListDemoUITests" */; 304 | buildPhases = ( 305 | 7177F9E81C03F14900544DBE /* Sources */, 306 | 7177F9E91C03F14900544DBE /* Frameworks */, 307 | 7177F9EA1C03F14900544DBE /* Resources */, 308 | ); 309 | buildRules = ( 310 | ); 311 | dependencies = ( 312 | 7177F9EE1C03F14900544DBE /* PBXTargetDependency */, 313 | ); 314 | name = CityListDemoUITests; 315 | productName = CityListDemoUITests; 316 | productReference = 7177F9EC1C03F14900544DBE /* CityListDemoUITests.xctest */; 317 | productType = "com.apple.product-type.bundle.ui-testing"; 318 | }; 319 | /* End PBXNativeTarget section */ 320 | 321 | /* Begin PBXProject section */ 322 | 7177F9C51C03F14900544DBE /* Project object */ = { 323 | isa = PBXProject; 324 | attributes = { 325 | LastSwiftUpdateCheck = 0700; 326 | LastUpgradeCheck = 0700; 327 | ORGANIZATIONNAME = ray; 328 | TargetAttributes = { 329 | 7177F9CC1C03F14900544DBE = { 330 | CreatedOnToolsVersion = 7.0; 331 | }; 332 | 7177F9E01C03F14900544DBE = { 333 | CreatedOnToolsVersion = 7.0; 334 | TestTargetID = 7177F9CC1C03F14900544DBE; 335 | }; 336 | 7177F9EB1C03F14900544DBE = { 337 | CreatedOnToolsVersion = 7.0; 338 | TestTargetID = 7177F9CC1C03F14900544DBE; 339 | }; 340 | }; 341 | }; 342 | buildConfigurationList = 7177F9C81C03F14900544DBE /* Build configuration list for PBXProject "CityListDemo" */; 343 | compatibilityVersion = "Xcode 3.2"; 344 | developmentRegion = English; 345 | hasScannedForEncodings = 0; 346 | knownRegions = ( 347 | en, 348 | Base, 349 | ); 350 | mainGroup = 7177F9C41C03F14900544DBE; 351 | productRefGroup = 7177F9CE1C03F14900544DBE /* Products */; 352 | projectDirPath = ""; 353 | projectRoot = ""; 354 | targets = ( 355 | 7177F9CC1C03F14900544DBE /* CityListDemo */, 356 | 7177F9E01C03F14900544DBE /* CityListDemoTests */, 357 | 7177F9EB1C03F14900544DBE /* CityListDemoUITests */, 358 | ); 359 | }; 360 | /* End PBXProject section */ 361 | 362 | /* Begin PBXResourcesBuildPhase section */ 363 | 7177F9CB1C03F14900544DBE /* Resources */ = { 364 | isa = PBXResourcesBuildPhase; 365 | buildActionMask = 2147483647; 366 | files = ( 367 | 716E095B1C0EC62E009C696C /* SectionView.xib in Resources */, 368 | 716E09541C0EC62E009C696C /* TableViewHeadSectionCell.xib in Resources */, 369 | 7154FBDF1C0FE9B800F2A3AF /* unicode_to_hanyu_pinyin.txt in Resources */, 370 | 716E095D1C0EC62E009C696C /* TableViewCell.xib in Resources */, 371 | 71B61A3D1C2BCB7900508011 /* citydict.plist in Resources */, 372 | 7177F9DB1C03F14900544DBE /* LaunchScreen.storyboard in Resources */, 373 | 716E09571C0EC62E009C696C /* CityViewController.xib in Resources */, 374 | 719365FF1C1812FE008B54C0 /* MainViewController.xib in Resources */, 375 | 716E09521C0EC62E009C696C /* CollectionViewCell.xib in Resources */, 376 | 7177F9D81C03F14900544DBE /* Assets.xcassets in Resources */, 377 | ); 378 | runOnlyForDeploymentPostprocessing = 0; 379 | }; 380 | 7177F9DF1C03F14900544DBE /* Resources */ = { 381 | isa = PBXResourcesBuildPhase; 382 | buildActionMask = 2147483647; 383 | files = ( 384 | ); 385 | runOnlyForDeploymentPostprocessing = 0; 386 | }; 387 | 7177F9EA1C03F14900544DBE /* Resources */ = { 388 | isa = PBXResourcesBuildPhase; 389 | buildActionMask = 2147483647; 390 | files = ( 391 | ); 392 | runOnlyForDeploymentPostprocessing = 0; 393 | }; 394 | /* End PBXResourcesBuildPhase section */ 395 | 396 | /* Begin PBXSourcesBuildPhase section */ 397 | 7177F9C91C03F14900544DBE /* Sources */ = { 398 | isa = PBXSourcesBuildPhase; 399 | buildActionMask = 2147483647; 400 | files = ( 401 | 7154FBDD1C0FE9B800F2A3AF /* PinYinForObjc.m in Sources */, 402 | 716E09551C0EC62E009C696C /* CityButton.swift in Sources */, 403 | 716E095C1C0EC62E009C696C /* TableViewCell.swift in Sources */, 404 | 7154FBD91C0FE9B800F2A3AF /* ChineseToPinyinResource.m in Sources */, 405 | 7105B4651C1673C100A5952C /* LocationManager.swift in Sources */, 406 | 716E09561C0EC62E009C696C /* CityViewController.swift in Sources */, 407 | 716E09531C0EC62E009C696C /* TableViewHeadSectionCell.swift in Sources */, 408 | 719365FE1C1812FE008B54C0 /* MainViewController.swift in Sources */, 409 | 7154FBDB1C0FE9B800F2A3AF /* NSString+PinYin4Cocoa.m in Sources */, 410 | 71B61A3F1C2BCBCC00508011 /* SpecifyArray.swift in Sources */, 411 | 716E095A1C0EC62E009C696C /* SectionView.swift in Sources */, 412 | 7154FBDC1C0FE9B800F2A3AF /* PinyinFormatter.m in Sources */, 413 | 7154FBE01C0FE9B800F2A3AF /* ZYPinYinSearch.m in Sources */, 414 | 7154FBDA1C0FE9B800F2A3AF /* HanyuPinyinOutputFormat.m in Sources */, 415 | 7154FBDE1C0FE9B800F2A3AF /* PinyinHelper.m in Sources */, 416 | 716E09511C0EC62E009C696C /* CollectionViewCell.swift in Sources */, 417 | 7154FBD81C0FE9B800F2A3AF /* ChineseInclude.m in Sources */, 418 | 7177F9D11C03F14900544DBE /* AppDelegate.swift in Sources */, 419 | ); 420 | runOnlyForDeploymentPostprocessing = 0; 421 | }; 422 | 7177F9DD1C03F14900544DBE /* Sources */ = { 423 | isa = PBXSourcesBuildPhase; 424 | buildActionMask = 2147483647; 425 | files = ( 426 | 7177F9E61C03F14900544DBE /* CityListDemoTests.swift in Sources */, 427 | ); 428 | runOnlyForDeploymentPostprocessing = 0; 429 | }; 430 | 7177F9E81C03F14900544DBE /* Sources */ = { 431 | isa = PBXSourcesBuildPhase; 432 | buildActionMask = 2147483647; 433 | files = ( 434 | 7177F9F11C03F14900544DBE /* CityListDemoUITests.swift in Sources */, 435 | ); 436 | runOnlyForDeploymentPostprocessing = 0; 437 | }; 438 | /* End PBXSourcesBuildPhase section */ 439 | 440 | /* Begin PBXTargetDependency section */ 441 | 7177F9E31C03F14900544DBE /* PBXTargetDependency */ = { 442 | isa = PBXTargetDependency; 443 | target = 7177F9CC1C03F14900544DBE /* CityListDemo */; 444 | targetProxy = 7177F9E21C03F14900544DBE /* PBXContainerItemProxy */; 445 | }; 446 | 7177F9EE1C03F14900544DBE /* PBXTargetDependency */ = { 447 | isa = PBXTargetDependency; 448 | target = 7177F9CC1C03F14900544DBE /* CityListDemo */; 449 | targetProxy = 7177F9ED1C03F14900544DBE /* PBXContainerItemProxy */; 450 | }; 451 | /* End PBXTargetDependency section */ 452 | 453 | /* Begin PBXVariantGroup section */ 454 | 7177F9D91C03F14900544DBE /* LaunchScreen.storyboard */ = { 455 | isa = PBXVariantGroup; 456 | children = ( 457 | 7177F9DA1C03F14900544DBE /* Base */, 458 | ); 459 | name = LaunchScreen.storyboard; 460 | sourceTree = ""; 461 | }; 462 | /* End PBXVariantGroup section */ 463 | 464 | /* Begin XCBuildConfiguration section */ 465 | 7177F9F31C03F14900544DBE /* Debug */ = { 466 | isa = XCBuildConfiguration; 467 | buildSettings = { 468 | ALWAYS_SEARCH_USER_PATHS = NO; 469 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 470 | CLANG_CXX_LIBRARY = "libc++"; 471 | CLANG_ENABLE_MODULES = YES; 472 | CLANG_ENABLE_OBJC_ARC = YES; 473 | CLANG_WARN_BOOL_CONVERSION = YES; 474 | CLANG_WARN_CONSTANT_CONVERSION = YES; 475 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 476 | CLANG_WARN_EMPTY_BODY = YES; 477 | CLANG_WARN_ENUM_CONVERSION = YES; 478 | CLANG_WARN_INT_CONVERSION = YES; 479 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 480 | CLANG_WARN_UNREACHABLE_CODE = YES; 481 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 482 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 483 | COPY_PHASE_STRIP = NO; 484 | DEBUG_INFORMATION_FORMAT = dwarf; 485 | ENABLE_STRICT_OBJC_MSGSEND = YES; 486 | ENABLE_TESTABILITY = YES; 487 | GCC_C_LANGUAGE_STANDARD = gnu99; 488 | GCC_DYNAMIC_NO_PIC = NO; 489 | GCC_NO_COMMON_BLOCKS = YES; 490 | GCC_OPTIMIZATION_LEVEL = 0; 491 | GCC_PREPROCESSOR_DEFINITIONS = ( 492 | "DEBUG=1", 493 | "$(inherited)", 494 | ); 495 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 496 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 497 | GCC_WARN_UNDECLARED_SELECTOR = YES; 498 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 499 | GCC_WARN_UNUSED_FUNCTION = YES; 500 | GCC_WARN_UNUSED_VARIABLE = YES; 501 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 502 | MTL_ENABLE_DEBUG_INFO = YES; 503 | ONLY_ACTIVE_ARCH = YES; 504 | SDKROOT = iphoneos; 505 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 506 | }; 507 | name = Debug; 508 | }; 509 | 7177F9F41C03F14900544DBE /* Release */ = { 510 | isa = XCBuildConfiguration; 511 | buildSettings = { 512 | ALWAYS_SEARCH_USER_PATHS = NO; 513 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 514 | CLANG_CXX_LIBRARY = "libc++"; 515 | CLANG_ENABLE_MODULES = YES; 516 | CLANG_ENABLE_OBJC_ARC = YES; 517 | CLANG_WARN_BOOL_CONVERSION = YES; 518 | CLANG_WARN_CONSTANT_CONVERSION = YES; 519 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 520 | CLANG_WARN_EMPTY_BODY = YES; 521 | CLANG_WARN_ENUM_CONVERSION = YES; 522 | CLANG_WARN_INT_CONVERSION = YES; 523 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 524 | CLANG_WARN_UNREACHABLE_CODE = YES; 525 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 526 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 527 | COPY_PHASE_STRIP = NO; 528 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 529 | ENABLE_NS_ASSERTIONS = NO; 530 | ENABLE_STRICT_OBJC_MSGSEND = YES; 531 | GCC_C_LANGUAGE_STANDARD = gnu99; 532 | GCC_NO_COMMON_BLOCKS = YES; 533 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 534 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 535 | GCC_WARN_UNDECLARED_SELECTOR = YES; 536 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 537 | GCC_WARN_UNUSED_FUNCTION = YES; 538 | GCC_WARN_UNUSED_VARIABLE = YES; 539 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 540 | MTL_ENABLE_DEBUG_INFO = NO; 541 | SDKROOT = iphoneos; 542 | VALIDATE_PRODUCT = YES; 543 | }; 544 | name = Release; 545 | }; 546 | 7177F9F61C03F14900544DBE /* Debug */ = { 547 | isa = XCBuildConfiguration; 548 | buildSettings = { 549 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 550 | CLANG_ENABLE_MODULES = YES; 551 | INFOPLIST_FILE = CityListDemo/Info.plist; 552 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 553 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 554 | PRODUCT_BUNDLE_IDENTIFIER = com.ray.CityListDemo; 555 | PRODUCT_NAME = "$(TARGET_NAME)"; 556 | SWIFT_OBJC_BRIDGING_HEADER = "CityListDemo/CityListDemo-Bridging-Header.h"; 557 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 558 | TARGETED_DEVICE_FAMILY = "1,2"; 559 | }; 560 | name = Debug; 561 | }; 562 | 7177F9F71C03F14900544DBE /* Release */ = { 563 | isa = XCBuildConfiguration; 564 | buildSettings = { 565 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 566 | CLANG_ENABLE_MODULES = YES; 567 | INFOPLIST_FILE = CityListDemo/Info.plist; 568 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 569 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 570 | PRODUCT_BUNDLE_IDENTIFIER = com.ray.CityListDemo; 571 | PRODUCT_NAME = "$(TARGET_NAME)"; 572 | SWIFT_OBJC_BRIDGING_HEADER = "CityListDemo/CityListDemo-Bridging-Header.h"; 573 | TARGETED_DEVICE_FAMILY = "1,2"; 574 | }; 575 | name = Release; 576 | }; 577 | 7177F9F91C03F14900544DBE /* Debug */ = { 578 | isa = XCBuildConfiguration; 579 | buildSettings = { 580 | BUNDLE_LOADER = "$(TEST_HOST)"; 581 | INFOPLIST_FILE = CityListDemoTests/Info.plist; 582 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 583 | PRODUCT_BUNDLE_IDENTIFIER = com.ray.CityListDemoTests; 584 | PRODUCT_NAME = "$(TARGET_NAME)"; 585 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CityListDemo.app/CityListDemo"; 586 | }; 587 | name = Debug; 588 | }; 589 | 7177F9FA1C03F14900544DBE /* Release */ = { 590 | isa = XCBuildConfiguration; 591 | buildSettings = { 592 | BUNDLE_LOADER = "$(TEST_HOST)"; 593 | INFOPLIST_FILE = CityListDemoTests/Info.plist; 594 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 595 | PRODUCT_BUNDLE_IDENTIFIER = com.ray.CityListDemoTests; 596 | PRODUCT_NAME = "$(TARGET_NAME)"; 597 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CityListDemo.app/CityListDemo"; 598 | }; 599 | name = Release; 600 | }; 601 | 7177F9FC1C03F14900544DBE /* Debug */ = { 602 | isa = XCBuildConfiguration; 603 | buildSettings = { 604 | INFOPLIST_FILE = CityListDemoUITests/Info.plist; 605 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 606 | PRODUCT_BUNDLE_IDENTIFIER = com.ray.CityListDemoUITests; 607 | PRODUCT_NAME = "$(TARGET_NAME)"; 608 | TEST_TARGET_NAME = CityListDemo; 609 | USES_XCTRUNNER = YES; 610 | }; 611 | name = Debug; 612 | }; 613 | 7177F9FD1C03F14900544DBE /* Release */ = { 614 | isa = XCBuildConfiguration; 615 | buildSettings = { 616 | INFOPLIST_FILE = CityListDemoUITests/Info.plist; 617 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 618 | PRODUCT_BUNDLE_IDENTIFIER = com.ray.CityListDemoUITests; 619 | PRODUCT_NAME = "$(TARGET_NAME)"; 620 | TEST_TARGET_NAME = CityListDemo; 621 | USES_XCTRUNNER = YES; 622 | }; 623 | name = Release; 624 | }; 625 | /* End XCBuildConfiguration section */ 626 | 627 | /* Begin XCConfigurationList section */ 628 | 7177F9C81C03F14900544DBE /* Build configuration list for PBXProject "CityListDemo" */ = { 629 | isa = XCConfigurationList; 630 | buildConfigurations = ( 631 | 7177F9F31C03F14900544DBE /* Debug */, 632 | 7177F9F41C03F14900544DBE /* Release */, 633 | ); 634 | defaultConfigurationIsVisible = 0; 635 | defaultConfigurationName = Release; 636 | }; 637 | 7177F9F51C03F14900544DBE /* Build configuration list for PBXNativeTarget "CityListDemo" */ = { 638 | isa = XCConfigurationList; 639 | buildConfigurations = ( 640 | 7177F9F61C03F14900544DBE /* Debug */, 641 | 7177F9F71C03F14900544DBE /* Release */, 642 | ); 643 | defaultConfigurationIsVisible = 0; 644 | defaultConfigurationName = Release; 645 | }; 646 | 7177F9F81C03F14900544DBE /* Build configuration list for PBXNativeTarget "CityListDemoTests" */ = { 647 | isa = XCConfigurationList; 648 | buildConfigurations = ( 649 | 7177F9F91C03F14900544DBE /* Debug */, 650 | 7177F9FA1C03F14900544DBE /* Release */, 651 | ); 652 | defaultConfigurationIsVisible = 0; 653 | defaultConfigurationName = Release; 654 | }; 655 | 7177F9FB1C03F14900544DBE /* Build configuration list for PBXNativeTarget "CityListDemoUITests" */ = { 656 | isa = XCConfigurationList; 657 | buildConfigurations = ( 658 | 7177F9FC1C03F14900544DBE /* Debug */, 659 | 7177F9FD1C03F14900544DBE /* Release */, 660 | ); 661 | defaultConfigurationIsVisible = 0; 662 | defaultConfigurationName = Release; 663 | }; 664 | /* End XCConfigurationList section */ 665 | }; 666 | rootObject = 7177F9C51C03F14900544DBE /* Project object */; 667 | } 668 | -------------------------------------------------------------------------------- /CityListDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CityListDemo.xcodeproj/project.xcworkspace/xcuserdata/ray.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/panyaorui/CityList/b541fc795db93809fffa11d2fb53c2de02f7ad08/CityListDemo.xcodeproj/project.xcworkspace/xcuserdata/ray.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /CityListDemo.xcodeproj/xcuserdata/ray.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 30 | 31 | 32 | 34 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /CityListDemo.xcodeproj/xcuserdata/ray.xcuserdatad/xcschemes/CityListDemo.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 | -------------------------------------------------------------------------------- /CityListDemo.xcodeproj/xcuserdata/ray.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CityListDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 7177F9CC1C03F14900544DBE 16 | 17 | primary 18 | 19 | 20 | 7177F9E01C03F14900544DBE 21 | 22 | primary 23 | 24 | 25 | 7177F9EB1C03F14900544DBE 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /CityListDemo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CityListDemo 4 | // 5 | // Created by ray on 15/11/24. 6 | // Copyright © 2015年 ray. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | var rootViewController:MainViewController!; 16 | 17 | 18 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 19 | 20 | self.window = UIWindow(frame: UIScreen.mainScreen().bounds); 21 | self.window?.backgroundColor = UIColor.blueColor(); 22 | rootViewController = MainViewController(nibName: "MainViewController", bundle: nil); 23 | let nav:UINavigationController = UINavigationController(rootViewController: rootViewController); 24 | self.window?.rootViewController = nav; 25 | self.window?.makeKeyAndVisible(); 26 | 27 | return true 28 | } 29 | 30 | func applicationWillResignActive(application: UIApplication) { 31 | // 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. 32 | // 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. 33 | } 34 | 35 | func applicationDidEnterBackground(application: UIApplication) { 36 | // 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. 37 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 38 | } 39 | 40 | func applicationWillEnterForeground(application: UIApplication) { 41 | // 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. 42 | } 43 | 44 | func applicationDidBecomeActive(application: UIApplication) { 45 | // 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. 46 | } 47 | 48 | func applicationWillTerminate(application: UIApplication) { 49 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 50 | } 51 | 52 | 53 | } 54 | 55 | -------------------------------------------------------------------------------- /CityListDemo/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 | } -------------------------------------------------------------------------------- /CityListDemo/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 | -------------------------------------------------------------------------------- /CityListDemo/CityListDemo-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | /** 拼音搜索 */ 6 | #include "ZYPinYinSearch.h" 7 | 8 | /** 定位*/ 9 | #include 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /CityListDemo/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 | NSLocationWhenInUseUsageDescription 26 | YES 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | LaunchScreen 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /CityListDemo/LocationManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LocationManager.swift 3 | // CityListDemo 4 | // 获取当前城市 5 | // Created by ray on 15/12/8. 6 | // Copyright © 2015年 ray. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol LocationManagerDelegate{ 12 | func locationCity(cityName:String); 13 | } 14 | 15 | class LocationManager: NSObject,CLLocationManagerDelegate { 16 | /** 获取城市位置代理*/ 17 | var delegate:LocationManagerDelegate?; 18 | /** 位置管理*/ 19 | var locationManager:CLLocationManager?; 20 | 21 | override init() { 22 | super.init(); 23 | } 24 | 25 | /** 获取当前城市*/ 26 | func startLocationCity(){ 27 | 28 | if(CLLocationManager.locationServicesEnabled()){ //开启定位 29 | locationManager = CLLocationManager(); 30 | locationManager!.delegate = self; 31 | locationManager!.desiredAccuracy = kCLLocationAccuracyBestForNavigation; 32 | locationManager!.distanceFilter = 100; 33 | // self.location!.desiredAccuracy = kCLLocationAccuracyBestForNavigation 34 | if #available(iOS 8.0, *) { 35 | self.locationManager!.requestWhenInUseAuthorization() 36 | } else { 37 | // Fallback on earlier versions 38 | } 39 | 40 | 41 | 42 | }else{//未开启定位 43 | print("未开启gps"); 44 | } 45 | locationManager!.startUpdatingLocation(); 46 | 47 | } 48 | func locationManager(manager: CLLocationManager, didFailWithError error: NSError) { 49 | 50 | } 51 | 52 | func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 53 | if(locations.count >= 1){ 54 | let location:CLLocation = locations[locations.count - 1]; 55 | self.locationManager!.stopUpdatingLocation(); 56 | let geocoder:CLGeocoder = CLGeocoder(); 57 | geocoder.reverseGeocodeLocation(location, completionHandler: { (placemarks:[CLPlacemark]?, NSError) -> Void in 58 | if(placemarks != nil && placemarks!.count >= 1){ 59 | let placemar:CLPlacemark = placemarks![0]; 60 | var city:String? = placemar.locality; 61 | if(city == nil){ //当前城市为 62 | city = placemar.administrativeArea; 63 | } 64 | if(self.delegate != nil){ 65 | self.delegate!.locationCity(city!); 66 | } 67 | } 68 | }) 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /CityListDemo/MainViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.swift 3 | // CityListDemo 4 | // 5 | // Created by ray on 15/12/9. 6 | // Copyright © 2015年 ray. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class MainViewController: UIViewController,CityViewControllerDelegate { 12 | 13 | @IBOutlet weak var btnCity: UIButton! 14 | var cityController:CityViewController!; 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | 19 | } 20 | 21 | 22 | @IBAction func actionCity(sender: AnyObject) { 23 | cityController = CityViewController(nibName: "CityViewController", bundle: nil); 24 | cityController.delegate = self; 25 | self.presentViewController(cityController, animated: true) { () -> Void in 26 | 27 | } 28 | } 29 | 30 | func selectCity(city: String) { 31 | self.btnCity.setTitle(city, forState: UIControlState.Normal); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /CityListDemo/MainViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /CityListDemoTests/CityListDemoTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CityListDemoTests.swift 3 | // CityListDemoTests 4 | // 5 | // Created by ray on 15/11/24. 6 | // Copyright © 2015年 ray. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import CityListDemo 11 | 12 | class CityListDemoTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /CityListDemoTests/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 | -------------------------------------------------------------------------------- /CityListDemoUITests/CityListDemoUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CityListDemoUITests.swift 3 | // CityListDemoUITests 4 | // 5 | // Created by ray on 15/11/24. 6 | // Copyright © 2015年 ray. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CityListDemoUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // 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. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /CityListDemoUITests/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 | -------------------------------------------------------------------------------- /CityListView/CityButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CityButton.swift 3 | // CityListDemo 4 | // 5 | // Created by ray on 15/11/30. 6 | // Copyright © 2015年 ray. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CityButton: UIButton { 12 | 13 | required init(coder aDecoder: NSCoder) 14 | { 15 | super.init(coder: aDecoder)!; 16 | 17 | //添加圆角 18 | self.layer.cornerRadius = 3; 19 | self.layer.masksToBounds = true; 20 | 21 | //添加变宽 22 | self.layer.borderWidth = 1; 23 | self.layer.borderColor = UIColor(red: 190 / 255, green: 190 / 255, blue: 190 / 255, alpha: 1).CGColor; 24 | 25 | } 26 | override init(frame: CGRect) { 27 | super.init(frame: frame); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /CityListView/CityViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CityViewController.swift 3 | // CityListDemo 4 | // 5 | // Created by ray on 15/11/24. 6 | // Copyright © 2015年 ray. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol CityViewControllerDelegate{ 12 | func selectCity(city:String); 13 | } 14 | 15 | class CityViewController: UIViewController,UISearchDisplayDelegate,UITableViewDelegate,UITableViewDataSource,CLLocationManagerDelegate,LocationManagerDelegate { 16 | 17 | @IBOutlet weak var layoutTopConstraint: NSLayoutConstraint! 18 | @IBOutlet var searchDC: UISearchDisplayController! 19 | @IBOutlet weak var searchBar: UISearchBar! 20 | @IBOutlet weak var tableview: UITableView! 21 | 22 | /** 回调接口*/ 23 | var delegate:CityViewControllerDelegate?; 24 | 25 | 26 | 27 | //城市数据库 28 | var dict:NSMutableDictionary!; 29 | //所有城市名称 30 | var cityArray:NSMutableArray!; 31 | //所有城市拼音首字母 32 | var citySpell:NSMutableArray!; 33 | //所有城市拼音首字母 34 | var sectionCitySpell:NSMutableArray!; 35 | //搜索到得城市 36 | var searchCityArray:NSArray!; 37 | //城市管理 38 | var locationManager:LocationManager!; 39 | //当前定位城市名称 40 | var cityName:String = "正在获取..."; 41 | //最近访问城市 42 | var historyCitys = ["北京","上海","广州"]; 43 | //热门城市 44 | let hotCitys = ["上海","北京","广州","深圳","武汉","天津","西安","南京","杭州"]; 45 | //最近访问城市数据 46 | var dataHistoryCitys:SpecifyArray!; 47 | let keyHistory = "keyHistory"; 48 | 49 | 50 | 51 | 52 | 53 | 54 | override func viewDidLoad() { 55 | super.viewDidLoad() 56 | self.title = "选择城市"; 57 | 58 | cityArray = NSMutableArray(); 59 | citySpell = NSMutableArray(); 60 | searchCityArray = NSArray(); 61 | dataHistoryCitys = SpecifyArray(max: 3); 62 | 63 | getCityData(); 64 | 65 | } 66 | 67 | /** 68 | 装在城市数据信息 69 | */ 70 | private func getCityData(){ 71 | //获取当前城市 72 | locationManager = LocationManager(); 73 | locationManager.delegate = self; 74 | locationManager.startLocationCity(); 75 | //获取最近放问城市 76 | var object = NSUserDefaults.standardUserDefaults().arrayForKey(keyHistory); 77 | if(object == nil){ 78 | self.dataHistoryCitys.addObject("北京"); 79 | }else{ 80 | self.dataHistoryCitys.addArray(object!); 81 | } 82 | self.historyCitys = self.dataHistoryCitys.getaArray() as! [String]; 83 | 84 | let path = NSBundle.mainBundle().pathForResource("citydict", ofType: "plist"); 85 | self.dict = NSMutableDictionary(contentsOfFile: path!); 86 | let key:NSArray = self.dict.allKeys; 87 | self.citySpell.addObjectsFromArray(key.sortedArrayUsingSelector(Selector("compare:"))); 88 | self.sectionCitySpell = NSMutableArray(); 89 | self.sectionCitySpell.addObjectsFromArray(["定位城市","最近访问城市","热门城市"]); 90 | self.sectionCitySpell.addObjectsFromArray(self.citySpell as [AnyObject]); 91 | let allValue:NSArray = self.dict.allValues; 92 | for oneArr in allValue{ 93 | for cityName in oneArr as! NSArray{ 94 | self.cityArray.addObject(cityName); 95 | } 96 | } 97 | 98 | } 99 | 100 | /** 对城市名称进行排序*/ 101 | private func cityNameSort(str1:NSString,str2:String,context:Void)->NSComparisonResult{ 102 | return str1.localizedCompare(str2); 103 | } 104 | private func handlerSearch(searchString:String?){ 105 | if(searchString == nil){ 106 | return; 107 | } 108 | 109 | //判断是否清空数据 110 | if(searchString!.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) > 0){ 111 | let array:NSArray = self.cityArray; 112 | let result:NSArray = ZYPinYinSearch.searchWithOriginalArray(array as [AnyObject], andSearchText: searchString, andSearchByPropertyName: ""); 113 | self.searchCityArray = result.sortedArrayUsingSelector(Selector("compare:")); 114 | }else{ //清空数据 115 | 116 | } 117 | } 118 | 119 | /** 120 | 将选中城市名称返回并关闭当前页面 121 | - parameter city: 城市名称 122 | */ 123 | private func selectCity(city:String){ 124 | 125 | if(self.delegate != nil){ 126 | dataHistoryCitys.addObject(city); 127 | NSUserDefaults.standardUserDefaults().setObject(dataHistoryCitys.getaArray(), forKey: keyHistory); 128 | self.delegate!.selectCity(city); 129 | self.dismissViewControllerAnimated(true , completion: { () -> Void in 130 | }) 131 | } 132 | 133 | } 134 | 135 | //////////////////// UITableViewDataSource //////////////////// 136 | 137 | internal func tableView(table: UITableView, numberOfRowsInSection section: Int) -> Int{ 138 | 139 | if(!self.tableview.isEqual(table)){ //搜索结果时 140 | return self.searchCityArray.count; 141 | } 142 | 143 | if(section < 3){ 144 | return 1; 145 | } 146 | let key:NSString = self.sectionCitySpell.objectAtIndex(section) as! NSString; 147 | return self.dict.objectForKey(key)!.count; 148 | } 149 | 150 | func numberOfSectionsInTableView(table: UITableView) -> Int { 151 | 152 | if(!self.tableview.isEqual(table)){ //搜索结果时 153 | return 1; 154 | } 155 | return self.sectionCitySpell.count; 156 | } 157 | 158 | func sectionIndexTitlesForTableView(table: UITableView) -> [String]? { 159 | if(!self.tableview.isEqual(table)){ //搜索结果时 160 | return nil; 161 | } 162 | let arr01:NSArray = self.citySpell; 163 | let arr02:NSArray = NSArray(array: ["#","$"," *"]).arrayByAddingObjectsFromArray(arr01 as [AnyObject]); 164 | 165 | return arr02 as? [String]; 166 | } 167 | 168 | func tableView(table: UITableView, viewForHeaderInSection section: Int) -> UIView? { 169 | let view:SectionView = SectionView.viewFromNibNamed(); 170 | if(!self.tableview.isEqual(table)){ //搜索结果时 171 | view.addData(self.citySpell.objectAtIndex(section) as! String); 172 | }else{ 173 | view.addData(self.sectionCitySpell.objectAtIndex(section) as! String); 174 | } 175 | 176 | return view; 177 | } 178 | 179 | func tableView(tableView: UITableView, section: Int) -> CGFloat { 180 | return 30; 181 | } 182 | 183 | func tableView(table: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat 184 | { 185 | if((indexPath.section == 0 || indexPath.section == 1) && self.tableview.isEqual(table)){ 186 | return 70; 187 | } 188 | if(indexPath.section == 2 && self.tableview.isEqual(table)){ 189 | return 175; 190 | } 191 | return 40; 192 | } 193 | 194 | internal func tableView(table: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ 195 | 196 | let identifierHead = "cellHead"; 197 | let identifier = "cell"; 198 | var cellHead:TableViewHeadSectionCell? = table.dequeueReusableCellWithIdentifier(identifierHead) as? TableViewHeadSectionCell; 199 | var cell:TableViewCell? = table.dequeueReusableCellWithIdentifier(identifier) as? TableViewCell; 200 | let section = indexPath.section; 201 | 202 | if((section == 2 || section == 0 || section == 1) && self.tableview.isEqual(table)){ //如果为头部Section 203 | 204 | if(cellHead == nil){ 205 | let nib:UINib = UINib(nibName: "TableViewHeadSectionCell", bundle: NSBundle.mainBundle()); 206 | table.registerNib(nib, forCellReuseIdentifier: identifierHead); 207 | cellHead = table.dequeueReusableCellWithIdentifier(identifierHead) as? TableViewHeadSectionCell; 208 | } 209 | //添加数据 210 | switch(section){ 211 | case 0: //定位城市 212 | cellHead!.addData([self.cityName], city: selectCity) 213 | cellHead!.reloadData(); 214 | break; 215 | case 1: // 最近使用城市 216 | cellHead!.addData(historyCitys, city: selectCity); 217 | 218 | break; 219 | case 2: // 热门城市 220 | cellHead!.addData(hotCitys, city: selectCity) 221 | break; 222 | 223 | default: 224 | break; 225 | } 226 | 227 | return cellHead!; 228 | 229 | } 230 | // 普通城市数据 231 | if(cell == nil){ 232 | let nib:UINib = UINib(nibName: "TableViewCell", bundle: NSBundle.mainBundle()); 233 | table.registerNib(nib, forCellReuseIdentifier: identifier); 234 | cell = table.dequeueReusableCellWithIdentifier(identifier) as? TableViewCell; 235 | } 236 | //添加数据 237 | var key:NSString = ""; 238 | if(self.tableview.isEqual(table)){ 239 | key = self.sectionCitySpell.objectAtIndex(indexPath.section) as! NSString; 240 | cell!.setData(self.dict.objectForKey(key)!.objectAtIndex(indexPath.row) as! String); 241 | }else{ 242 | cell!.setData(self.searchCityArray.objectAtIndex(indexPath.row) as! String); 243 | } 244 | 245 | return cell!; 246 | } 247 | 248 | //////////////////// UITableViewDelegate //////////////////// 249 | 250 | func tableView(table: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 251 | if(self.delegate != nil ){ 252 | var cityName:String = ""; 253 | if(table != self.tableview){ 254 | cityName = self.searchCityArray.objectAtIndex(indexPath.row) as! String; 255 | }else{ 256 | let section = indexPath.section; 257 | if(section > 2){//列表城市 258 | let key:NSString = self.sectionCitySpell.objectAtIndex(section) as! NSString; 259 | cityName = self.dict.objectForKey(key)!.objectAtIndex(indexPath.row) as! String; 260 | } 261 | } 262 | self.selectCity(cityName); 263 | } 264 | } 265 | 266 | 267 | 268 | //////////////////// UISearchDisplayDelegate //////////////////// 269 | 270 | /** 271 | 即将开始搜索 272 | */ 273 | internal func searchDisplayControllerWillBeginSearch(controller: UISearchDisplayController){ 274 | self.layoutTopConstraint.constant = 20; 275 | UIView.animateWithDuration(0.3) { () -> Void in 276 | self.view.layoutIfNeeded(); 277 | } 278 | } 279 | 280 | /** 281 | 搜索结束 282 | */ 283 | internal func searchDisplayControllerWillEndSearch(controller: UISearchDisplayController){ 284 | self.layoutTopConstraint.constant = 65; 285 | } 286 | 287 | //shouldReloadTableForSearchString 288 | func searchDisplayController(controller: UISearchDisplayController, shouldReloadTableForSearchString searchString: String?) -> Bool { 289 | 290 | self.handlerSearch(searchString); 291 | return true; 292 | } 293 | 294 | //////////////////// LocationManagerDelegate //////////////////// 295 | 296 | /** 297 | 获取到当前城市 298 | - parameter cityName: 城市名称 299 | */ 300 | func locationCity(cityName: String) { 301 | self.cityName = cityName; 302 | let indexPath:NSIndexPath = NSIndexPath(forRow: 0, inSection: 0); 303 | self.tableview.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None); 304 | } 305 | 306 | } 307 | -------------------------------------------------------------------------------- /CityListView/CityViewController.xib: -------------------------------------------------------------------------------- 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 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /CityListView/CollectionViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionViewCell.swift 3 | // CityListDemo 4 | // 5 | // Created by ray on 15/12/2. 6 | // Copyright © 2015年 ray. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CollectionViewCell: UICollectionViewCell { 12 | 13 | @IBOutlet weak var button: CityButton! 14 | 15 | override func awakeFromNib() { 16 | super.awakeFromNib() 17 | 18 | } 19 | 20 | func addData(str:String){ 21 | self.button.setTitle(str, forState: UIControlState.Normal); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /CityListView/CollectionViewCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /CityListView/Resource/citydict.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A 6 | 7 | 阿坝藏族羌族自治州 8 | 阿克苏地区 9 | 阿拉尔 10 | 阿拉善盟 11 | 阿勒泰地区 12 | 阿里地区 13 | 安康 14 | 安庆 15 | 安顺 16 | 安阳 17 | 鞍山 18 | 澳门特别行政区 19 | 20 | B 21 | 22 | 巴彦淖尔 23 | 巴音郭楞蒙古自治州 24 | 巴中 25 | 白城 26 | 白沙黎族自治县 27 | 白山 28 | 白银 29 | 百色 30 | 蚌埠 31 | 包头 32 | 宝鸡 33 | 保定 34 | 保山 35 | 保亭黎族苗族自治县 36 | 北海 37 | 北京 38 | 本溪 39 | 毕节地区 40 | 滨州 41 | 亳州 42 | 博尔塔拉蒙古自治州 43 | 44 | C 45 | 46 | 沧州 47 | 昌都地区 48 | 昌吉回族自治州 49 | 昌江黎族自治县 50 | 长春 51 | 长沙 52 | 长治 53 | 常德 54 | 常州 55 | 巢湖 56 | 朝阳 57 | 潮州 58 | 郴州 59 | 成都 60 | 承德 61 | 澄迈县 62 | 池州 63 | 赤峰 64 | 崇左 65 | 滁州 66 | 楚雄彝族自治州 67 | 68 | D 69 | 70 | 达州 71 | 大理白族自治州 72 | 大连 73 | 大庆 74 | 大同 75 | 大兴安岭地区 76 | 丹东 77 | 儋州 78 | 德宏傣族景颇族自治州 79 | 德阳 80 | 德州 81 | 迪庆藏族自治州 82 | 定安县 83 | 定西 84 | 东方 85 | 东莞 86 | 东营 87 | 88 | E 89 | 90 | 鄂尔多斯 91 | 鄂州 92 | 恩施土家族苗族自治州 93 | 94 | F 95 | 96 | 防城港 97 | 佛山 98 | 福州 99 | 抚顺 100 | 抚州 101 | 阜新 102 | 阜阳 103 | 104 | G 105 | 106 | 甘南藏族自治州 107 | 甘孜藏族自治州 108 | 赣州 109 | 高雄 110 | 高雄县 111 | 固原 112 | 广安 113 | 广元 114 | 广州 115 | 贵港 116 | 贵阳 117 | 桂林 118 | 果洛藏族自治州 119 | 120 | H 121 | 122 | 哈尔滨 123 | 哈密地区 124 | 海外 125 | 海北藏族自治州 126 | 海东地区 127 | 海口 128 | 海南藏族自治州 129 | 海西蒙古族藏族自治州 130 | 邯郸 131 | 汉中 132 | 杭州 133 | 合肥 134 | 和田地区 135 | 河池 136 | 河源 137 | 菏泽 138 | 贺州 139 | 鹤壁 140 | 鹤岗 141 | 黑河 142 | 衡水 143 | 衡阳 144 | 红河哈尼族彝族自治州 145 | 呼和浩特 146 | 呼伦贝尔 147 | 湖州 148 | 葫芦岛 149 | 花莲县 150 | 怀化 151 | 淮安 152 | 淮北 153 | 淮南 154 | 黄冈 155 | 黄南藏族自治州 156 | 黄山 157 | 黄石 158 | 惠州 159 | 160 | J 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 | 酒泉 187 | 188 | K 189 | 190 | 喀什地区 191 | 开封 192 | 克拉玛依 193 | 克孜勒苏柯尔克孜自治州 194 | 昆明 195 | 196 | L 197 | 198 | 拉萨 199 | 来宾 200 | 莱芜 201 | 兰州 202 | 廊坊 203 | 乐东黎族自治县 204 | 乐山 205 | 丽江 206 | 丽水 207 | 连云港 208 | 凉山彝族自治州 209 | 辽阳 210 | 辽源 211 | 聊城 212 | 林芝地区 213 | 临沧 214 | 临汾 215 | 临高县 216 | 临夏回族自治州 217 | 临沂 218 | 陵水黎族自治县 219 | 柳州 220 | 六安 221 | 六盘水 222 | 龙岩 223 | 陇南 224 | 娄底 225 | 泸州 226 | 吕梁 227 | 洛阳 228 | 漯河 229 | 230 | M 231 | 232 | 马鞍山 233 | 茂名 234 | 眉山 235 | 梅州 236 | 绵阳 237 | 苗栗县 238 | 牡丹江 239 | 240 | N 241 | 242 | 内江 243 | 那曲地区 244 | 南昌 245 | 南充 246 | 南京 247 | 南宁 248 | 南平 249 | 南沙群岛 250 | 南通 251 | 南投县 252 | 南阳 253 | 宁波 254 | 宁德 255 | 怒江傈僳族自治州 256 | 257 | P 258 | 259 | 攀枝花 260 | 盘锦 261 | 澎湖县 262 | 平顶山 263 | 平凉 264 | 屏东县 265 | 萍乡 266 | 莆田 267 | 濮阳 268 | 269 | Q 270 | 271 | 七台河 272 | 齐齐哈尔 273 | 其他 274 | 潜江 275 | 黔东南苗族侗族自治州 276 | 黔南布依族苗族自治州 277 | 黔西南布依族苗族自治州 278 | 钦州 279 | 秦皇岛 280 | 青岛 281 | 清远 282 | 庆阳 283 | 琼海 284 | 琼中黎族苗族自治县 285 | 曲靖 286 | 衢州 287 | 泉州 288 | 289 | R 290 | 291 | 日喀则地区 292 | 日照 293 | 294 | S 295 | 296 | 三门峡 297 | 三明 298 | 三亚 299 | 山南地区 300 | 汕头 301 | 汕尾 302 | 商洛 303 | 商丘 304 | 上海 305 | 上饶 306 | 韶关 307 | 邵阳 308 | 绍兴 309 | 深圳 310 | 神农架林区 311 | 沈阳 312 | 十堰 313 | 石河子 314 | 石家庄 315 | 石嘴山 316 | 双鸭山 317 | 朔州 318 | 思茅 319 | 四平 320 | 松原 321 | 苏州 322 | 宿迁 323 | 宿州 324 | 绥化 325 | 随州 326 | 遂宁 327 | 328 | T 329 | 330 | 塔城地区 331 | 台北 332 | 台北县 333 | 台东县 334 | 台南 335 | 台南县 336 | 台中 337 | 台中县 338 | 台州 339 | 太原 340 | 泰安 341 | 泰州 342 | 唐山 343 | 桃园县 344 | 天津 345 | 天门 346 | 天水 347 | 铁岭 348 | 通化 349 | 通辽 350 | 铜川 351 | 铜陵 352 | 铜仁地区 353 | 图木舒克 354 | 吐鲁番地区 355 | 屯昌县 356 | 357 | W 358 | 359 | 无锡 360 | 万宁 361 | 威海 362 | 潍坊 363 | 渭南 364 | 温州 365 | 文昌 366 | 文山壮族苗族自治州 367 | 乌海 368 | 乌兰察布 369 | 乌鲁木齐 370 | 吴忠 371 | 芜湖 372 | 梧州 373 | 五家渠 374 | 五指山 375 | 武汉 376 | 武威 377 | 378 | X 379 | 380 | 西安 381 | 西宁 382 | 西沙群岛 383 | 西双版纳傣族自治州 384 | 锡林郭勒盟 385 | 厦门 386 | 仙桃 387 | 咸宁 388 | 咸阳 389 | 香港特别行政区 390 | 湘潭 391 | 湘西土家族苗族自治州 392 | 襄樊 393 | 孝感 394 | 忻州 395 | 新乡 396 | 新余 397 | 新竹 398 | 新竹县 399 | 信阳 400 | 兴安盟 401 | 邢台 402 | 徐州 403 | 许昌 404 | 宣城 405 | 406 | Y 407 | 408 | 雅安 409 | 烟台 410 | 延安 411 | 延边朝鲜族自治州 412 | 盐城 413 | 扬州 414 | 阳江 415 | 阳泉 416 | 伊春 417 | 伊犁哈萨克自治州 418 | 宜宾 419 | 宜昌 420 | 宜春 421 | 宜兰县 422 | 益阳 423 | 银川 424 | 鹰潭 425 | 营口 426 | 永州 427 | 榆林 428 | 玉林 429 | 玉树藏族自治州 430 | 玉溪 431 | 岳阳 432 | 云浮 433 | 云林县 434 | 运城 435 | 436 | Z 437 | 438 | 枣庄 439 | 湛江 440 | 张家界 441 | 张家口 442 | 张掖 443 | 彰化县 444 | 漳州 445 | 昭通 446 | 肇庆 447 | 镇江 448 | 郑州 449 | 中沙群岛的岛礁及其海域 450 | 中山 451 | 中卫 452 | 重庆 453 | 舟山 454 | 周口 455 | 株洲 456 | 珠海 457 | 驻马店 458 | 资阳 459 | 淄博 460 | 自贡 461 | 遵义 462 | 463 | 464 | -------------------------------------------------------------------------------- /CityListView/SectionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SectionView.swift 3 | // CityListDemo 4 | // 5 | // Created by ray on 15/11/30. 6 | // Copyright © 2015年 ray. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SectionView: UIView { 12 | 13 | @IBOutlet weak var labelCityName: UILabel! 14 | 15 | class func viewFromNibNamed()->SectionView 16 | { 17 | return NSBundle.mainBundle().loadNibNamed("SectionView", owner: self, options: nil)[0] as! SectionView; 18 | } 19 | 20 | func addData(string:String){ 21 | self.labelCityName.text = string; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /CityListView/SectionView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /CityListView/TableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewCell.swift 3 | // CityListDemo 4 | // 5 | // Created by ray on 15/11/24. 6 | // Copyright © 2015年 ray. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TableViewCell: UITableViewCell { 12 | 13 | @IBOutlet weak var cityName: UILabel! 14 | override func awakeFromNib() { 15 | super.awakeFromNib() 16 | } 17 | 18 | override func setSelected(selected: Bool, animated: Bool) { 19 | super.setSelected(selected, animated: animated) 20 | 21 | } 22 | 23 | func setData(cityName:String){ 24 | self.cityName.text = cityName; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /CityListView/TableViewCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /CityListView/TableViewHeadSectionCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewHeadSectionCell.swift 3 | // CityListDemo 4 | // 5 | // Created by ray on 15/12/1. 6 | // Copyright © 2015年 ray. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TableViewHeadSectionCell: UITableViewCell,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout { 12 | 13 | var delegate:CityViewControllerDelegate?; 14 | //回调函数 15 | var action = {(str:String) -> Void in 16 | 17 | } 18 | 19 | 20 | @IBOutlet weak var collectionView: UICollectionView! 21 | 22 | private var data = [String]!(); 23 | override func awakeFromNib() { 24 | super.awakeFromNib() 25 | 26 | } 27 | 28 | override func setSelected(selected: Bool, animated: Bool) { 29 | super.setSelected(selected, animated: animated) 30 | 31 | } 32 | 33 | func addData(data:[String],city:(cityName:String)->Void){ 34 | self.data = data; 35 | self.action = city; 36 | } 37 | 38 | func reloadData(){ 39 | self.collectionView.reloadData(); 40 | } 41 | 42 | //////////////////// UICollectionViewDataSource //////////////////// 43 | 44 | func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{ 45 | return data!.count; 46 | } 47 | 48 | 49 | func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell{ 50 | let nib = UINib(nibName: "CollectionViewCell", bundle: NSBundle.mainBundle()); 51 | collectionView.registerNib(nib, forCellWithReuseIdentifier: "cell"); 52 | let cell:CollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CollectionViewCell; 53 | cell.addData(self.data[indexPath.row]); 54 | return cell; 55 | } 56 | 57 | //////////////////// UICollectionViewDelegateFlowLayout //////////////////// 58 | 59 | /** 每一个cell的大小 **/ 60 | func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize 61 | { 62 | let widht = UIScreen.mainScreen().bounds.size.width; 63 | return CGSizeMake(widht / 3 - 20,40); 64 | } 65 | 66 | /** 设置每组的cell的边界 **/ 67 | func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets 68 | { 69 | return UIEdgeInsets(top: 0, left:0, bottom: 0, right: 0); 70 | } 71 | 72 | //////////////////// UICollectionViewDelegate //////////////////// 73 | 74 | func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { 75 | let cityName:String = data[indexPath.row]; 76 | self.action(cityName); 77 | // print(cityName); 78 | } 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /CityListView/TableViewHeadSectionCell.xib: -------------------------------------------------------------------------------- 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 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /CityListView/Util/SpecifyArray.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SpecifyArray.swift 3 | // CityListDemo 4 | // 5 | // Created by ray on 15/12/10. 6 | // Copyright © 2015年 ray. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SpecifyArray: NSObject { 12 | 13 | var array:NSMutableArray = NSMutableArray(); 14 | 15 | 16 | var maxCount:Int = 10{ 17 | didSet{ 18 | if(maxCount <= 0){ 19 | maxCount = 10; 20 | } 21 | } 22 | } 23 | 24 | init(max:Int) { 25 | super.init(); 26 | maxCount = max; 27 | } 28 | 29 | func addObject(object:NSObject){ 30 | array.addObject(object); 31 | if(array.count > maxCount && array.count > 1){ 32 | array.removeObjectAtIndex(0); 33 | } 34 | } 35 | 36 | func count()->Int{ 37 | return array.count; 38 | } 39 | 40 | func getaArray()->NSArray{ 41 | return array; 42 | } 43 | 44 | func addArray(arr:NSArray){ 45 | // self.array = array as! NSMutableArray; 46 | self.array = NSMutableArray(array: arr); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 定位和选择城市 2 | 3 | ## 动画效果 4 | 5 | ![image](https://github.com/panyaorui/CityList/blob/master/效果图/01.gif) 6 | 7 | 8 | ##使用说明 9 | ### 1.引用CoreLocation类库用于定位服务 10 | ![image](https://github.com/panyaorui/CityList/blob/master/效果图/02.png) 11 | 12 | ### 2.设置定位权限NSLocationWhenInUseUsageDescription(使用应用程序时允许定位) 13 | ![image](https://github.com/panyaorui/CityList/blob/master/效果图/03.png) 14 | 15 | ### 3.直接跳转CityViewController即可 16 | ```swift 17 | var cityViewController:CityViewController = CityViewController(nibName: "CityViewController", bundle: nil); 18 | self.presentViewController(cityViewController, animated: true) { () -> Void in 19 | 20 | } 21 | ``` 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ZYPinYinSearchLib/ChineseInclude.h: -------------------------------------------------------------------------------- 1 | // 2 | // ChineseInclude.h 3 | // Search 4 | // 5 | // Created by LYZ on 14-1-24. 6 | // Copyright (c) 2014年 LYZ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ChineseInclude : NSObject 12 | + (BOOL)isIncludeChineseInString:(NSString*)str; 13 | @end 14 | -------------------------------------------------------------------------------- /ZYPinYinSearchLib/ChineseInclude.m: -------------------------------------------------------------------------------- 1 | // 2 | // ChineseInclude.m 3 | // Search 4 | // 5 | // Created by LYZ on 14-1-24. 6 | // Copyright (c) 2014年 LYZ. All rights reserved. 7 | // 8 | 9 | #import "ChineseInclude.h" 10 | 11 | @implementation ChineseInclude 12 | + (BOOL)isIncludeChineseInString:(NSString*)str { 13 | for (int i=0; i 10 | @class NSArray; 11 | @class NSMutableDictionary; 12 | 13 | @interface ChineseToPinyinResource : NSObject { 14 | NSString* _directory; 15 | NSDictionary *_unicodeToHanyuPinyinTable; 16 | } 17 | //@property(nonatomic, strong)NSDictionary *unicodeToHanyuPinyinTable; 18 | 19 | - (id)init; 20 | - (void)initializeResource; 21 | - (NSArray *)getHanyuPinyinStringArrayWithChar:(unichar)ch; 22 | - (BOOL)isValidRecordWithNSString:(NSString *)record; 23 | - (NSString *)getHanyuPinyinRecordFromCharWithChar:(unichar)ch; 24 | + (ChineseToPinyinResource *)getInstance; 25 | 26 | @end 27 | 28 | 29 | 30 | #endif // _ChineseToPinyinResource_H_ 31 | -------------------------------------------------------------------------------- /ZYPinYinSearchLib/ChineseToPinyinResource.m: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // 4 | // Created by kimziv on 13-9-14. 5 | // 6 | 7 | #include "ChineseToPinyinResource.h" 8 | #define LEFT_BRACKET @"(" 9 | #define RIGHT_BRACKET @")" 10 | #define COMMA @"," 11 | 12 | #define kCacheKeyForUnicode2Pinyin @"cache.key.for.unicode.to.pinyin" 13 | 14 | static inline NSString* cachePathForKey(NSString* directory, NSString* key) { 15 | return [directory stringByAppendingPathComponent:key]; 16 | } 17 | 18 | @interface ChineseToPinyinResource () 19 | - (id)cachedObjectForKey:(NSString*)key; 20 | -(void)cacheObjec:(id)obj forKey:(NSString *)key; 21 | 22 | @end 23 | 24 | @implementation ChineseToPinyinResource 25 | //@synthesize unicodeToHanyuPinyinTable=_unicodeToHanyuPinyinTable; 26 | //- (NSDictionary *)getUnicodeToHanyuPinyinTable { 27 | // return _unicodeToHanyuPinyinTable; 28 | //} 29 | 30 | - (id)init { 31 | if (self = [super init]) { 32 | _unicodeToHanyuPinyinTable = nil; 33 | [self initializeResource]; 34 | } 35 | return self; 36 | } 37 | 38 | - (void)initializeResource { 39 | NSString* cachesDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0]; 40 | NSString* oldCachesDirectory = [[[cachesDirectory stringByAppendingPathComponent:[[NSProcessInfo processInfo] processName]] stringByAppendingPathComponent:@"PinYinCache"] copy]; 41 | 42 | if([[NSFileManager defaultManager] fileExistsAtPath:oldCachesDirectory]) { 43 | [[NSFileManager defaultManager] removeItemAtPath:oldCachesDirectory error:NULL]; 44 | } 45 | 46 | _directory = [[[cachesDirectory stringByAppendingPathComponent:[[NSBundle mainBundle] bundleIdentifier]] stringByAppendingPathComponent:@"PinYinCache"] copy]; 47 | 48 | NSDictionary *dataMap=(NSDictionary *)[self cachedObjectForKey:kCacheKeyForUnicode2Pinyin]; 49 | if (dataMap) { 50 | self->_unicodeToHanyuPinyinTable=dataMap; 51 | }else{ 52 | NSString *resourceName =[[NSBundle mainBundle] pathForResource:@"unicode_to_hanyu_pinyin" ofType:@"txt"]; 53 | NSString *dictionaryText=[NSString stringWithContentsOfFile:resourceName encoding:NSUTF8StringEncoding error:nil]; 54 | NSArray *lines = [dictionaryText componentsSeparatedByString:@"\r\n"]; 55 | __block NSMutableDictionary *tempMap=[[NSMutableDictionary alloc] init]; 56 | @autoreleasepool { 57 | [lines enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 58 | NSArray *lineComponents=[obj componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 59 | //NSLog(@"%@, %@",lineComponents[0],lineComponents[1]); 60 | [tempMap setObject:lineComponents[1] forKey:lineComponents[0]]; 61 | }]; 62 | } 63 | self->_unicodeToHanyuPinyinTable=tempMap; 64 | [self cacheObjec:self->_unicodeToHanyuPinyinTable forKey:kCacheKeyForUnicode2Pinyin]; 65 | } 66 | } 67 | 68 | - (id)cachedObjectForKey:(NSString*)key 69 | { 70 | NSData *data = [NSData dataWithContentsOfFile:cachePathForKey(_directory, key) options:0 error:NULL]; 71 | if (data) { 72 | return [NSKeyedUnarchiver unarchiveObjectWithData:data]; 73 | } 74 | return nil; 75 | } 76 | 77 | -(void)cacheObjec:(id)obj forKey:(NSString *)key 78 | { 79 | NSData* data= [NSKeyedArchiver archivedDataWithRootObject:obj]; 80 | NSString* cachePath = cachePathForKey(_directory, key); 81 | dispatch_async(dispatch_get_main_queue(), ^{ 82 | [data writeToFile:cachePath atomically:YES]; 83 | }); 84 | } 85 | 86 | - (NSArray *)getHanyuPinyinStringArrayWithChar:(unichar)ch { 87 | NSString *pinyinRecord = [self getHanyuPinyinRecordFromCharWithChar:ch]; 88 | if (nil != pinyinRecord) { 89 | NSRange rangeOfLeftBracket= [pinyinRecord rangeOfString:LEFT_BRACKET]; 90 | NSRange rangeOfRightBracket= [pinyinRecord rangeOfString:RIGHT_BRACKET]; 91 | NSString *stripedString = [pinyinRecord substringWithRange:NSMakeRange(rangeOfLeftBracket.location+rangeOfLeftBracket.length, rangeOfRightBracket.location-rangeOfLeftBracket.location-rangeOfLeftBracket.length)]; 92 | return [stripedString componentsSeparatedByString:COMMA]; 93 | } 94 | else return nil; 95 | } 96 | 97 | - (BOOL)isValidRecordWithNSString:(NSString *)record { 98 | NSString *noneStr = @"(none0)"; 99 | if ((nil != record) && ![record isEqual:noneStr] && [record hasPrefix:LEFT_BRACKET] && [record hasSuffix:RIGHT_BRACKET]) { 100 | return YES; 101 | } 102 | else return NO; 103 | } 104 | 105 | - (NSString *)getHanyuPinyinRecordFromCharWithChar:(unichar)ch { 106 | int codePointOfChar = ch; 107 | NSString *codepointHexStr =[[NSString stringWithFormat:@"%x", codePointOfChar] uppercaseString]; 108 | NSString *foundRecord =[self->_unicodeToHanyuPinyinTable objectForKey:codepointHexStr]; 109 | return [self isValidRecordWithNSString:foundRecord] ? foundRecord : nil; 110 | } 111 | 112 | + (ChineseToPinyinResource *)getInstance { 113 | static ChineseToPinyinResource *sharedInstance=nil; 114 | static dispatch_once_t onceToken; 115 | dispatch_once(&onceToken, ^{ 116 | sharedInstance=[[self alloc] init]; 117 | }); 118 | return sharedInstance; 119 | } 120 | 121 | @end 122 | 123 | -------------------------------------------------------------------------------- /ZYPinYinSearchLib/HanyuPinyinOutputFormat.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by kimziv on 13-9-14. 3 | */ 4 | #ifndef _HanyuPinyinOutputFormat_H_ 5 | #define _HanyuPinyinOutputFormat_H_ 6 | #import 7 | typedef enum { 8 | ToneTypeWithToneNumber, 9 | ToneTypeWithoutTone, 10 | ToneTypeWithToneMark 11 | }ToneType; 12 | 13 | typedef enum { 14 | CaseTypeUppercase, 15 | CaseTypeLowercase 16 | }CaseType; 17 | 18 | typedef enum { 19 | VCharTypeWithUAndColon, 20 | VCharTypeWithV, 21 | VCharTypeWithUUnicode 22 | }VCharType; 23 | 24 | 25 | @interface HanyuPinyinOutputFormat : NSObject 26 | 27 | @property(nonatomic, assign) VCharType vCharType; 28 | @property(nonatomic, assign) CaseType caseType; 29 | @property(nonatomic, assign) ToneType toneType; 30 | 31 | - (id)init; 32 | - (void)restoreDefault; 33 | @end 34 | 35 | #endif // _HanyuPinyinOutputFormat_H_ 36 | -------------------------------------------------------------------------------- /ZYPinYinSearchLib/HanyuPinyinOutputFormat.m: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // 4 | // Created by kimziv on 13-9-14. 5 | // 6 | 7 | #include "HanyuPinyinOutputFormat.h" 8 | 9 | @implementation HanyuPinyinOutputFormat 10 | @synthesize vCharType=_vCharType; 11 | @synthesize caseType=_caseType; 12 | @synthesize toneType=_toneType; 13 | 14 | - (id)init { 15 | if (self = [super init]) { 16 | [self restoreDefault]; 17 | } 18 | return self; 19 | } 20 | 21 | - (void)restoreDefault { 22 | _vCharType = VCharTypeWithUAndColon; 23 | _caseType = CaseTypeLowercase; 24 | _toneType = ToneTypeWithToneNumber; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /ZYPinYinSearchLib/NSString+PinYin4Cocoa.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+PinYin4Cocoa.h 3 | // PinYin4Cocoa 4 | // 5 | // Created by kimziv on 13-9-15. 6 | // Copyright (c) 2013年 kimziv. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (PinYin4Cocoa) 12 | 13 | - (NSInteger)indexOfString:(NSString *)s; 14 | - (NSInteger)indexOfString:(NSString *)s fromIndex:(int)index; 15 | - (NSInteger)indexOf:(int)ch; 16 | - (NSInteger)indexOf:(int)ch fromIndex:(int)index; 17 | + (NSString *)valueOfChar:(unichar)value; 18 | 19 | -(NSString *) stringByReplacingRegexPattern:(NSString *)regex withString:(NSString *) replacement; 20 | -(NSString *) stringByReplacingRegexPattern:(NSString *)regex withString:(NSString *) replacement caseInsensitive:(BOOL) ignoreCase; 21 | -(NSString *) stringByReplacingRegexPattern:(NSString *)regex withString:(NSString *) replacement caseInsensitive:(BOOL) ignoreCase treatAsOneLine:(BOOL) assumeMultiLine; 22 | -(NSArray *) stringsByExtractingGroupsUsingRegexPattern:(NSString *)regex; 23 | -(NSArray *) stringsByExtractingGroupsUsingRegexPattern:(NSString *)regex caseInsensitive:(BOOL) ignoreCase treatAsOneLine:(BOOL) assumeMultiLine; 24 | -(BOOL) matchesPatternRegexPattern:(NSString *)regex; 25 | -(BOOL) matchesPatternRegexPattern:(NSString *)regex caseInsensitive:(BOOL) ignoreCase treatAsOneLine:(BOOL) assumeMultiLine; 26 | @end 27 | -------------------------------------------------------------------------------- /ZYPinYinSearchLib/NSString+PinYin4Cocoa.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+PinYin4Cocoa.m 3 | // PinYin4Cocoa 4 | // 5 | // Created by kimziv on 13-9-15. 6 | // Copyright (c) 2013年 kimziv. All rights reserved. 7 | // 8 | 9 | #import "NSString+PinYin4Cocoa.h" 10 | 11 | @implementation NSString (PinYin4Cocoa) 12 | 13 | 14 | - (NSInteger)indexOfString:(NSString *)s { 15 | NSAssert3((s!=nil), @"Error, s is a nil string, %s, %s, %d", __FILE__, __FUNCTION__, __LINE__); 16 | if ([s length] == 0) { 17 | return 0; 18 | } 19 | NSRange range = [self rangeOfString:s]; 20 | return range.location == NSNotFound ? -1 : (int) range.location; 21 | } 22 | 23 | 24 | - (NSInteger)indexOfString:(NSString *)s fromIndex:(int)index { 25 | NSAssert3((s!=nil), @"Error, s is a nil string, %s, %s, %d", __FILE__, __FUNCTION__, __LINE__); 26 | if ([s length] == 0) { 27 | return 0; 28 | } 29 | NSRange searchRange = NSMakeRange((NSUInteger) index, 30 | [self length] - (NSUInteger) index); 31 | NSRange range = [self rangeOfString:s 32 | options:NSLiteralSearch 33 | range:searchRange]; 34 | return range.location == NSNotFound ? -1 : (int) range.location; 35 | } 36 | 37 | - (NSInteger)indexOf:(int)ch { 38 | // unichar c = (unichar) ch; 39 | // for(int i=0;i 0); 133 | } 134 | 135 | -(BOOL) matchesPatternRegexPattern:(NSString *)regex { 136 | return [self matchesPatternRegexPattern:regex caseInsensitive:NO treatAsOneLine:NO]; 137 | } 138 | 139 | @end 140 | -------------------------------------------------------------------------------- /ZYPinYinSearchLib/PinYinForObjc.h: -------------------------------------------------------------------------------- 1 | // 2 | // PinYinForObjc.h 3 | // Search 4 | // 5 | // Created by LYZ on 14-1-24. 6 | // Copyright (c) 2014年 LYZ. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "HanyuPinyinOutputFormat.h" 11 | #import "PinyinHelper.h" 12 | 13 | @interface PinYinForObjc : NSObject 14 | 15 | + (NSString*)chineseConvertToPinYin:(NSString*)chinese;//转换为拼音 16 | + (NSString*)chineseConvertToPinYinHead:(NSString *)chinese;//转换为拼音首字母 17 | @end 18 | -------------------------------------------------------------------------------- /ZYPinYinSearchLib/PinYinForObjc.m: -------------------------------------------------------------------------------- 1 | // 2 | // PinYinForObjc.m 3 | // Search 4 | // 5 | // Created by LYZ on 14-1-24. 6 | // Copyright (c) 2014年 LYZ. All rights reserved. 7 | // 8 | 9 | #import "PinYinForObjc.h" 10 | 11 | @implementation PinYinForObjc 12 | 13 | + (NSString*)chineseConvertToPinYin:(NSString*)chinese { 14 | NSString *sourceText = chinese; 15 | HanyuPinyinOutputFormat *outputFormat = [[HanyuPinyinOutputFormat alloc] init]; 16 | [outputFormat setToneType:ToneTypeWithoutTone]; 17 | [outputFormat setVCharType:VCharTypeWithV]; 18 | [outputFormat setCaseType:CaseTypeLowercase]; 19 | NSString *outputPinyin = [PinyinHelper toHanyuPinyinStringWithNSString:sourceText withHanyuPinyinOutputFormat:outputFormat withNSString:@""]; 20 | 21 | return outputPinyin; 22 | 23 | 24 | } 25 | 26 | + (NSString*)chineseConvertToPinYinHead:(NSString *)chinese { 27 | HanyuPinyinOutputFormat *outputFormat = [[HanyuPinyinOutputFormat alloc] init]; 28 | [outputFormat setToneType:ToneTypeWithoutTone]; 29 | [outputFormat setVCharType:VCharTypeWithV]; 30 | [outputFormat setCaseType:CaseTypeLowercase]; 31 | NSMutableString *outputPinyin = [[NSMutableString alloc] init]; 32 | for (int i=0;i 10 | @class HanyuPinyinOutputFormat; 11 | 12 | @interface PinyinFormatter : NSObject { 13 | } 14 | 15 | + (NSString *)formatHanyuPinyinWithNSString:(NSString *)pinyinStr 16 | withHanyuPinyinOutputFormat:(HanyuPinyinOutputFormat *)outputFormat; 17 | + (NSString *)convertToneNumber2ToneMarkWithNSString:(NSString *)pinyinStr; 18 | - (id)init; 19 | @end 20 | 21 | #endif // _PinyinFormatter_H_ 22 | -------------------------------------------------------------------------------- /ZYPinYinSearchLib/PinyinFormatter.m: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // 4 | // Created by kimziv on 13-9-14. 5 | // 6 | 7 | #include "HanyuPinyinOutputFormat.h" 8 | #include "PinyinFormatter.h" 9 | #import "NSString+PinYin4Cocoa.h" 10 | 11 | @interface PinyinFormatter () 12 | +(NSInteger)getNumericValue:(unichar)c; 13 | +(NSInteger)indexOfChar:(int*) table ch:(unichar)c; 14 | @end 15 | 16 | @implementation PinyinFormatter 17 | 18 | static int numericKeys[] = { 19 | 0x0030, 0x0041, 0x0061, 0x00b2, 0x00b9, 0x00bc, 0x0660, 0x06f0, 20 | 0x0966, 0x09e6, 0x09f4, 0x09f9, 0x0a66, 0x0ae6, 0x0b66, 0x0be7, 21 | 0x0bf1, 0x0bf2, 0x0c66, 0x0ce6, 0x0d66, 0x0e50, 0x0ed0, 0x0f20, 22 | 0x1040, 0x1369, 0x1373, 0x1374, 0x1375, 0x1376, 0x1377, 0x1378, 23 | 0x1379, 0x137a, 0x137b, 0x137c, 0x16ee, 0x17e0, 0x1810, 0x2070, 24 | 0x2074, 0x2080, 0x2153, 0x215f, 0x2160, 0x216c, 0x216d, 0x216e, 25 | 0x216f, 0x2170, 0x217c, 0x217d, 0x217e, 0x217f, 0x2180, 0x2181, 26 | 0x2182, 0x2460, 0x2474, 0x2488, 0x24ea, 0x2776, 0x2780, 0x278a, 27 | 0x3007, 0x3021, 0x3038, 0x3039, 0x303a, 0x3280, 0xff10, 0xff21, 28 | 0xff41, 29 | }; 30 | 31 | static unichar numericValues[] = { 32 | 0x0039, 0x0030, 0x005a, 0x0037, 0x007a, 0x0057, 0x00b3, 0x00b0, 33 | 0x00b9, 0x00b8, 0x00be, 0x0000, 0x0669, 0x0660, 0x06f9, 0x06f0, 34 | 0x096f, 0x0966, 0x09ef, 0x09e6, 0x09f7, 0x09f3, 0x09f9, 0x09e9, 35 | 0x0a6f, 0x0a66, 0x0aef, 0x0ae6, 0x0b6f, 0x0b66, 0x0bf0, 0x0be6, 36 | 0x0bf1, 0x0b8d, 0x0bf2, 0x080a, 0x0c6f, 0x0c66, 0x0cef, 0x0ce6, 37 | 0x0d6f, 0x0d66, 0x0e59, 0x0e50, 0x0ed9, 0x0ed0, 0x0f29, 0x0f20, 38 | 0x1049, 0x1040, 0x1372, 0x1368, 0x1373, 0x135f, 0x1374, 0x1356, 39 | 0x1375, 0x134d, 0x1376, 0x1344, 0x1377, 0x133b, 0x1378, 0x1332, 40 | 0x1379, 0x1329, 0x137a, 0x1320, 0x137b, 0x1317, 0x137c, 0xec6c, 41 | 0x16f0, 0x16dd, 0x17e9, 0x17e0, 0x1819, 0x1810, 0x2070, 0x2070, 42 | 0x2079, 0x2070, 0x2089, 0x2080, 0x215e, 0x0000, 0x215f, 0x215e, 43 | 0x216b, 0x215f, 0x216c, 0x213a, 0x216d, 0x2109, 0x216e, 0x1f7a, 44 | 0x216f, 0x1d87, 0x217b, 0x216f, 0x217c, 0x214a, 0x217d, 0x2119, 45 | 0x217e, 0x1f8a, 0x217f, 0x1d97, 0x2180, 0x1d98, 0x2181, 0x0df9, 46 | 0x2182, 0xfa72, 0x2473, 0x245f, 0x2487, 0x2473, 0x249b, 0x2487, 47 | 0x24ea, 0x24ea, 0x277f, 0x2775, 0x2789, 0x277f, 0x2793, 0x2789, 48 | 0x3007, 0x3007, 0x3029, 0x3020, 0x3038, 0x302e, 0x3039, 0x3025, 49 | 0x303a, 0x301c, 0x3289, 0x327f, 0xff19, 0xff10, 0xff3a, 0xff17, 50 | 0xff5a, 0xff37, 51 | }; 52 | 53 | 54 | + (NSString *)formatHanyuPinyinWithNSString:(NSString *)pinyinStr 55 | withHanyuPinyinOutputFormat:(HanyuPinyinOutputFormat *)outputFormat { 56 | if ((ToneTypeWithToneMark == [outputFormat toneType]) && ((VCharTypeWithV == [outputFormat vCharType]) || (VCharTypeWithUAndColon == [outputFormat vCharType]))) { 57 | @throw [NSException exceptionWithName:@"Throwing a BadHanyuPinyinOutputFormatCombination exception" reason:@"tone marks cannot be added to v or u:." userInfo:nil]; 58 | } 59 | if (ToneTypeWithoutTone == [outputFormat toneType]) { 60 | pinyinStr =[pinyinStr stringByReplacingOccurrencesOfString:@"[1-5]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, pinyinStr.length)]; 61 | } 62 | else if (ToneTypeWithToneMark == [outputFormat toneType]) { 63 | pinyinStr =[pinyinStr stringByReplacingOccurrencesOfString:@"u:" withString:@"v"]; 64 | pinyinStr = [PinyinFormatter convertToneNumber2ToneMarkWithNSString:pinyinStr]; 65 | } 66 | if (VCharTypeWithV == [outputFormat vCharType]) { 67 | pinyinStr =[pinyinStr stringByReplacingOccurrencesOfString:@"u:" withString:@"v"]; 68 | } 69 | else if (VCharTypeWithUUnicode == [outputFormat vCharType]) { 70 | pinyinStr =[pinyinStr stringByReplacingOccurrencesOfString:@"u:" withString:@"ü"]; 71 | } 72 | if (CaseTypeUppercase == [outputFormat caseType]) { 73 | pinyinStr = [pinyinStr uppercaseString]; 74 | } 75 | return pinyinStr; 76 | } 77 | 78 | + (NSString *)convertToneNumber2ToneMarkWithNSString:(NSString *)pinyinStr { 79 | NSString *lowerCasePinyinStr = [pinyinStr lowercaseString]; 80 | if ([lowerCasePinyinStr matchesPatternRegexPattern:@"[a-z]*[1-5]?"]) { 81 | unichar defautlCharValue = '$'; 82 | int defautlIndexValue = -1; 83 | unichar unmarkedVowel = defautlCharValue; 84 | int indexOfUnmarkedVowel = defautlIndexValue; 85 | unichar charA = 'a'; 86 | unichar charE = 'e'; 87 | NSString *ouStr = @"ou"; 88 | NSString *allUnmarkedVowelStr = @"aeiouv"; 89 | NSString *allMarkedVowelStr = @"āáăàaēéĕèeīíĭìiōóŏòoūúŭùuǖǘǚǜü"; 90 | if ([lowerCasePinyinStr matchesPatternRegexPattern:@"[a-z]*[1-5]"]) { 91 | int tuneNumber = [PinyinFormatter getNumericValue:[lowerCasePinyinStr characterAtIndex:lowerCasePinyinStr.length -1]]; 92 | int indexOfA = [lowerCasePinyinStr indexOf:charA]; 93 | int indexOfE = [lowerCasePinyinStr indexOf:charE]; 94 | int ouIndex = [lowerCasePinyinStr indexOfString:ouStr]; 95 | if (-1 != indexOfA) { 96 | indexOfUnmarkedVowel = indexOfA; 97 | unmarkedVowel = charA; 98 | } 99 | else if (-1 != indexOfE) { 100 | indexOfUnmarkedVowel = indexOfE; 101 | unmarkedVowel = charE; 102 | } 103 | else if (-1 != ouIndex) { 104 | indexOfUnmarkedVowel = ouIndex; 105 | unmarkedVowel = [ouStr characterAtIndex:0]; 106 | } 107 | else { 108 | for (int i = [lowerCasePinyinStr length] - 1; i >= 0; i--) { 109 | if ([[NSString valueOfChar:[lowerCasePinyinStr characterAtIndex:i]] matchesPatternRegexPattern:@"[aeiouv]"]) { 110 | indexOfUnmarkedVowel = i; 111 | unmarkedVowel = [lowerCasePinyinStr characterAtIndex:i]; 112 | break; 113 | } 114 | } 115 | } 116 | if ((defautlCharValue != unmarkedVowel) && (defautlIndexValue != indexOfUnmarkedVowel)) { 117 | int rowIndex = [allUnmarkedVowelStr indexOf:unmarkedVowel]; 118 | int columnIndex = tuneNumber - 1; 119 | int vowelLocation = rowIndex * 5 + columnIndex; 120 | unichar markedVowel = [allMarkedVowelStr characterAtIndex:vowelLocation]; 121 | NSMutableString *resultBuffer = [[NSMutableString alloc] init]; 122 | [resultBuffer appendString:[[lowerCasePinyinStr substringToIndex:indexOfUnmarkedVowel+1] stringByReplacingOccurrencesOfString:@"v" withString:@"ü"]]; 123 | [resultBuffer appendFormat:@"%C",markedVowel]; 124 | [resultBuffer appendString:[[lowerCasePinyinStr substringWithRange:NSMakeRange(indexOfUnmarkedVowel + 1, lowerCasePinyinStr.length-indexOfUnmarkedVowel)] stringByReplacingOccurrencesOfString:@"v" withString:@"ü"]]; 125 | return [resultBuffer description]; 126 | } 127 | else { 128 | return lowerCasePinyinStr; 129 | } 130 | } 131 | else { 132 | return [lowerCasePinyinStr stringByReplacingOccurrencesOfString:@"v" withString:@"ü"]; 133 | } 134 | } 135 | else { 136 | return lowerCasePinyinStr; 137 | } 138 | } 139 | 140 | +(NSInteger)getNumericValue:(unichar)c 141 | { 142 | if (c < 128) { 143 | // Optimized for ASCII 144 | if (c >= '0' && c <= '9') { 145 | return c - '0'; 146 | } 147 | if (c >= 'a' && c <= 'z') { 148 | return c - ('a' - 10); 149 | } 150 | if (c >= 'A' && c <= 'Z') { 151 | return c - ('A' - 10); 152 | } 153 | return -1; 154 | } 155 | NSInteger result = [self indexOfChar:numericKeys ch:c]; 156 | if (result >= 0 && c <= numericValues[result * 2]) { 157 | unichar difference = numericValues[result * 2 + 1]; 158 | if (difference == 0) { 159 | return -2; 160 | } 161 | // Value is always positive, must be negative value 162 | if (difference > c) { 163 | return c - (short) difference; 164 | } 165 | return c - difference; 166 | } 167 | return -1; 168 | 169 | } 170 | 171 | +(NSInteger)indexOfChar:(int*) table ch:(unichar)c{ 172 | NSInteger len=sizeof(table)/sizeof(table[0]); 173 | for (int i = 0; i < len; i++) { 174 | if (table[i] == (int) c) { 175 | return i; 176 | } 177 | } 178 | return -1; 179 | } 180 | 181 | 182 | - (id)init { 183 | return [super init]; 184 | } 185 | 186 | 187 | 188 | @end 189 | -------------------------------------------------------------------------------- /ZYPinYinSearchLib/PinyinHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // 4 | // Created by kimziv on 13-9-14. 5 | // 6 | 7 | #ifndef _PinyinHelper_H_ 8 | #define _PinyinHelper_H_ 9 | #import 10 | @class HanyuPinyinOutputFormat; 11 | 12 | @interface PinyinHelper : NSObject { 13 | } 14 | 15 | + (NSArray *)toHanyuPinyinStringArrayWithChar:(unichar)ch; 16 | + (NSArray *)toHanyuPinyinStringArrayWithChar:(unichar)ch 17 | withHanyuPinyinOutputFormat:(HanyuPinyinOutputFormat *)outputFormat; 18 | + (NSArray *)getFormattedHanyuPinyinStringArrayWithChar:(unichar)ch 19 | withHanyuPinyinOutputFormat:(HanyuPinyinOutputFormat *)outputFormat; 20 | + (NSArray *)getUnformattedHanyuPinyinStringArrayWithChar:(unichar)ch; 21 | + (NSArray *)toTongyongPinyinStringArrayWithChar:(unichar)ch; 22 | + (NSArray *)toWadeGilesPinyinStringArrayWithChar:(unichar)ch; 23 | + (NSArray *)toMPS2PinyinStringArrayWithChar:(unichar)ch; 24 | + (NSArray *)toYalePinyinStringArrayWithChar:(unichar)ch; 25 | + (NSArray *)convertToTargetPinyinStringArrayWithChar:(unichar)ch 26 | withPinyinRomanizationType:(NSString *)targetPinyinSystem; 27 | + (NSArray *)toGwoyeuRomatzyhStringArrayWithChar:(unichar)ch; 28 | + (NSArray *)convertToGwoyeuRomatzyhStringArrayWithChar:(unichar)ch; 29 | + (NSString *)toHanyuPinyinStringWithNSString:(NSString *)str 30 | withHanyuPinyinOutputFormat:(HanyuPinyinOutputFormat *)outputFormat 31 | withNSString:(NSString *)seperater; 32 | + (NSString *)getFirstHanyuPinyinStringWithChar:(unichar)ch 33 | withHanyuPinyinOutputFormat:(HanyuPinyinOutputFormat *)outputFormat; 34 | - (id)init; 35 | @end 36 | 37 | #endif // _PinyinHelper_H_ 38 | -------------------------------------------------------------------------------- /ZYPinYinSearchLib/PinyinHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // 4 | // Created by kimziv on 13-9-14. 5 | // 6 | 7 | #include "ChineseToPinyinResource.h" 8 | #include "HanyuPinyinOutputFormat.h" 9 | #include "PinyinFormatter.h" 10 | #include "PinyinHelper.h" 11 | 12 | #define HANYU_PINYIN @"Hanyu" 13 | #define WADEGILES_PINYIN @"Wade" 14 | #define MPS2_PINYIN @"MPSII" 15 | #define YALE_PINYIN @"Yale" 16 | #define TONGYONG_PINYIN @"Tongyong" 17 | #define GWOYEU_ROMATZYH @"Gwoyeu" 18 | 19 | @implementation PinyinHelper 20 | 21 | + (NSArray *)toHanyuPinyinStringArrayWithChar:(unichar)ch { 22 | return [PinyinHelper getUnformattedHanyuPinyinStringArrayWithChar:ch]; 23 | } 24 | 25 | + (NSArray *)toHanyuPinyinStringArrayWithChar:(unichar)ch 26 | withHanyuPinyinOutputFormat:(HanyuPinyinOutputFormat *)outputFormat { 27 | return [PinyinHelper getFormattedHanyuPinyinStringArrayWithChar:ch withHanyuPinyinOutputFormat:outputFormat]; 28 | } 29 | 30 | + (NSArray *)getFormattedHanyuPinyinStringArrayWithChar:(unichar)ch 31 | withHanyuPinyinOutputFormat:(HanyuPinyinOutputFormat *)outputFormat { 32 | NSMutableArray *pinyinStrArray =[NSMutableArray arrayWithArray:[PinyinHelper getUnformattedHanyuPinyinStringArrayWithChar:ch]]; 33 | if (nil != pinyinStrArray) { 34 | for (int i = 0; i < (int) [pinyinStrArray count]; i++) { 35 | [pinyinStrArray replaceObjectAtIndex:i withObject:[PinyinFormatter formatHanyuPinyinWithNSString: 36 | [pinyinStrArray objectAtIndex:i]withHanyuPinyinOutputFormat:outputFormat]]; 37 | } 38 | return pinyinStrArray; 39 | } 40 | else return nil; 41 | } 42 | 43 | + (NSArray *)getUnformattedHanyuPinyinStringArrayWithChar:(unichar)ch { 44 | return [[ChineseToPinyinResource getInstance] getHanyuPinyinStringArrayWithChar:ch]; 45 | } 46 | 47 | + (NSArray *)toTongyongPinyinStringArrayWithChar:(unichar)ch { 48 | return [PinyinHelper convertToTargetPinyinStringArrayWithChar:ch withPinyinRomanizationType: TONGYONG_PINYIN]; 49 | } 50 | 51 | + (NSArray *)toWadeGilesPinyinStringArrayWithChar:(unichar)ch { 52 | return [PinyinHelper convertToTargetPinyinStringArrayWithChar:ch withPinyinRomanizationType: WADEGILES_PINYIN]; 53 | } 54 | 55 | + (NSArray *)toMPS2PinyinStringArrayWithChar:(unichar)ch { 56 | return [PinyinHelper convertToTargetPinyinStringArrayWithChar:ch withPinyinRomanizationType: MPS2_PINYIN]; 57 | } 58 | 59 | + (NSArray *)toYalePinyinStringArrayWithChar:(unichar)ch { 60 | return [PinyinHelper convertToTargetPinyinStringArrayWithChar:ch withPinyinRomanizationType: YALE_PINYIN]; 61 | } 62 | 63 | + (NSArray *)convertToTargetPinyinStringArrayWithChar:(unichar)ch 64 | withPinyinRomanizationType:(NSString *)targetPinyinSystem { 65 | NSArray *hanyuPinyinStringArray = [PinyinHelper getUnformattedHanyuPinyinStringArrayWithChar:ch]; 66 | if (nil != hanyuPinyinStringArray) { 67 | NSMutableArray *targetPinyinStringArray = [NSMutableArray arrayWithCapacity:hanyuPinyinStringArray.count]; 68 | for (int i = 0; i < (int) [hanyuPinyinStringArray count]; i++) { 69 | 70 | } 71 | return targetPinyinStringArray; 72 | } 73 | else return nil; 74 | } 75 | 76 | + (NSArray *)toGwoyeuRomatzyhStringArrayWithChar:(unichar)ch { 77 | return [PinyinHelper convertToGwoyeuRomatzyhStringArrayWithChar:ch]; 78 | } 79 | 80 | + (NSArray *)convertToGwoyeuRomatzyhStringArrayWithChar:(unichar)ch { 81 | NSArray *hanyuPinyinStringArray = [PinyinHelper getUnformattedHanyuPinyinStringArrayWithChar:ch]; 82 | if (nil != hanyuPinyinStringArray) { 83 | NSMutableArray *targetPinyinStringArray =[NSMutableArray arrayWithCapacity:hanyuPinyinStringArray.count]; 84 | for (int i = 0; i < (int) [hanyuPinyinStringArray count]; i++) { 85 | } 86 | return targetPinyinStringArray; 87 | } 88 | else return nil; 89 | } 90 | 91 | + (NSString *)toHanyuPinyinStringWithNSString:(NSString *)str 92 | withHanyuPinyinOutputFormat:(HanyuPinyinOutputFormat *)outputFormat 93 | withNSString:(NSString *)seperater { 94 | NSMutableString *resultPinyinStrBuf = [[NSMutableString alloc] init]; 95 | for (int i = 0; i < str.length; i++) { 96 | NSString *mainPinyinStrOfChar = [PinyinHelper getFirstHanyuPinyinStringWithChar:[str characterAtIndex:i] withHanyuPinyinOutputFormat:outputFormat]; 97 | if (nil != mainPinyinStrOfChar) { 98 | [resultPinyinStrBuf appendString:mainPinyinStrOfChar]; 99 | if (i != [str length] - 1) { 100 | [resultPinyinStrBuf appendString:seperater]; 101 | } 102 | } 103 | else { 104 | [resultPinyinStrBuf appendFormat:@"%C",[str characterAtIndex:i]]; 105 | } 106 | } 107 | return resultPinyinStrBuf; 108 | } 109 | 110 | + (NSString *)getFirstHanyuPinyinStringWithChar:(unichar)ch 111 | withHanyuPinyinOutputFormat:(HanyuPinyinOutputFormat *)outputFormat { 112 | NSArray *pinyinStrArray = [PinyinHelper getFormattedHanyuPinyinStringArrayWithChar:ch withHanyuPinyinOutputFormat:outputFormat]; 113 | if ((nil != pinyinStrArray) && ((int) [pinyinStrArray count] > 0)) { 114 | return [pinyinStrArray objectAtIndex:0]; 115 | } 116 | else { 117 | return nil; 118 | } 119 | } 120 | 121 | - (id)init { 122 | return [super init]; 123 | } 124 | 125 | @end 126 | -------------------------------------------------------------------------------- /ZYPinYinSearchLib/ZYPinYinSearch.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZYPinYinSearch.h 3 | // ZYPinYinSearch 4 | // 5 | // Created by soufun on 15/7/27. 6 | // Copyright (c) 2015年 ZY. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZYPinYinSearch : NSObject 12 | /** 13 | * 搜索数组,返回新的数组。目前支持NSString,NSDictionnary,自定义Model,后面两个可以指定按照哪个字段搜索 14 | * 15 | * @param originalArray 要搜索的数据源 16 | * @param searchText 搜索的文本 17 | * @param propertyName 按照字典中或者model中哪个字段搜索,如果数组中存的是NSString,则传@""即可 18 | * @example _dataSourceArray = [ZYPinYinSearch searchWithOriginalArray:_originalArray andSearchText:searchBar.text andSearchByPropertyName:@"name"]; 19 | */ 20 | +(NSArray *)searchWithOriginalArray:(NSArray *)originalArray andSearchText:(NSString *)searchText andSearchByPropertyName:(NSString *)propertyName; 21 | @end 22 | -------------------------------------------------------------------------------- /ZYPinYinSearchLib/ZYPinYinSearch.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZYPinYinSearch.m 3 | // ZYPinYinSearch 4 | // 5 | // Created by soufun on 15/7/27. 6 | // Copyright (c) 2015年 ZY. All rights reserved. 7 | // 8 | 9 | #import "ZYPinYinSearch.h" 10 | #import "ChineseInclude.h" 11 | #import "PinYinForObjc.h" 12 | #import "objc/runtime.h" 13 | #import 14 | @implementation ZYPinYinSearch 15 | +(NSArray *)searchWithOriginalArray:(NSArray *)originalArray andSearchText:(NSString *)searchText andSearchByPropertyName:(NSString *)propertyName{ 16 | NSMutableArray * dataSourceArray = [[NSMutableArray alloc]init]; 17 | NSString * type; 18 | if(originalArray.count <= 0){ 19 | UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"数据源不能为空" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles: nil]; 20 | [alert show]; 21 | return originalArray; 22 | } 23 | else{ 24 | id object = originalArray[0]; 25 | if ([object isKindOfClass:[NSString class]]) { 26 | type = @"string"; 27 | } 28 | else if([object isKindOfClass:[NSDictionary class]]){ 29 | type = @"dict"; 30 | NSDictionary * dict = originalArray[0]; 31 | // NSLog(@"字典keys:%@",[dict allKeys]); 32 | BOOL isExit = NO; 33 | for (NSString * key in dict.allKeys) { 34 | if([key isEqualToString:propertyName]){ 35 | isExit = YES; 36 | break; 37 | } 38 | } 39 | if (!isExit) { 40 | UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"提示" message:[NSString stringWithFormat:@"数据源中的字典没有你指定的key:%@",propertyName] delegate:nil cancelButtonTitle:@"确定" otherButtonTitles: nil]; 41 | [alert show]; 42 | return originalArray; 43 | } 44 | } 45 | else{ 46 | type = @"model"; 47 | NSMutableArray *props = [NSMutableArray array]; 48 | unsigned int outCount, i; 49 | objc_property_t *properties = class_copyPropertyList([object class], &outCount); 50 | for (i = 0; i0&&![ChineseInclude isIncludeChineseInString:searchText]) { 75 | for (int i=0; i0) { 88 | [dataSourceArray addObject:originalArray[i]]; 89 | continue; 90 | } 91 | NSString *tempPinYinHeadStr = [PinYinForObjc chineseConvertToPinYinHead:tempString]; 92 | // NSLog(@"%@",tempPinYinHeadStr); 93 | NSRange titleHeadResult=[tempPinYinHeadStr rangeOfString:searchText options:NSCaseInsensitiveSearch]; 94 | if (titleHeadResult.length>0) { 95 | [dataSourceArray addObject:originalArray[i]]; 96 | continue; 97 | } 98 | } 99 | else { 100 | NSRange titleResult=[tempString rangeOfString:searchText options:NSCaseInsensitiveSearch]; 101 | if (titleResult.length>0) { 102 | [dataSourceArray addObject:originalArray[i]]; 103 | continue; 104 | } 105 | } 106 | } 107 | } else if (searchText.length>0&&[ChineseInclude isIncludeChineseInString:searchText]) { 108 | for (id object in originalArray) { 109 | NSString * tempString; 110 | if ([type isEqualToString:@"string"]) { 111 | tempString = object; 112 | } 113 | else{ 114 | tempString = [object valueForKey:propertyName]; 115 | } 116 | NSRange titleResult=[tempString rangeOfString:searchText options:NSCaseInsensitiveSearch]; 117 | if (titleResult.length>0) { 118 | [dataSourceArray addObject:object]; 119 | } 120 | } 121 | } 122 | return dataSourceArray; 123 | } 124 | 125 | @end 126 | -------------------------------------------------------------------------------- /效果图/01.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/panyaorui/CityList/b541fc795db93809fffa11d2fb53c2de02f7ad08/效果图/01.gif -------------------------------------------------------------------------------- /效果图/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/panyaorui/CityList/b541fc795db93809fffa11d2fb53c2de02f7ad08/效果图/02.png -------------------------------------------------------------------------------- /效果图/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/panyaorui/CityList/b541fc795db93809fffa11d2fb53c2de02f7ad08/效果图/03.png --------------------------------------------------------------------------------