├── README.md ├── ZGiReader ├── ZGiReader.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── yangzhenguo.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── yangzhenguo.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── ZGiReader │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── ViewController.h │ ├── ViewController.m │ ├── ZGiReader.xcdatamodeld │ │ └── ZGiReader.xcdatamodel │ │ │ └── contents │ └── main.m ├── ZGiReaderController │ ├── 205832.txt │ ├── JJPreventCrash.h │ ├── JJPreventCrash.m │ ├── NSString+ZGiReaderPaging.h │ ├── NSString+ZGiReaderPaging.m │ ├── ZGBaseViewController.h │ ├── ZGBaseViewController.m │ ├── ZGiReader │ │ ├── Model │ │ │ ├── ZGiReaderChapterModel.h │ │ │ ├── ZGiReaderChapterModel.m │ │ │ ├── ZGiReaderGlobalModel.h │ │ │ ├── ZGiReaderGlobalModel.m │ │ │ ├── ZGiReaderRecordModel.h │ │ │ └── ZGiReaderRecordModel.m │ │ ├── ZGiReaderCollectionView.h │ │ ├── ZGiReaderCollectionView.m │ │ ├── ZGiReaderCollectionViewFlowLayout.h │ │ ├── ZGiReaderCollectionViewFlowLayout.m │ │ ├── ZGiReaderCurrentTempView.h │ │ ├── ZGiReaderCurrentTempView.m │ │ ├── ZGiReaderPageCell.h │ │ ├── ZGiReaderPageCell.m │ │ ├── ZGiReaderPageView.h │ │ ├── ZGiReaderPageView.m │ │ ├── ZGiReaderTopAndBottomBarController.h │ │ ├── ZGiReaderTopAndBottomBarController.m │ │ ├── ZGiReaderViewController.h │ │ └── ZGiReaderViewController.m │ ├── ZGiReaderAppInfoManager.h │ ├── ZGiReaderAppInfoManager.m │ ├── ZGiReaderHeader.h │ ├── ZGiReaderReadUtilites.h │ ├── ZGiReaderReadUtilites.m │ └── test.txt ├── ZGiReaderTests │ ├── Info.plist │ └── ZGiReaderTests.m └── ZGiReaderUITests │ ├── Info.plist │ └── ZGiReaderUITests.m └── 破解VIP视频软件.dmg /README.md: -------------------------------------------------------------------------------- 1 | # ZGiReader 2 | iReader,仿掌阅,仿qq阅读,仿起点,仿晋江,仿书旗,追书大神,追书神器,笔趣阁,潇湘书院,TXT阅读器,小说,阅读,微信读书,京东阅读,仿真翻页,覆盖翻页,滚动翻页,无动画翻页,翻页模式 3 | 后续功能会陆续添加 4 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReader.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 65534D402111BCDF00882AF1 /* test.txt in Resources */ = {isa = PBXBuildFile; fileRef = 65534D3F2111BCDF00882AF1 /* test.txt */; }; 11 | 658365522109AB49002039F6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 658365512109AB49002039F6 /* AppDelegate.m */; }; 12 | 658365552109AB49002039F6 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 658365542109AB49002039F6 /* ViewController.m */; }; 13 | 658365582109AB49002039F6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 658365562109AB49002039F6 /* Main.storyboard */; }; 14 | 6583655B2109AB49002039F6 /* ZGiReader.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 658365592109AB49002039F6 /* ZGiReader.xcdatamodeld */; }; 15 | 6583655D2109AB49002039F6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6583655C2109AB49002039F6 /* Assets.xcassets */; }; 16 | 658365602109AB49002039F6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6583655E2109AB49002039F6 /* LaunchScreen.storyboard */; }; 17 | 658365632109AB49002039F6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 658365622109AB49002039F6 /* main.m */; }; 18 | 6583656D2109AB49002039F6 /* ZGiReaderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6583656C2109AB49002039F6 /* ZGiReaderTests.m */; }; 19 | 658365782109AB49002039F6 /* ZGiReaderUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 658365772109AB49002039F6 /* ZGiReaderUITests.m */; }; 20 | 658365882109ABB1002039F6 /* ZGBaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 658365872109ABB1002039F6 /* ZGBaseViewController.m */; }; 21 | 6583658C2109ABF1002039F6 /* ZGiReaderViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6583658B2109ABF1002039F6 /* ZGiReaderViewController.m */; }; 22 | 658365932109B525002039F6 /* ZGiReaderCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 658365922109B525002039F6 /* ZGiReaderCollectionView.m */; }; 23 | 658CCD97211159A4007E88B4 /* ZGiReaderCollectionViewFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 658CCD96211159A4007E88B4 /* ZGiReaderCollectionViewFlowLayout.m */; }; 24 | 658CCD9B21116088007E88B4 /* NSString+ZGiReaderPaging.m in Sources */ = {isa = PBXBuildFile; fileRef = 658CCD9A21116088007E88B4 /* NSString+ZGiReaderPaging.m */; }; 25 | 658CCD9E21116199007E88B4 /* ZGiReaderPageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 658CCD9D21116199007E88B4 /* ZGiReaderPageView.m */; }; 26 | 658CCDA4211162A7007E88B4 /* ZGiReaderGlobalModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 658CCDA3211162A7007E88B4 /* ZGiReaderGlobalModel.m */; }; 27 | 658CCDA7211164D4007E88B4 /* ZGiReaderAppInfoManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 658CCDA6211164D4007E88B4 /* ZGiReaderAppInfoManager.m */; }; 28 | 658CCDAA21116762007E88B4 /* ZGiReaderPageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 658CCDA921116762007E88B4 /* ZGiReaderPageCell.m */; }; 29 | 65BAC19021129F8400B06FFC /* ZGiReaderCurrentTempView.m in Sources */ = {isa = PBXBuildFile; fileRef = 65BAC18F21129F8400B06FFC /* ZGiReaderCurrentTempView.m */; }; 30 | 65BAC1992112E77D00B06FFC /* ZGiReaderRecordModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 65BAC1982112E77D00B06FFC /* ZGiReaderRecordModel.m */; }; 31 | 65BAC19C2112F22700B06FFC /* ZGiReaderReadUtilites.m in Sources */ = {isa = PBXBuildFile; fileRef = 65BAC19B2112F22700B06FFC /* ZGiReaderReadUtilites.m */; }; 32 | 65BAC19E2112F40000B06FFC /* 205832.txt in Resources */ = {isa = PBXBuildFile; fileRef = 65BAC19D2112F40000B06FFC /* 205832.txt */; }; 33 | 65BAC1A12112F7FE00B06FFC /* JJPreventCrash.m in Sources */ = {isa = PBXBuildFile; fileRef = 65BAC1A02112F7FE00B06FFC /* JJPreventCrash.m */; }; 34 | 65BAC1A42112FBFF00B06FFC /* ZGiReaderChapterModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 65BAC1A32112FBFF00B06FFC /* ZGiReaderChapterModel.m */; }; 35 | 65CBD7C6211464A80047A146 /* ZGiReaderTopAndBottomBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 65CBD7C5211464A80047A146 /* ZGiReaderTopAndBottomBarController.m */; }; 36 | /* End PBXBuildFile section */ 37 | 38 | /* Begin PBXContainerItemProxy section */ 39 | 658365692109AB49002039F6 /* PBXContainerItemProxy */ = { 40 | isa = PBXContainerItemProxy; 41 | containerPortal = 658365452109AB49002039F6 /* Project object */; 42 | proxyType = 1; 43 | remoteGlobalIDString = 6583654C2109AB49002039F6; 44 | remoteInfo = ZGiReader; 45 | }; 46 | 658365742109AB49002039F6 /* PBXContainerItemProxy */ = { 47 | isa = PBXContainerItemProxy; 48 | containerPortal = 658365452109AB49002039F6 /* Project object */; 49 | proxyType = 1; 50 | remoteGlobalIDString = 6583654C2109AB49002039F6; 51 | remoteInfo = ZGiReader; 52 | }; 53 | /* End PBXContainerItemProxy section */ 54 | 55 | /* Begin PBXFileReference section */ 56 | 65534D3F2111BCDF00882AF1 /* test.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test.txt; sourceTree = ""; }; 57 | 6583654D2109AB49002039F6 /* ZGiReader.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ZGiReader.app; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 658365502109AB49002039F6 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 59 | 658365512109AB49002039F6 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 60 | 658365532109AB49002039F6 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 61 | 658365542109AB49002039F6 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 62 | 658365572109AB49002039F6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 63 | 6583655A2109AB49002039F6 /* ZGiReader.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = ZGiReader.xcdatamodel; sourceTree = ""; }; 64 | 6583655C2109AB49002039F6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 65 | 6583655F2109AB49002039F6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 66 | 658365612109AB49002039F6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 67 | 658365622109AB49002039F6 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 68 | 658365682109AB49002039F6 /* ZGiReaderTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ZGiReaderTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 69 | 6583656C2109AB49002039F6 /* ZGiReaderTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGiReaderTests.m; sourceTree = ""; }; 70 | 6583656E2109AB49002039F6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 71 | 658365732109AB49002039F6 /* ZGiReaderUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ZGiReaderUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 72 | 658365772109AB49002039F6 /* ZGiReaderUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGiReaderUITests.m; sourceTree = ""; }; 73 | 658365792109AB49002039F6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 74 | 658365862109ABB1002039F6 /* ZGBaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZGBaseViewController.h; sourceTree = ""; }; 75 | 658365872109ABB1002039F6 /* ZGBaseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGBaseViewController.m; sourceTree = ""; }; 76 | 6583658A2109ABF1002039F6 /* ZGiReaderViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZGiReaderViewController.h; sourceTree = ""; }; 77 | 6583658B2109ABF1002039F6 /* ZGiReaderViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGiReaderViewController.m; sourceTree = ""; }; 78 | 658365912109B525002039F6 /* ZGiReaderCollectionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZGiReaderCollectionView.h; sourceTree = ""; }; 79 | 658365922109B525002039F6 /* ZGiReaderCollectionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGiReaderCollectionView.m; sourceTree = ""; }; 80 | 658CCD95211159A4007E88B4 /* ZGiReaderCollectionViewFlowLayout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZGiReaderCollectionViewFlowLayout.h; sourceTree = ""; }; 81 | 658CCD96211159A4007E88B4 /* ZGiReaderCollectionViewFlowLayout.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGiReaderCollectionViewFlowLayout.m; sourceTree = ""; }; 82 | 658CCD9821115C90007E88B4 /* ZGiReaderHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZGiReaderHeader.h; sourceTree = ""; }; 83 | 658CCD9921116088007E88B4 /* NSString+ZGiReaderPaging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSString+ZGiReaderPaging.h"; sourceTree = ""; }; 84 | 658CCD9A21116088007E88B4 /* NSString+ZGiReaderPaging.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSString+ZGiReaderPaging.m"; sourceTree = ""; }; 85 | 658CCD9C21116199007E88B4 /* ZGiReaderPageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZGiReaderPageView.h; sourceTree = ""; }; 86 | 658CCD9D21116199007E88B4 /* ZGiReaderPageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGiReaderPageView.m; sourceTree = ""; }; 87 | 658CCDA2211162A7007E88B4 /* ZGiReaderGlobalModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZGiReaderGlobalModel.h; sourceTree = ""; }; 88 | 658CCDA3211162A7007E88B4 /* ZGiReaderGlobalModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGiReaderGlobalModel.m; sourceTree = ""; }; 89 | 658CCDA5211164D4007E88B4 /* ZGiReaderAppInfoManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZGiReaderAppInfoManager.h; sourceTree = ""; }; 90 | 658CCDA6211164D4007E88B4 /* ZGiReaderAppInfoManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGiReaderAppInfoManager.m; sourceTree = ""; }; 91 | 658CCDA821116762007E88B4 /* ZGiReaderPageCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZGiReaderPageCell.h; sourceTree = ""; }; 92 | 658CCDA921116762007E88B4 /* ZGiReaderPageCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGiReaderPageCell.m; sourceTree = ""; }; 93 | 65BAC18E21129F8400B06FFC /* ZGiReaderCurrentTempView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZGiReaderCurrentTempView.h; sourceTree = ""; }; 94 | 65BAC18F21129F8400B06FFC /* ZGiReaderCurrentTempView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGiReaderCurrentTempView.m; sourceTree = ""; }; 95 | 65BAC1972112E77D00B06FFC /* ZGiReaderRecordModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZGiReaderRecordModel.h; sourceTree = ""; }; 96 | 65BAC1982112E77D00B06FFC /* ZGiReaderRecordModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGiReaderRecordModel.m; sourceTree = ""; }; 97 | 65BAC19A2112F22700B06FFC /* ZGiReaderReadUtilites.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZGiReaderReadUtilites.h; sourceTree = ""; }; 98 | 65BAC19B2112F22700B06FFC /* ZGiReaderReadUtilites.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGiReaderReadUtilites.m; sourceTree = ""; }; 99 | 65BAC19D2112F40000B06FFC /* 205832.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = 205832.txt; sourceTree = ""; }; 100 | 65BAC19F2112F7FD00B06FFC /* JJPreventCrash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JJPreventCrash.h; sourceTree = ""; }; 101 | 65BAC1A02112F7FE00B06FFC /* JJPreventCrash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JJPreventCrash.m; sourceTree = ""; }; 102 | 65BAC1A22112FBFF00B06FFC /* ZGiReaderChapterModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZGiReaderChapterModel.h; sourceTree = ""; }; 103 | 65BAC1A32112FBFF00B06FFC /* ZGiReaderChapterModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGiReaderChapterModel.m; sourceTree = ""; }; 104 | 65CBD7C4211464A80047A146 /* ZGiReaderTopAndBottomBarController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZGiReaderTopAndBottomBarController.h; sourceTree = ""; }; 105 | 65CBD7C5211464A80047A146 /* ZGiReaderTopAndBottomBarController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZGiReaderTopAndBottomBarController.m; sourceTree = ""; }; 106 | /* End PBXFileReference section */ 107 | 108 | /* Begin PBXFrameworksBuildPhase section */ 109 | 6583654A2109AB49002039F6 /* Frameworks */ = { 110 | isa = PBXFrameworksBuildPhase; 111 | buildActionMask = 2147483647; 112 | files = ( 113 | ); 114 | runOnlyForDeploymentPostprocessing = 0; 115 | }; 116 | 658365652109AB49002039F6 /* Frameworks */ = { 117 | isa = PBXFrameworksBuildPhase; 118 | buildActionMask = 2147483647; 119 | files = ( 120 | ); 121 | runOnlyForDeploymentPostprocessing = 0; 122 | }; 123 | 658365702109AB49002039F6 /* Frameworks */ = { 124 | isa = PBXFrameworksBuildPhase; 125 | buildActionMask = 2147483647; 126 | files = ( 127 | ); 128 | runOnlyForDeploymentPostprocessing = 0; 129 | }; 130 | /* End PBXFrameworksBuildPhase section */ 131 | 132 | /* Begin PBXGroup section */ 133 | 658365442109AB49002039F6 = { 134 | isa = PBXGroup; 135 | children = ( 136 | 658365852109AB89002039F6 /* ZGiReaderController */, 137 | 6583654F2109AB49002039F6 /* ZGiReader */, 138 | 6583656B2109AB49002039F6 /* ZGiReaderTests */, 139 | 658365762109AB49002039F6 /* ZGiReaderUITests */, 140 | 6583654E2109AB49002039F6 /* Products */, 141 | ); 142 | sourceTree = ""; 143 | }; 144 | 6583654E2109AB49002039F6 /* Products */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | 6583654D2109AB49002039F6 /* ZGiReader.app */, 148 | 658365682109AB49002039F6 /* ZGiReaderTests.xctest */, 149 | 658365732109AB49002039F6 /* ZGiReaderUITests.xctest */, 150 | ); 151 | name = Products; 152 | sourceTree = ""; 153 | }; 154 | 6583654F2109AB49002039F6 /* ZGiReader */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | 658365502109AB49002039F6 /* AppDelegate.h */, 158 | 658365512109AB49002039F6 /* AppDelegate.m */, 159 | 658365532109AB49002039F6 /* ViewController.h */, 160 | 658365542109AB49002039F6 /* ViewController.m */, 161 | 658365562109AB49002039F6 /* Main.storyboard */, 162 | 6583655C2109AB49002039F6 /* Assets.xcassets */, 163 | 6583655E2109AB49002039F6 /* LaunchScreen.storyboard */, 164 | 658365612109AB49002039F6 /* Info.plist */, 165 | 658365622109AB49002039F6 /* main.m */, 166 | 658365592109AB49002039F6 /* ZGiReader.xcdatamodeld */, 167 | ); 168 | path = ZGiReader; 169 | sourceTree = ""; 170 | }; 171 | 6583656B2109AB49002039F6 /* ZGiReaderTests */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | 6583656C2109AB49002039F6 /* ZGiReaderTests.m */, 175 | 6583656E2109AB49002039F6 /* Info.plist */, 176 | ); 177 | path = ZGiReaderTests; 178 | sourceTree = ""; 179 | }; 180 | 658365762109AB49002039F6 /* ZGiReaderUITests */ = { 181 | isa = PBXGroup; 182 | children = ( 183 | 658365772109AB49002039F6 /* ZGiReaderUITests.m */, 184 | 658365792109AB49002039F6 /* Info.plist */, 185 | ); 186 | path = ZGiReaderUITests; 187 | sourceTree = ""; 188 | }; 189 | 658365852109AB89002039F6 /* ZGiReaderController */ = { 190 | isa = PBXGroup; 191 | children = ( 192 | 65BAC19D2112F40000B06FFC /* 205832.txt */, 193 | 65534D3F2111BCDF00882AF1 /* test.txt */, 194 | 65BAC19F2112F7FD00B06FFC /* JJPreventCrash.h */, 195 | 65BAC1A02112F7FE00B06FFC /* JJPreventCrash.m */, 196 | 65BAC19A2112F22700B06FFC /* ZGiReaderReadUtilites.h */, 197 | 65BAC19B2112F22700B06FFC /* ZGiReaderReadUtilites.m */, 198 | 658CCD9921116088007E88B4 /* NSString+ZGiReaderPaging.h */, 199 | 658CCD9A21116088007E88B4 /* NSString+ZGiReaderPaging.m */, 200 | 658CCD9821115C90007E88B4 /* ZGiReaderHeader.h */, 201 | 658CCDA5211164D4007E88B4 /* ZGiReaderAppInfoManager.h */, 202 | 658CCDA6211164D4007E88B4 /* ZGiReaderAppInfoManager.m */, 203 | 6583658D2109B18F002039F6 /* ZGiReader */, 204 | 658365892109ABBF002039F6 /* Base */, 205 | ); 206 | path = ZGiReaderController; 207 | sourceTree = ""; 208 | }; 209 | 658365892109ABBF002039F6 /* Base */ = { 210 | isa = PBXGroup; 211 | children = ( 212 | 658365862109ABB1002039F6 /* ZGBaseViewController.h */, 213 | 658365872109ABB1002039F6 /* ZGBaseViewController.m */, 214 | ); 215 | name = Base; 216 | sourceTree = ""; 217 | }; 218 | 6583658D2109B18F002039F6 /* ZGiReader */ = { 219 | isa = PBXGroup; 220 | children = ( 221 | 658365902109B1D2002039F6 /* Model */, 222 | 6583658F2109B1C7002039F6 /* View */, 223 | 6583658E2109B1B3002039F6 /* Controller */, 224 | ); 225 | path = ZGiReader; 226 | sourceTree = ""; 227 | }; 228 | 6583658E2109B1B3002039F6 /* Controller */ = { 229 | isa = PBXGroup; 230 | children = ( 231 | 6583658A2109ABF1002039F6 /* ZGiReaderViewController.h */, 232 | 6583658B2109ABF1002039F6 /* ZGiReaderViewController.m */, 233 | 65CBD7C4211464A80047A146 /* ZGiReaderTopAndBottomBarController.h */, 234 | 65CBD7C5211464A80047A146 /* ZGiReaderTopAndBottomBarController.m */, 235 | ); 236 | name = Controller; 237 | sourceTree = ""; 238 | }; 239 | 6583658F2109B1C7002039F6 /* View */ = { 240 | isa = PBXGroup; 241 | children = ( 242 | 658365912109B525002039F6 /* ZGiReaderCollectionView.h */, 243 | 658365922109B525002039F6 /* ZGiReaderCollectionView.m */, 244 | 658CCD95211159A4007E88B4 /* ZGiReaderCollectionViewFlowLayout.h */, 245 | 658CCD96211159A4007E88B4 /* ZGiReaderCollectionViewFlowLayout.m */, 246 | 658CCD9C21116199007E88B4 /* ZGiReaderPageView.h */, 247 | 658CCD9D21116199007E88B4 /* ZGiReaderPageView.m */, 248 | 658CCDA821116762007E88B4 /* ZGiReaderPageCell.h */, 249 | 658CCDA921116762007E88B4 /* ZGiReaderPageCell.m */, 250 | 65BAC18E21129F8400B06FFC /* ZGiReaderCurrentTempView.h */, 251 | 65BAC18F21129F8400B06FFC /* ZGiReaderCurrentTempView.m */, 252 | ); 253 | name = View; 254 | sourceTree = ""; 255 | }; 256 | 658365902109B1D2002039F6 /* Model */ = { 257 | isa = PBXGroup; 258 | children = ( 259 | 658CCDA2211162A7007E88B4 /* ZGiReaderGlobalModel.h */, 260 | 658CCDA3211162A7007E88B4 /* ZGiReaderGlobalModel.m */, 261 | 65BAC1972112E77D00B06FFC /* ZGiReaderRecordModel.h */, 262 | 65BAC1982112E77D00B06FFC /* ZGiReaderRecordModel.m */, 263 | 65BAC1A22112FBFF00B06FFC /* ZGiReaderChapterModel.h */, 264 | 65BAC1A32112FBFF00B06FFC /* ZGiReaderChapterModel.m */, 265 | ); 266 | path = Model; 267 | sourceTree = ""; 268 | }; 269 | /* End PBXGroup section */ 270 | 271 | /* Begin PBXNativeTarget section */ 272 | 6583654C2109AB49002039F6 /* ZGiReader */ = { 273 | isa = PBXNativeTarget; 274 | buildConfigurationList = 6583657C2109AB49002039F6 /* Build configuration list for PBXNativeTarget "ZGiReader" */; 275 | buildPhases = ( 276 | 658365492109AB49002039F6 /* Sources */, 277 | 6583654A2109AB49002039F6 /* Frameworks */, 278 | 6583654B2109AB49002039F6 /* Resources */, 279 | ); 280 | buildRules = ( 281 | ); 282 | dependencies = ( 283 | ); 284 | name = ZGiReader; 285 | productName = ZGiReader; 286 | productReference = 6583654D2109AB49002039F6 /* ZGiReader.app */; 287 | productType = "com.apple.product-type.application"; 288 | }; 289 | 658365672109AB49002039F6 /* ZGiReaderTests */ = { 290 | isa = PBXNativeTarget; 291 | buildConfigurationList = 6583657F2109AB49002039F6 /* Build configuration list for PBXNativeTarget "ZGiReaderTests" */; 292 | buildPhases = ( 293 | 658365642109AB49002039F6 /* Sources */, 294 | 658365652109AB49002039F6 /* Frameworks */, 295 | 658365662109AB49002039F6 /* Resources */, 296 | ); 297 | buildRules = ( 298 | ); 299 | dependencies = ( 300 | 6583656A2109AB49002039F6 /* PBXTargetDependency */, 301 | ); 302 | name = ZGiReaderTests; 303 | productName = ZGiReaderTests; 304 | productReference = 658365682109AB49002039F6 /* ZGiReaderTests.xctest */; 305 | productType = "com.apple.product-type.bundle.unit-test"; 306 | }; 307 | 658365722109AB49002039F6 /* ZGiReaderUITests */ = { 308 | isa = PBXNativeTarget; 309 | buildConfigurationList = 658365822109AB49002039F6 /* Build configuration list for PBXNativeTarget "ZGiReaderUITests" */; 310 | buildPhases = ( 311 | 6583656F2109AB49002039F6 /* Sources */, 312 | 658365702109AB49002039F6 /* Frameworks */, 313 | 658365712109AB49002039F6 /* Resources */, 314 | ); 315 | buildRules = ( 316 | ); 317 | dependencies = ( 318 | 658365752109AB49002039F6 /* PBXTargetDependency */, 319 | ); 320 | name = ZGiReaderUITests; 321 | productName = ZGiReaderUITests; 322 | productReference = 658365732109AB49002039F6 /* ZGiReaderUITests.xctest */; 323 | productType = "com.apple.product-type.bundle.ui-testing"; 324 | }; 325 | /* End PBXNativeTarget section */ 326 | 327 | /* Begin PBXProject section */ 328 | 658365452109AB49002039F6 /* Project object */ = { 329 | isa = PBXProject; 330 | attributes = { 331 | CLASSPREFIX = ZGiReader; 332 | LastUpgradeCheck = 0910; 333 | ORGANIZATIONNAME = aikutv; 334 | TargetAttributes = { 335 | 6583654C2109AB49002039F6 = { 336 | CreatedOnToolsVersion = 9.1; 337 | ProvisioningStyle = Automatic; 338 | }; 339 | 658365672109AB49002039F6 = { 340 | CreatedOnToolsVersion = 9.1; 341 | ProvisioningStyle = Automatic; 342 | TestTargetID = 6583654C2109AB49002039F6; 343 | }; 344 | 658365722109AB49002039F6 = { 345 | CreatedOnToolsVersion = 9.1; 346 | ProvisioningStyle = Automatic; 347 | TestTargetID = 6583654C2109AB49002039F6; 348 | }; 349 | }; 350 | }; 351 | buildConfigurationList = 658365482109AB49002039F6 /* Build configuration list for PBXProject "ZGiReader" */; 352 | compatibilityVersion = "Xcode 8.0"; 353 | developmentRegion = en; 354 | hasScannedForEncodings = 0; 355 | knownRegions = ( 356 | en, 357 | Base, 358 | ); 359 | mainGroup = 658365442109AB49002039F6; 360 | productRefGroup = 6583654E2109AB49002039F6 /* Products */; 361 | projectDirPath = ""; 362 | projectRoot = ""; 363 | targets = ( 364 | 6583654C2109AB49002039F6 /* ZGiReader */, 365 | 658365672109AB49002039F6 /* ZGiReaderTests */, 366 | 658365722109AB49002039F6 /* ZGiReaderUITests */, 367 | ); 368 | }; 369 | /* End PBXProject section */ 370 | 371 | /* Begin PBXResourcesBuildPhase section */ 372 | 6583654B2109AB49002039F6 /* Resources */ = { 373 | isa = PBXResourcesBuildPhase; 374 | buildActionMask = 2147483647; 375 | files = ( 376 | 65BAC19E2112F40000B06FFC /* 205832.txt in Resources */, 377 | 658365602109AB49002039F6 /* LaunchScreen.storyboard in Resources */, 378 | 6583655D2109AB49002039F6 /* Assets.xcassets in Resources */, 379 | 65534D402111BCDF00882AF1 /* test.txt in Resources */, 380 | 658365582109AB49002039F6 /* Main.storyboard in Resources */, 381 | ); 382 | runOnlyForDeploymentPostprocessing = 0; 383 | }; 384 | 658365662109AB49002039F6 /* Resources */ = { 385 | isa = PBXResourcesBuildPhase; 386 | buildActionMask = 2147483647; 387 | files = ( 388 | ); 389 | runOnlyForDeploymentPostprocessing = 0; 390 | }; 391 | 658365712109AB49002039F6 /* Resources */ = { 392 | isa = PBXResourcesBuildPhase; 393 | buildActionMask = 2147483647; 394 | files = ( 395 | ); 396 | runOnlyForDeploymentPostprocessing = 0; 397 | }; 398 | /* End PBXResourcesBuildPhase section */ 399 | 400 | /* Begin PBXSourcesBuildPhase section */ 401 | 658365492109AB49002039F6 /* Sources */ = { 402 | isa = PBXSourcesBuildPhase; 403 | buildActionMask = 2147483647; 404 | files = ( 405 | 658CCD9B21116088007E88B4 /* NSString+ZGiReaderPaging.m in Sources */, 406 | 658CCD97211159A4007E88B4 /* ZGiReaderCollectionViewFlowLayout.m in Sources */, 407 | 6583658C2109ABF1002039F6 /* ZGiReaderViewController.m in Sources */, 408 | 658365552109AB49002039F6 /* ViewController.m in Sources */, 409 | 65BAC19021129F8400B06FFC /* ZGiReaderCurrentTempView.m in Sources */, 410 | 658CCDA4211162A7007E88B4 /* ZGiReaderGlobalModel.m in Sources */, 411 | 658CCDA7211164D4007E88B4 /* ZGiReaderAppInfoManager.m in Sources */, 412 | 65CBD7C6211464A80047A146 /* ZGiReaderTopAndBottomBarController.m in Sources */, 413 | 658CCDAA21116762007E88B4 /* ZGiReaderPageCell.m in Sources */, 414 | 65BAC1A12112F7FE00B06FFC /* JJPreventCrash.m in Sources */, 415 | 658365932109B525002039F6 /* ZGiReaderCollectionView.m in Sources */, 416 | 658CCD9E21116199007E88B4 /* ZGiReaderPageView.m in Sources */, 417 | 65BAC1A42112FBFF00B06FFC /* ZGiReaderChapterModel.m in Sources */, 418 | 658365882109ABB1002039F6 /* ZGBaseViewController.m in Sources */, 419 | 65BAC1992112E77D00B06FFC /* ZGiReaderRecordModel.m in Sources */, 420 | 658365522109AB49002039F6 /* AppDelegate.m in Sources */, 421 | 658365632109AB49002039F6 /* main.m in Sources */, 422 | 65BAC19C2112F22700B06FFC /* ZGiReaderReadUtilites.m in Sources */, 423 | 6583655B2109AB49002039F6 /* ZGiReader.xcdatamodeld in Sources */, 424 | ); 425 | runOnlyForDeploymentPostprocessing = 0; 426 | }; 427 | 658365642109AB49002039F6 /* Sources */ = { 428 | isa = PBXSourcesBuildPhase; 429 | buildActionMask = 2147483647; 430 | files = ( 431 | 6583656D2109AB49002039F6 /* ZGiReaderTests.m in Sources */, 432 | ); 433 | runOnlyForDeploymentPostprocessing = 0; 434 | }; 435 | 6583656F2109AB49002039F6 /* Sources */ = { 436 | isa = PBXSourcesBuildPhase; 437 | buildActionMask = 2147483647; 438 | files = ( 439 | 658365782109AB49002039F6 /* ZGiReaderUITests.m in Sources */, 440 | ); 441 | runOnlyForDeploymentPostprocessing = 0; 442 | }; 443 | /* End PBXSourcesBuildPhase section */ 444 | 445 | /* Begin PBXTargetDependency section */ 446 | 6583656A2109AB49002039F6 /* PBXTargetDependency */ = { 447 | isa = PBXTargetDependency; 448 | target = 6583654C2109AB49002039F6 /* ZGiReader */; 449 | targetProxy = 658365692109AB49002039F6 /* PBXContainerItemProxy */; 450 | }; 451 | 658365752109AB49002039F6 /* PBXTargetDependency */ = { 452 | isa = PBXTargetDependency; 453 | target = 6583654C2109AB49002039F6 /* ZGiReader */; 454 | targetProxy = 658365742109AB49002039F6 /* PBXContainerItemProxy */; 455 | }; 456 | /* End PBXTargetDependency section */ 457 | 458 | /* Begin PBXVariantGroup section */ 459 | 658365562109AB49002039F6 /* Main.storyboard */ = { 460 | isa = PBXVariantGroup; 461 | children = ( 462 | 658365572109AB49002039F6 /* Base */, 463 | ); 464 | name = Main.storyboard; 465 | sourceTree = ""; 466 | }; 467 | 6583655E2109AB49002039F6 /* LaunchScreen.storyboard */ = { 468 | isa = PBXVariantGroup; 469 | children = ( 470 | 6583655F2109AB49002039F6 /* Base */, 471 | ); 472 | name = LaunchScreen.storyboard; 473 | sourceTree = ""; 474 | }; 475 | /* End PBXVariantGroup section */ 476 | 477 | /* Begin XCBuildConfiguration section */ 478 | 6583657A2109AB49002039F6 /* Debug */ = { 479 | isa = XCBuildConfiguration; 480 | buildSettings = { 481 | ALWAYS_SEARCH_USER_PATHS = NO; 482 | CLANG_ANALYZER_NONNULL = YES; 483 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 484 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 485 | CLANG_CXX_LIBRARY = "libc++"; 486 | CLANG_ENABLE_MODULES = YES; 487 | CLANG_ENABLE_OBJC_ARC = YES; 488 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 489 | CLANG_WARN_BOOL_CONVERSION = YES; 490 | CLANG_WARN_COMMA = YES; 491 | CLANG_WARN_CONSTANT_CONVERSION = YES; 492 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 493 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 494 | CLANG_WARN_EMPTY_BODY = YES; 495 | CLANG_WARN_ENUM_CONVERSION = YES; 496 | CLANG_WARN_INFINITE_RECURSION = YES; 497 | CLANG_WARN_INT_CONVERSION = YES; 498 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 499 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 500 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 501 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 502 | CLANG_WARN_STRICT_PROTOTYPES = YES; 503 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 504 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 505 | CLANG_WARN_UNREACHABLE_CODE = YES; 506 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 507 | CODE_SIGN_IDENTITY = "iPhone Developer"; 508 | COPY_PHASE_STRIP = NO; 509 | DEBUG_INFORMATION_FORMAT = dwarf; 510 | ENABLE_STRICT_OBJC_MSGSEND = YES; 511 | ENABLE_TESTABILITY = YES; 512 | GCC_C_LANGUAGE_STANDARD = gnu11; 513 | GCC_DYNAMIC_NO_PIC = NO; 514 | GCC_NO_COMMON_BLOCKS = YES; 515 | GCC_OPTIMIZATION_LEVEL = 0; 516 | GCC_PREPROCESSOR_DEFINITIONS = ( 517 | "DEBUG=1", 518 | "$(inherited)", 519 | ); 520 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 521 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 522 | GCC_WARN_UNDECLARED_SELECTOR = YES; 523 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 524 | GCC_WARN_UNUSED_FUNCTION = YES; 525 | GCC_WARN_UNUSED_VARIABLE = YES; 526 | IPHONEOS_DEPLOYMENT_TARGET = 11.1; 527 | MTL_ENABLE_DEBUG_INFO = YES; 528 | ONLY_ACTIVE_ARCH = YES; 529 | SDKROOT = iphoneos; 530 | }; 531 | name = Debug; 532 | }; 533 | 6583657B2109AB49002039F6 /* Release */ = { 534 | isa = XCBuildConfiguration; 535 | buildSettings = { 536 | ALWAYS_SEARCH_USER_PATHS = NO; 537 | CLANG_ANALYZER_NONNULL = YES; 538 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 539 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 540 | CLANG_CXX_LIBRARY = "libc++"; 541 | CLANG_ENABLE_MODULES = YES; 542 | CLANG_ENABLE_OBJC_ARC = YES; 543 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 544 | CLANG_WARN_BOOL_CONVERSION = YES; 545 | CLANG_WARN_COMMA = YES; 546 | CLANG_WARN_CONSTANT_CONVERSION = YES; 547 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 548 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 549 | CLANG_WARN_EMPTY_BODY = YES; 550 | CLANG_WARN_ENUM_CONVERSION = YES; 551 | CLANG_WARN_INFINITE_RECURSION = YES; 552 | CLANG_WARN_INT_CONVERSION = YES; 553 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 554 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 555 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 556 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 557 | CLANG_WARN_STRICT_PROTOTYPES = YES; 558 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 559 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 560 | CLANG_WARN_UNREACHABLE_CODE = YES; 561 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 562 | CODE_SIGN_IDENTITY = "iPhone Developer"; 563 | COPY_PHASE_STRIP = NO; 564 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 565 | ENABLE_NS_ASSERTIONS = NO; 566 | ENABLE_STRICT_OBJC_MSGSEND = YES; 567 | GCC_C_LANGUAGE_STANDARD = gnu11; 568 | GCC_NO_COMMON_BLOCKS = YES; 569 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 570 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 571 | GCC_WARN_UNDECLARED_SELECTOR = YES; 572 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 573 | GCC_WARN_UNUSED_FUNCTION = YES; 574 | GCC_WARN_UNUSED_VARIABLE = YES; 575 | IPHONEOS_DEPLOYMENT_TARGET = 11.1; 576 | MTL_ENABLE_DEBUG_INFO = NO; 577 | SDKROOT = iphoneos; 578 | VALIDATE_PRODUCT = YES; 579 | }; 580 | name = Release; 581 | }; 582 | 6583657D2109AB49002039F6 /* Debug */ = { 583 | isa = XCBuildConfiguration; 584 | buildSettings = { 585 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 586 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 587 | CODE_SIGN_STYLE = Automatic; 588 | DEVELOPMENT_TEAM = 85X69HTM5H; 589 | INFOPLIST_FILE = ZGiReader/Info.plist; 590 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 591 | PRODUCT_BUNDLE_IDENTIFIER = www.aikutv.cc; 592 | PRODUCT_NAME = "$(TARGET_NAME)"; 593 | PROVISIONING_PROFILE_SPECIFIER = ""; 594 | TARGETED_DEVICE_FAMILY = "1,2"; 595 | }; 596 | name = Debug; 597 | }; 598 | 6583657E2109AB49002039F6 /* Release */ = { 599 | isa = XCBuildConfiguration; 600 | buildSettings = { 601 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 602 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 603 | CODE_SIGN_STYLE = Automatic; 604 | DEVELOPMENT_TEAM = 85X69HTM5H; 605 | INFOPLIST_FILE = ZGiReader/Info.plist; 606 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 607 | PRODUCT_BUNDLE_IDENTIFIER = www.aikutv.cc; 608 | PRODUCT_NAME = "$(TARGET_NAME)"; 609 | PROVISIONING_PROFILE_SPECIFIER = ""; 610 | TARGETED_DEVICE_FAMILY = "1,2"; 611 | }; 612 | name = Release; 613 | }; 614 | 658365802109AB49002039F6 /* Debug */ = { 615 | isa = XCBuildConfiguration; 616 | buildSettings = { 617 | BUNDLE_LOADER = "$(TEST_HOST)"; 618 | CODE_SIGN_STYLE = Automatic; 619 | INFOPLIST_FILE = ZGiReaderTests/Info.plist; 620 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 621 | PRODUCT_BUNDLE_IDENTIFIER = www.aikutv.cc.ZGiReaderTests; 622 | PRODUCT_NAME = "$(TARGET_NAME)"; 623 | TARGETED_DEVICE_FAMILY = "1,2"; 624 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ZGiReader.app/ZGiReader"; 625 | }; 626 | name = Debug; 627 | }; 628 | 658365812109AB49002039F6 /* Release */ = { 629 | isa = XCBuildConfiguration; 630 | buildSettings = { 631 | BUNDLE_LOADER = "$(TEST_HOST)"; 632 | CODE_SIGN_STYLE = Automatic; 633 | INFOPLIST_FILE = ZGiReaderTests/Info.plist; 634 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 635 | PRODUCT_BUNDLE_IDENTIFIER = www.aikutv.cc.ZGiReaderTests; 636 | PRODUCT_NAME = "$(TARGET_NAME)"; 637 | TARGETED_DEVICE_FAMILY = "1,2"; 638 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ZGiReader.app/ZGiReader"; 639 | }; 640 | name = Release; 641 | }; 642 | 658365832109AB49002039F6 /* Debug */ = { 643 | isa = XCBuildConfiguration; 644 | buildSettings = { 645 | CODE_SIGN_STYLE = Automatic; 646 | INFOPLIST_FILE = ZGiReaderUITests/Info.plist; 647 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 648 | PRODUCT_BUNDLE_IDENTIFIER = www.aikutv.cc.ZGiReaderUITests; 649 | PRODUCT_NAME = "$(TARGET_NAME)"; 650 | TARGETED_DEVICE_FAMILY = "1,2"; 651 | TEST_TARGET_NAME = ZGiReader; 652 | }; 653 | name = Debug; 654 | }; 655 | 658365842109AB49002039F6 /* Release */ = { 656 | isa = XCBuildConfiguration; 657 | buildSettings = { 658 | CODE_SIGN_STYLE = Automatic; 659 | INFOPLIST_FILE = ZGiReaderUITests/Info.plist; 660 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 661 | PRODUCT_BUNDLE_IDENTIFIER = www.aikutv.cc.ZGiReaderUITests; 662 | PRODUCT_NAME = "$(TARGET_NAME)"; 663 | TARGETED_DEVICE_FAMILY = "1,2"; 664 | TEST_TARGET_NAME = ZGiReader; 665 | }; 666 | name = Release; 667 | }; 668 | /* End XCBuildConfiguration section */ 669 | 670 | /* Begin XCConfigurationList section */ 671 | 658365482109AB49002039F6 /* Build configuration list for PBXProject "ZGiReader" */ = { 672 | isa = XCConfigurationList; 673 | buildConfigurations = ( 674 | 6583657A2109AB49002039F6 /* Debug */, 675 | 6583657B2109AB49002039F6 /* Release */, 676 | ); 677 | defaultConfigurationIsVisible = 0; 678 | defaultConfigurationName = Release; 679 | }; 680 | 6583657C2109AB49002039F6 /* Build configuration list for PBXNativeTarget "ZGiReader" */ = { 681 | isa = XCConfigurationList; 682 | buildConfigurations = ( 683 | 6583657D2109AB49002039F6 /* Debug */, 684 | 6583657E2109AB49002039F6 /* Release */, 685 | ); 686 | defaultConfigurationIsVisible = 0; 687 | defaultConfigurationName = Release; 688 | }; 689 | 6583657F2109AB49002039F6 /* Build configuration list for PBXNativeTarget "ZGiReaderTests" */ = { 690 | isa = XCConfigurationList; 691 | buildConfigurations = ( 692 | 658365802109AB49002039F6 /* Debug */, 693 | 658365812109AB49002039F6 /* Release */, 694 | ); 695 | defaultConfigurationIsVisible = 0; 696 | defaultConfigurationName = Release; 697 | }; 698 | 658365822109AB49002039F6 /* Build configuration list for PBXNativeTarget "ZGiReaderUITests" */ = { 699 | isa = XCConfigurationList; 700 | buildConfigurations = ( 701 | 658365832109AB49002039F6 /* Debug */, 702 | 658365842109AB49002039F6 /* Release */, 703 | ); 704 | defaultConfigurationIsVisible = 0; 705 | defaultConfigurationName = Release; 706 | }; 707 | /* End XCConfigurationList section */ 708 | 709 | /* Begin XCVersionGroup section */ 710 | 658365592109AB49002039F6 /* ZGiReader.xcdatamodeld */ = { 711 | isa = XCVersionGroup; 712 | children = ( 713 | 6583655A2109AB49002039F6 /* ZGiReader.xcdatamodel */, 714 | ); 715 | currentVersion = 6583655A2109AB49002039F6 /* ZGiReader.xcdatamodel */; 716 | path = ZGiReader.xcdatamodeld; 717 | sourceTree = ""; 718 | versionGroupType = wrapper.xcdatamodel; 719 | }; 720 | /* End XCVersionGroup section */ 721 | }; 722 | rootObject = 658365452109AB49002039F6 /* Project object */; 723 | } 724 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReader.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReader.xcodeproj/project.xcworkspace/xcuserdata/yangzhenguo.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/123456github/ZGiReader/c92b0272e6476f8862eea490e2cdf34c857ebc39/ZGiReader/ZGiReader.xcodeproj/project.xcworkspace/xcuserdata/yangzhenguo.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ZGiReader/ZGiReader.xcodeproj/xcuserdata/yangzhenguo.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 18 | 30 | 31 | 32 | 34 | 46 | 47 | 48 | 50 | 62 | 63 | 64 | 66 | 78 | 79 | 80 | 82 | 94 | 95 | 96 | 98 | 110 | 111 | 112 | 114 | 126 | 127 | 128 | 130 | 142 | 143 | 144 | 146 | 158 | 159 | 160 | 162 | 174 | 175 | 176 | 178 | 190 | 191 | 192 | 194 | 206 | 207 | 208 | 209 | 210 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReader.xcodeproj/xcuserdata/yangzhenguo.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ZGiReader.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReader/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/7/26. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | 16 | @property (readonly, strong) NSPersistentContainer *persistentContainer; 17 | 18 | - (void)saveContext; 19 | 20 | 21 | @end 22 | 23 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReader/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/7/26. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | // Saves changes in the application's managed object context before the application terminates. 49 | [self saveContext]; 50 | } 51 | 52 | 53 | #pragma mark - Core Data stack 54 | 55 | @synthesize persistentContainer = _persistentContainer; 56 | 57 | - (NSPersistentContainer *)persistentContainer { 58 | // The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it. 59 | @synchronized (self) { 60 | if (_persistentContainer == nil) { 61 | _persistentContainer = [[NSPersistentContainer alloc] initWithName:@"ZGiReader"]; 62 | [_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) { 63 | if (error != nil) { 64 | // Replace this implementation with code to handle the error appropriately. 65 | // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 66 | 67 | /* 68 | Typical reasons for an error here include: 69 | * The parent directory does not exist, cannot be created, or disallows writing. 70 | * The persistent store is not accessible, due to permissions or data protection when the device is locked. 71 | * The device is out of space. 72 | * The store could not be migrated to the current model version. 73 | Check the error message to determine what the actual problem was. 74 | */ 75 | NSLog(@"Unresolved error %@, %@", error, error.userInfo); 76 | abort(); 77 | } 78 | }]; 79 | } 80 | } 81 | 82 | return _persistentContainer; 83 | } 84 | 85 | #pragma mark - Core Data Saving support 86 | 87 | - (void)saveContext { 88 | NSManagedObjectContext *context = self.persistentContainer.viewContext; 89 | NSError *error = nil; 90 | if ([context hasChanges] && ![context save:&error]) { 91 | // Replace this implementation with code to handle the error appropriately. 92 | // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 93 | NSLog(@"Unresolved error %@, %@", error, error.userInfo); 94 | abort(); 95 | } 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReader/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /ZGiReader/ZGiReader/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 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReader/Base.lproj/Main.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 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReader/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReader/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/7/26. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReader/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/7/26. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "ZGiReaderViewController.h" 11 | #import "ZGiReaderReadUtilites.h" 12 | #import "JJPreventCrash.h" 13 | 14 | @interface ViewController () 15 | @property(nonatomic,strong)UINavigationController * iNavigationController; 16 | @end 17 | 18 | @implementation ViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | 23 | 24 | 25 | [self setupUI]; 26 | 27 | 28 | 29 | } 30 | 31 | - (void)setupUI 32 | { 33 | UIButton * btn = [[UIButton alloc]init]; 34 | btn.center = self.view.center; 35 | btn.backgroundColor = [UIColor redColor]; 36 | [btn setTitle:@"开始阅读" forState:UIControlStateNormal]; 37 | [self.view addSubview:btn]; 38 | btn.bounds = CGRectMake(0, 0, 100, 50); 39 | [btn addTarget:self action:@selector(toMainVc) forControlEvents:UIControlEventTouchUpInside]; 40 | } 41 | 42 | - (void)toMainVc 43 | { 44 | NSURL *url = [[NSBundle mainBundle] URLForResource:@"205832" withExtension:@"txt"]; 45 | 46 | 47 | NSString * str = [ZGiReaderReadUtilites encodeWithURL:url];//[NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil]; 48 | NSArray * arr = [ZGiReaderReadUtilites encodeReturnFilterSplitContentTextWithURL:url]; 49 | 50 | ZGiReaderChapterModel * model = [JJPreventCrash jjObjectWithArray:arr AndAtIndex:100];//显示第几章传入几,适用于目录 51 | 52 | ZGiReaderViewController * iReaderViewController = [ZGiReaderViewController new]; 53 | [self addChildViewController:iReaderViewController]; 54 | [self.view addSubview:iReaderViewController.view]; 55 | [iReaderViewController loadText:model.chapterContent]; 56 | 57 | 58 | } 59 | 60 | 61 | 62 | - (void)didReceiveMemoryWarning { 63 | [super didReceiveMemoryWarning]; 64 | // Dispose of any resources that can be recreated. 65 | } 66 | 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReader/ZGiReader.xcdatamodeld/ZGiReader.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReader/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/7/26. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/JJPreventCrash.h: -------------------------------------------------------------------------------- 1 | // 2 | // JJPreventCrash.h 3 | // JINJIANG-iOS 4 | // 5 | // Created by 杨振国 on 2017/12/8. 6 | // Copyright © 2017年 Andy. All rights reserved. 7 | // 8 | 9 | #import 10 | #define jjString(str) [JJPreventCrash jjFilterTheAfferentString:str] 11 | @interface JJPreventCrash : NSObject 12 | 13 | + (NSString *)jjFilterTheAfferentString:(NSString *)str; 14 | 15 | + (id)jjObjectWithArray:(NSArray*)array AndAtIndex:(NSInteger)index; 16 | + (NSDictionary *)jjDictionaryWithArray:(NSArray*)array AndAtIndex:(NSInteger)index; 17 | + (NSString *)jjDictionaryValue:(NSArray *)array index:(NSInteger)index key:(NSString *)key; 18 | + (NSArray *)jjDictionary:(NSDictionary *)dict objectForKey:(NSString *)key; 19 | + (NSString *)jjRetuenStringDictionary:(NSDictionary *)dict objectForKey:(NSString *)key; 20 | + (NSArray *)jjArray:(NSArray *)array index:(NSInteger)index key:(NSString *)key; 21 | /** 22 | 过滤字符串 23 | 24 | @param value 需要过滤的字符串 25 | @param str 如果value不是string设置的默认str,此str最好不要为nil 26 | @return 如果是string就返回原来的value,不是就返回str 27 | */ 28 | + (NSString *)jjValueIsNil:(NSString *)value BecomeString:(NSString *)str; 29 | 30 | + (NSDictionary *)jjReturnDictionaryInDictionary:(NSDictionary *)dict key:(NSString *)key; 31 | 32 | + (NSString *)jjParseString:(NSDictionary *)dictionary key:(NSString *)key; 33 | //防止往可变数组中插入非对象类型数据 34 | + (NSMutableArray *)jjAddObjectWithArrayM:(NSMutableArray *)arrM addObject:(NSObject *)obj; 35 | 36 | 37 | /** 38 | 从一个字符串中截取对应位置和长度的字符串 39 | 40 | @param string 从该字符串中截取内容 41 | @param range 要截取的位置和长度 42 | @return 返回截取成功的字符串 43 | */ 44 | + (NSString *)jjReturnSubStringWithString:(NSString *)string substringWithRange:(NSRange)range; 45 | @end 46 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/JJPreventCrash.m: -------------------------------------------------------------------------------- 1 | // 2 | // JJPreventCrash.m 3 | // JINJIANG-iOS 4 | // 5 | // Created by 杨振国 on 2017/12/8. 6 | // Copyright © 2017年 Andy. All rights reserved. 7 | // 8 | 9 | #import "JJPreventCrash.h" 10 | 11 | 12 | 13 | @implementation JJPreventCrash 14 | 15 | + (NSString *)jjFilterTheAfferentString:(NSString *)str 16 | { 17 | if ([str isKindOfClass:[NSString class]]) { 18 | return str; 19 | }else{ 20 | return [NSString string]; 21 | } 22 | } 23 | 24 | 25 | + (NSString *)jjRetuenStringDictionary:(NSDictionary *)dict objectForKey:(NSString *)key 26 | { 27 | if ([dict isKindOfClass:[NSDictionary class]]) 28 | { 29 | for (NSString * str in [dict allKeys]) 30 | { 31 | if ([str isEqualToString:key]) 32 | { 33 | NSString * str = [dict objectForKey:key]; 34 | return jjString(str); 35 | } 36 | 37 | } 38 | 39 | return [NSString string]; 40 | 41 | }else{ 42 | return [NSString string]; 43 | } 44 | 45 | } 46 | 47 | /** 48 | 过滤字符串 49 | 50 | @param value 需要过滤的字符串 51 | @param str 如果value不是string设置的默认str,此str最好不要为nil 52 | @return 如果是string就返回原来的value,不是就返回str 53 | */ 54 | + (NSString *)jjValueIsNil:(NSString *)value BecomeString:(NSString *)str 55 | { 56 | if ([value isKindOfClass:[NSString class]]) { 57 | return value; 58 | }else{ 59 | NSLog(@"传入的数据异常"); 60 | return str; 61 | } 62 | } 63 | + (NSArray *)jjArray:(NSArray *)array index:(NSInteger)index key:(NSString *)key 64 | { 65 | if (([array isKindOfClass:[NSArray class]]) && array.count > index && index > -1 && ([key isKindOfClass:[NSString class]])) 66 | { 67 | if ([[array objectAtIndex:index] isKindOfClass:[NSDictionary class]]) { 68 | return [[array objectAtIndex:index] objectForKey:key]; 69 | }else{ 70 | NSLog(@"数组越界"); 71 | return [NSArray array]; 72 | } 73 | 74 | }else{ 75 | NSLog(@"数组越界"); 76 | return [NSArray array]; 77 | } 78 | } 79 | + (id)jjObjectWithArray:(NSArray*)array AndAtIndex:(NSInteger)index 80 | { 81 | if (array.count > index && index > -1 && [array isKindOfClass:[NSArray class]]) { 82 | id object = [array objectAtIndex:index]; 83 | return object; 84 | } 85 | NSLog(@"数组越界"); 86 | return nil; 87 | } 88 | + (NSDictionary *)jjDictionaryWithArray:(NSArray*)array AndAtIndex:(NSInteger)index 89 | { 90 | if (array.count > index && index > -1 && [array isKindOfClass:[NSArray class]]) { 91 | id object = [array objectAtIndex:index]; 92 | return object; 93 | } 94 | NSLog(@"数组越界"); 95 | return [NSDictionary dictionary]; 96 | } 97 | 98 | 99 | /** 100 | 根据数组下标取出字典,根据字典的key取出value 101 | 102 | @param array 最外层数组 103 | @param index 数组下标 104 | @param key 该下标下的字典的key 105 | @return 返回字典中key对应的value 106 | */ 107 | + (NSString *)jjDictionaryValue:(NSArray *)array index:(NSInteger)index key:(NSString *)key 108 | { 109 | if (array) { 110 | if (array.count > index && index > -1) { 111 | id tempid = [array objectAtIndex:index]; 112 | if ([tempid isKindOfClass:[NSDictionary class]]) { 113 | NSDictionary *tempDic = (NSDictionary *)tempid; 114 | if (key) { 115 | if ([tempDic objectForKey:key] && [[tempDic objectForKey:key] isKindOfClass:[NSString class]]) { 116 | NSString *string = (NSString *)[tempDic objectForKey:key]; 117 | return string; 118 | }else if ([tempDic objectForKey:key] && [[tempDic objectForKey:key] isKindOfClass:[NSNumber class]]){ 119 | NSNumber *value = [tempDic objectForKey:key]; 120 | return [NSString stringWithFormat:@"%td", [value integerValue]]; 121 | 122 | } 123 | } 124 | } 125 | } 126 | } 127 | return [NSString string]; 128 | } 129 | 130 | + (NSArray *)jjDictionary:(NSDictionary *)dict objectForKey:(NSString *)key 131 | { 132 | if([[dict objectForKey:key] isKindOfClass:[NSNull class]] || (![dict isKindOfClass:[NSDictionary class]])){ 133 | return [NSArray array]; 134 | }else{ 135 | return [dict objectForKey:key]; 136 | } 137 | } 138 | + (NSDictionary *)jjReturnDictionaryInDictionary:(NSDictionary *)dict key:(NSString *)key 139 | { 140 | if ([dict isKindOfClass:[NSDictionary class]] && [key isKindOfClass:[NSString class]]) { 141 | if ([[dict objectForKey:key] isKindOfClass:[NSDictionary class]]) { 142 | return [dict objectForKey:key]; 143 | }else{ 144 | return [NSDictionary dictionary]; 145 | } 146 | }else{ 147 | return [NSDictionary dictionary]; 148 | } 149 | 150 | 151 | } 152 | 153 | + (NSString *)jjParseString:(NSDictionary *)dictionary key:(NSString *)key 154 | { 155 | if (!dictionary || !key) { 156 | return @""; 157 | } 158 | id temp = [dictionary objectForKey:key]; 159 | if (temp && [temp isKindOfClass:[NSString class]]) { 160 | NSString *backString = (NSString *)temp; 161 | return backString; 162 | }else if (temp && [temp isKindOfClass:[NSNumber class]]) { 163 | NSNumber *backString = (NSNumber *)temp; 164 | 165 | double maxQuota = [backString doubleValue]; 166 | return [NSString stringWithFormat:@"%.2f", maxQuota]; 167 | }else{ 168 | return @""; 169 | } 170 | } 171 | + (NSMutableArray *)jjAddObjectWithArrayM:(NSMutableArray *)arrM addObject:(NSObject *)obj 172 | { 173 | if ([arrM isKindOfClass:[NSMutableArray class]] && [obj isKindOfClass:[NSObject class]]) { 174 | [arrM addObject:obj]; 175 | return arrM; 176 | }else{ 177 | return arrM; 178 | } 179 | } 180 | 181 | + (NSString *)jjReturnSubStringWithString:(NSString *)string substringWithRange:(NSRange)range 182 | { 183 | if ([string isKindOfClass:[NSString class]] && (range.location + range.length) <= string.length && range.location < string.length && range.length > 0) { 184 | return [string substringWithRange:range]; 185 | }else{ 186 | NSLog(@"--------字符串截取时出错--------"); 187 | 188 | return [NSString string]; 189 | } 190 | } 191 | @end 192 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/NSString+ZGiReaderPaging.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+ZGiReaderPaging.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/1. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface NSString (ZGiReaderPaging) 13 | - (NSArray *)paginationWithAttributes:(NSDictionary *)attributes constrainedToSize:(CGSize)size; 14 | 15 | - (NSString *)halfWidthToFullWidth; 16 | @end 17 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/NSString+ZGiReaderPaging.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+ZGiReaderPaging.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/1. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "NSString+ZGiReaderPaging.h" 10 | #import 11 | 12 | @implementation NSString (ZGiReaderPaging) 13 | /** 14 | * @abstract 根据指定的大小,对字符串进行分页,计算出每页显示的字符串区间(NSRange) 15 | * 16 | * @param attributes 分页所需的字符串样式,需要指定字体大小,行间距等。iOS6.0以上请参见UIKit中NSAttributedString的扩展,iOS6.0以下请参考CoreText中的CTStringAttributes.h 17 | * @param size 需要参考的size。即在size区域内 18 | */ 19 | - (NSArray *)paginationWithAttributes:(NSDictionary *)attributes constrainedToSize:(CGSize)size { 20 | NSMutableArray * resultRange = [NSMutableArray arrayWithCapacity:5]; 21 | CGRect rect = CGRectMake(0, 0, size.width, size.height); 22 | // 构造NSAttributedString 23 | NSAttributedString * attributedString = [[NSAttributedString alloc] initWithString:self attributes:attributes]; 24 | 25 | // 以下方法耗时 基本再 0.5s 以内 26 | NSDate * date = [NSDate date]; 27 | NSInteger rangeIndex = 0; 28 | do { 29 | //TODO 需要根据具体字号对最小值就行分别设定 30 | unsigned long length = MIN(750, attributedString.length - rangeIndex); 31 | NSAttributedString * childString = [attributedString attributedSubstringFromRange:NSMakeRange(rangeIndex, length)]; 32 | 33 | CTFramesetterRef childFramesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef) childString); 34 | UIBezierPath * bezierPath = [UIBezierPath bezierPathWithRect:rect]; 35 | CTFrameRef frame = CTFramesetterCreateFrame(childFramesetter, CFRangeMake(0, 0), bezierPath.CGPath, NULL); 36 | 37 | CFRange range = CTFrameGetVisibleStringRange(frame); 38 | NSRange r = {rangeIndex, range.length}; 39 | 40 | if (r.length > 0) { 41 | [resultRange addObject:NSStringFromRange(r)]; 42 | } 43 | rangeIndex += r.length; 44 | CFRelease(frame); 45 | CFRelease(childFramesetter); 46 | } while (rangeIndex < attributedString.length && attributedString.length > 0); 47 | NSTimeInterval millionSecond = [[NSDate date] timeIntervalSinceDate:date]; 48 | NSLog(@"耗时 %@", [NSString stringWithFormat:@"%lf", millionSecond]); 49 | return resultRange; 50 | } 51 | 52 | - (NSString *)halfWidthToFullWidth 53 | { 54 | //半角转全角 55 | NSMutableString *convertedString = [self mutableCopy]; 56 | CFStringTransform((CFMutableStringRef)convertedString, NULL, kCFStringTransformHiraganaKatakana, false); 57 | return [convertedString copy]; 58 | } 59 | @end 60 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGBaseViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZGBaseViewController.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/7/26. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZGBaseViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGBaseViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGBaseViewController.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/7/26. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGBaseViewController.h" 10 | 11 | @interface ZGBaseViewController () 12 | 13 | @end 14 | 15 | @implementation ZGBaseViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | 20 | // Do any additional setup after loading the view. 21 | } 22 | 23 | - (void)didReceiveMemoryWarning { 24 | [super didReceiveMemoryWarning]; 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | /* 29 | #pragma mark - Navigation 30 | 31 | // In a storyboard-based application, you will often want to do a little preparation before navigation 32 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 33 | // Get the new view controller using [segue destinationViewController]. 34 | // Pass the selected object to the new view controller. 35 | } 36 | */ 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/Model/ZGiReaderChapterModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderChapterModel.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/2. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZGiReaderChapterModel : NSObject 12 | @property(nonatomic,strong)NSString * title; 13 | @property(nonatomic,strong)NSString * chapterContent; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/Model/ZGiReaderChapterModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderChapterModel.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/2. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGiReaderChapterModel.h" 10 | 11 | @implementation ZGiReaderChapterModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/Model/ZGiReaderGlobalModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderGlobalModel.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/1. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | static NSString *kUpdatePageNotification = @"kUpdatePageNotification"; 13 | @interface ZGiReaderGlobalModel : NSObject 14 | @property (nonatomic, strong) NSString *text; 15 | @property (nonatomic, strong) NSMutableArray *rangeArray; 16 | @property (nonatomic, strong) NSDictionary *attributes; 17 | @property (nonatomic,assign) CGFloat fontSize; 18 | @property (nonatomic,assign) int lineSpace; 19 | @property (nonatomic,assign) CGFloat marginSpace;//页边距 20 | @property (nonatomic) NSInteger currentPage; 21 | @property (nonatomic) NSRange currentRange; //尚未使用 22 | @property (nonatomic,strong)UIColor *bgColor; 23 | 24 | 25 | + (instancetype)shareModel; 26 | 27 | - (void)loadText:(NSString *)text completion:(void(^)(void))completion; 28 | 29 | - (void)updateFontCompletion:(void(^)(void))completion; 30 | @end 31 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/Model/ZGiReaderGlobalModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderGlobalModel.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/1. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGiReaderGlobalModel.h" 10 | #import "ZGiReaderHeader.h" 11 | #import "NSString+ZGiReaderPaging.h" 12 | 13 | @implementation ZGiReaderGlobalModel 14 | + (instancetype)shareModel 15 | { 16 | static ZGiReaderGlobalModel *model = nil; 17 | static dispatch_once_t predicate; 18 | dispatch_once(&predicate, ^{ 19 | model = [[ZGiReaderGlobalModel alloc] init]; 20 | }); 21 | return model; 22 | } 23 | 24 | - (instancetype)init 25 | { 26 | self = [super init]; 27 | if (self) { 28 | // self.fontSize = 18; 29 | } 30 | return self; 31 | } 32 | 33 | - (void)loadText:(NSString *)text completion:(void (^)(void))completion 34 | { 35 | self.text = text; 36 | [self pagingTextCompletion:completion]; 37 | } 38 | 39 | - (void)pagingTextCompletion:(void (^)(void))completion 40 | { 41 | NSMutableDictionary * attributes = [NSMutableDictionary dictionaryWithCapacity:5]; 42 | UIFont * font = [UIFont systemFontOfSize:self.fontSize]; 43 | [attributes setValue:font forKey:NSFontAttributeName]; 44 | [attributes setValue:@(1.0) forKey:NSKernAttributeName]; 45 | [attributes setValue:@(1.0) forKey:NSKernAttributeName]; 46 | // UIColor *color = [E_CommonManager color];//颜色暂时去掉 47 | //[attributes setValue:color forKey:NSForegroundColorAttributeName]; 48 | NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 49 | paragraphStyle.lineSpacing = self.lineSpace;//行距 50 | // paragraphStyle.paragraphSpacing = 0.0;//段距 51 | paragraphStyle.alignment = NSTextAlignmentJustified; 52 | [attributes setValue:paragraphStyle forKey:NSParagraphStyleAttributeName]; 53 | self.attributes = [attributes copy]; 54 | self.rangeArray = [[self.text paginationWithAttributes:self.attributes constrainedToSize:ZGiReader_pageView_Size] mutableCopy];//每一页的大小 55 | if (completion) { 56 | completion(); 57 | } 58 | } 59 | 60 | - (void)updateFontCompletion:(void (^)(void))completion 61 | { 62 | //取回之前的定位页数 63 | NSRange range = self.currentRange; 64 | [self pagingTextCompletion:^{ 65 | //重新定位页码 66 | [self.rangeArray enumerateObjectsUsingBlock:^(NSString *rangeStr, NSUInteger idx, BOOL *stop) { 67 | NSRange tempRange = NSRangeFromString(rangeStr); 68 | if (tempRange.location <= range.location && tempRange.location + tempRange.length > range.location) { 69 | self.currentPage = idx; 70 | *stop = YES; 71 | } 72 | }]; 73 | if (completion) { 74 | completion(); 75 | } 76 | }]; 77 | } 78 | 79 | //- (void)setFontSize:(CGFloat)fontSize 80 | //{ 81 | // if (fontSize < 14.0) { 82 | // _fontSize = 14.0; 83 | // } else if (fontSize > 30.0) { 84 | // _fontSize = 30.0; 85 | // } else { 86 | // _fontSize = fontSize; 87 | // } 88 | //} 89 | 90 | -(void)setLineSpace:(int)lineSpace 91 | { 92 | _lineSpace = lineSpace; 93 | // if (lineSpace) { 94 | // <#statements#> 95 | // } 96 | } 97 | 98 | - (void)setCurrentRange:(NSRange)currentRange 99 | { 100 | _currentRange = currentRange; 101 | NSLog(@"%@", NSStringFromRange(_currentRange)); 102 | } 103 | 104 | @end 105 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/Model/ZGiReaderRecordModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderRecordModel.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/2. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZGiReaderRecordModel : NSObject 12 | @property (nonatomic,strong) NSString * contentString; 13 | //@property (nonatomic,strong) ZGiReaderRecordModel *chapterModel; //阅读的章节 14 | //@property (nonatomic) NSUInteger page; //阅读的页数 15 | //@property (nonatomic) NSUInteger chapter; //阅读的章节数 16 | //@property (nonatomic) NSUInteger chapterCount; //总章节数 17 | @end 18 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/Model/ZGiReaderRecordModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderRecordModel.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/2. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGiReaderRecordModel.h" 10 | 11 | @implementation ZGiReaderRecordModel 12 | -(id)copyWithZone:(NSZone *)zone 13 | { 14 | ZGiReaderRecordModel *recordModel = [[ZGiReaderRecordModel allocWithZone:zone]init]; 15 | recordModel.contentString = self.contentString; 16 | // recordModel.chapterModel = [self.chapterModel copy]; 17 | // recordModel.page = self.page; 18 | // recordModel.chapter = self.chapter; 19 | return recordModel; 20 | } 21 | 22 | -(void)encodeWithCoder:(NSCoder *)aCoder{ 23 | [aCoder encodeObject:self.contentString forKey:@"contentString"]; 24 | // [aCoder encodeInteger:self.page forKey:@"page"]; 25 | // [aCoder encodeInteger:self.chapter forKey:@"chapter"]; 26 | // [aCoder encodeInteger:self.chapterCount forKey:@"chapterCount"]; 27 | } 28 | -(id)initWithCoder:(NSCoder *)aDecoder{ 29 | self = [super init]; 30 | if (self) { 31 | self.contentString = [aDecoder decodeObjectForKey:@"contentString"]; 32 | // self.page = [aDecoder decodeIntegerForKey:@"page"]; 33 | // self.chapter = [aDecoder decodeIntegerForKey:@"chapter"]; 34 | // self.chapterCount = [aDecoder decodeIntegerForKey:@"chapterCount"]; 35 | } 36 | return self; 37 | } 38 | @end 39 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/ZGiReaderCollectionView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderCollectionView.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/7/26. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZGiReaderCollectionView : UICollectionView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/ZGiReaderCollectionView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderCollectionView.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/7/26. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGiReaderCollectionView.h" 10 | 11 | @implementation ZGiReaderCollectionView 12 | 13 | - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout 14 | { 15 | if (self = [super initWithFrame:frame collectionViewLayout:layout]) { 16 | [self setupUI]; 17 | } 18 | return self; 19 | } 20 | 21 | 22 | 23 | - (void)setupUI 24 | { 25 | 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/ZGiReaderCollectionViewFlowLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderCollectionViewFlowLayout.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/1. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ZGiReaderHeader.h" 11 | @interface ZGiReaderCollectionViewFlowLayout : UICollectionViewFlowLayout 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/ZGiReaderCollectionViewFlowLayout.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderCollectionViewFlowLayout.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/1. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGiReaderCollectionViewFlowLayout.h" 10 | 11 | @implementation ZGiReaderCollectionViewFlowLayout 12 | - (void)prepareLayout 13 | { 14 | self.itemSize = CGSizeMake(K_SCREEN_WIDTH, K_SCREEN_HEIGHT); 15 | //水平滑动 16 | self.scrollDirection = UICollectionViewScrollDirectionHorizontal; 17 | //上左下右四个偏移量 18 | self.sectionInset = UIEdgeInsetsMake(0,0,0,0); 19 | //每个cell之间的间距 20 | self.minimumInteritemSpacing = 0; 21 | self.minimumLineSpacing = 0; 22 | 23 | } 24 | @end 25 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/ZGiReaderCurrentTempView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderCurrentTempView.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/2. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ZGiReaderPageView.h" 11 | 12 | @interface ZGiReaderCurrentTempView : UIView 13 | @property (nonatomic, strong) ZGiReaderPageView *pageView; 14 | @end 15 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/ZGiReaderCurrentTempView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderCurrentTempView.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/2. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGiReaderCurrentTempView.h" 10 | #import "ZGiReaderHeader.h" 11 | 12 | @interface ZGiReaderCurrentTempView() 13 | 14 | @property (nonatomic, assign) CGRect iFrame; 15 | 16 | @end 17 | 18 | @implementation ZGiReaderCurrentTempView 19 | 20 | - (instancetype)initWithFrame:(CGRect)frame 21 | { 22 | self = [super initWithFrame:frame]; 23 | if (self) { 24 | [self addSubview:self.pageView]; 25 | self.iFrame = frame; 26 | self.pageView.frame = CGRectMake(offSet_x, 0, frame.size.width - 2 * offSet_x, frame.size.height);//self.contentView.bounds; 27 | 28 | // [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_pageView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_pageView)]]; 29 | // [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_pageView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_pageView)]]; 30 | // self.contentView.backgroundColor = [UIColor yellowColor]; 31 | 32 | // [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(RollingModeUpdateMargin) name:@"RollingModeUpdateMargin" object:nil]; 33 | } 34 | return self; 35 | } 36 | 37 | 38 | // 39 | //- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 40 | //// if (_interactionLocked) 41 | //// return; 42 | //// 43 | //// UITouch *touch = [event.allTouches anyObject]; 44 | //// _touchBeganPoint = [touch locationInView:self]; 45 | //// 46 | //// if ([self touchedPrevPage] && [self hasPrevPage]) { 47 | //// [CATransaction begin]; 48 | //// [CATransaction setValue:(id)kCFBooleanTrue 49 | //// forKey:kCATransactionDisableActions]; 50 | //// 51 | //// self.currentPageIndex = self.currentPageIndex - _numberOfVisiblePages; 52 | //// self.leafEdge = 0.0; 53 | //// [CATransaction commit]; 54 | //// _touchIsActive = YES; 55 | //// } 56 | //// else if ([self touchedNextPage] && [self hasNextPage]) 57 | //// _touchIsActive = YES; 58 | //// 59 | //// else 60 | //// _touchIsActive = NO; 61 | //} 62 | //// 63 | //- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 64 | //// if (!_touchIsActive) 65 | //// return; 66 | //// UITouch *touch = [event.allTouches anyObject]; 67 | //// CGPoint touchPoint = [touch locationInView:self]; 68 | //// 69 | //// [CATransaction begin]; 70 | //// [CATransaction setValue:[NSNumber numberWithFloat:0.07] 71 | //// forKey:kCATransactionAnimationDuration]; 72 | //// self.leafEdge = touchPoint.x / self.bounds.size.width; 73 | //// [CATransaction commit]; 74 | //} 75 | // 76 | // 77 | //- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 78 | //// if (!_touchIsActive) 79 | //// return; 80 | //// _touchIsActive = NO; 81 | //// 82 | //// UITouch *touch = [event.allTouches anyObject]; 83 | //// CGPoint touchPoint = [touch locationInView:self]; 84 | //// BOOL dragged = distance(touchPoint, _touchBeganPoint) > [self dragThreshold]; 85 | //// 86 | //// [CATransaction begin]; 87 | //// float duration; 88 | //// if ((dragged && self.leafEdge < 0.5) || (!dragged && [self touchedNextPage])) { 89 | //// [self willTurnToPageAtIndex:_currentPageIndex + _numberOfVisiblePages]; 90 | //// self.leafEdge = 0; 91 | //// duration = _leafEdge; 92 | //// _interactionLocked = YES; 93 | //// if (_currentPageIndex+2 < _numberOfPages && _backgroundRendering) 94 | //// [_pageCache precacheImageForPageIndex:_currentPageIndex+2]; 95 | //// [self performSelector:@selector(didTurnPageForward) 96 | //// withObject:nil 97 | //// afterDelay:duration + 0.25]; 98 | //// } 99 | //// else { 100 | //// [self willTurnToPageAtIndex:_currentPageIndex]; 101 | //// self.leafEdge = 1.0; 102 | //// duration = 1 - _leafEdge; 103 | //// _interactionLocked = YES; 104 | //// [self performSelector:@selector(didTurnPageBackward) 105 | //// withObject:nil 106 | //// afterDelay:duration + 0.25]; 107 | //// } 108 | //// [CATransaction setValue:[NSNumber numberWithFloat:duration] 109 | //// forKey:kCATransactionAnimationDuration]; 110 | //// [CATransaction commit]; 111 | //} 112 | 113 | 114 | 115 | 116 | 117 | - (void)RollingModeUpdateMargin 118 | { 119 | self.pageView.frame = CGRectMake(offSet_x, 0, self.iFrame.size.width - 2 * offSet_x, self.iFrame.size.height); 120 | } 121 | #pragma mark - lazy loading 122 | 123 | - (ZGiReaderPageView *)pageView 124 | { 125 | if (!_pageView) { 126 | _pageView = [[ZGiReaderPageView alloc] init]; 127 | _pageView.translatesAutoresizingMaskIntoConstraints = NO; 128 | _pageView.backgroundColor = ZGiReader_backgroundColor; 129 | } 130 | return _pageView; 131 | } 132 | 133 | - (void)dealloc 134 | { 135 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 136 | } 137 | 138 | @end 139 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/ZGiReaderPageCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderPageCell.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/1. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ZGiReaderPageView.h" 11 | 12 | static NSString *PageCellIdentifier = @"PageCellIdentifier"; 13 | @interface ZGiReaderPageCell : UICollectionViewCell 14 | @property (nonatomic, strong) ZGiReaderPageView *pageView; 15 | @end 16 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/ZGiReaderPageCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderPageCell.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/1. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGiReaderPageCell.h" 10 | #import "ZGiReaderHeader.h" 11 | @interface ZGiReaderPageCell() 12 | 13 | @property (nonatomic, assign) CGRect iFrame; 14 | 15 | @end 16 | 17 | @implementation ZGiReaderPageCell 18 | - (instancetype)initWithFrame:(CGRect)frame 19 | { 20 | self = [super initWithFrame:frame]; 21 | if (self) { 22 | [self.contentView addSubview:self.pageView]; 23 | self.iFrame = frame; 24 | 25 | 26 | 27 | self.pageView.frame = ZGiReader_pageView_Frame;//ZGiReader_pageView_Size; 28 | 29 | // [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_pageView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_pageView)]]; 30 | // [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_pageView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_pageView)]]; 31 | // self.contentView.backgroundColor = [UIColor yellowColor]; 32 | 33 | // [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(RollingModeUpdateMargin) name:@"RollingModeUpdateMargin" object:nil]; 34 | } 35 | 36 | return self; 37 | } 38 | 39 | - (void)RollingModeUpdateMargin 40 | { 41 | self.pageView.frame = CGRectMake(offSet_x, 0, self.iFrame.size.width - 2 * offSet_x, self.iFrame.size.height); 42 | } 43 | #pragma mark - lazy loading 44 | 45 | - (ZGiReaderPageView *)pageView 46 | { 47 | if (!_pageView) { 48 | _pageView = [[ZGiReaderPageView alloc] init]; 49 | _pageView.translatesAutoresizingMaskIntoConstraints = NO; 50 | _pageView.backgroundColor = zgRc4randomColor;//ZGiReader_backgroundColor; 51 | } 52 | return _pageView; 53 | } 54 | 55 | - (void)dealloc 56 | { 57 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 58 | } 59 | @end 60 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/ZGiReaderPageView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderPageView.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/1. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZGiReaderPageView : UIView 12 | @property (nonatomic, copy) NSAttributedString *attributedText; 13 | 14 | - (void)setText:(NSAttributedString *)attributedText; 15 | @end 16 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/ZGiReaderPageView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderPageView.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/1. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGiReaderPageView.h" 10 | #import 11 | 12 | @implementation ZGiReaderPageView 13 | - (void)setText:(NSAttributedString *)attributedText 14 | { 15 | 16 | 17 | self.attributedText = attributedText; 18 | [self setNeedsDisplay]; 19 | } 20 | 21 | - (void)drawRect:(CGRect)rect { 22 | // Drawing code 23 | CGContextRef context = UIGraphicsGetCurrentContext(); 24 | // Flip the coordinate system 25 | CGContextSetTextMatrix(context, CGAffineTransformIdentity); 26 | 27 | CGAffineTransform transform = CGAffineTransformMake(1,0,0,-1,0,self.bounds.size.height); 28 | CGContextConcatCTM(context, transform); 29 | 30 | // CGContextTranslateCTM(context, 0, self.bounds.size.height); 31 | // CGContextScaleCTM(context, 1.0, -1.0); 32 | 33 | CTFramesetterRef childFramesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)self.attributedText); 34 | UIBezierPath * bezierPath = [UIBezierPath bezierPathWithRect:rect]; 35 | CTFrameRef frame = CTFramesetterCreateFrame(childFramesetter, CFRangeMake(0, 0), bezierPath.CGPath, NULL); 36 | CTFrameDraw(frame, context); 37 | // CFRelease(frame); 38 | // CFRelease(childFramesetter); 39 | // self.backgroundColor = [UIColor redColor]; 40 | } 41 | @end 42 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/ZGiReaderTopAndBottomBarController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderTopAndBottomBarController.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/3. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGBaseViewController.h" 10 | 11 | @interface ZGiReaderTopAndBottomBarController : ZGBaseViewController 12 | - (void)hiddenOrShowZGiReaderTopAndBottomBar; 13 | @end 14 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/ZGiReaderTopAndBottomBarController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderTopAndBottomBarController.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/3. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGiReaderTopAndBottomBarController.h" 10 | #import "ZGiReaderHeader.h" 11 | 12 | 13 | @interface ZGiReaderTopAndBottomBarController () 14 | @property(nonatomic,strong)UIView * topView; 15 | @property(nonatomic,strong)UIView * bottomView; 16 | @property(nonatomic,assign)BOOL isShow; 17 | 18 | @property(nonatomic,strong)UIButton * backButton;//返回按钮 19 | @end 20 | 21 | @implementation ZGiReaderTopAndBottomBarController 22 | 23 | - (void)viewDidLoad { 24 | [super viewDidLoad]; 25 | 26 | [self setupUI]; 27 | 28 | } 29 | 30 | 31 | - (void)hiddenOrShowZGiReaderTopAndBottomBar 32 | { 33 | 34 | [UIView animateWithDuration:ZGiReader_afterDelay animations:^{ 35 | if (self.isShow) { 36 | 37 | self.topView.frame = CGRectMake(0, -NavigationBar_Height, K_SCREEN_WIDTH, NavigationBar_Height); 38 | self.bottomView.frame = CGRectMake(0, K_SCREEN_HEIGHT, K_SCREEN_WIDTH, ZGiReaderTopAndBottomBar_BottomViewHeight); 39 | }else{ 40 | self.topView.frame = CGRectMake(0, 0, K_SCREEN_WIDTH, NavigationBar_Height); 41 | self.bottomView.frame = CGRectMake(0, K_SCREEN_HEIGHT - ZGiReaderTopAndBottomBar_BottomViewHeight, K_SCREEN_WIDTH, ZGiReaderTopAndBottomBar_BottomViewHeight); 42 | } 43 | 44 | self.isShow = !self.isShow; 45 | }]; 46 | 47 | } 48 | 49 | 50 | - (void)setupUI 51 | { 52 | [self.view addSubview:self.topView]; 53 | [self.view addSubview:self.bottomView]; 54 | 55 | 56 | 57 | } 58 | 59 | #pragma mark - 按钮点击事件 60 | - (void)buttonClickWithSender:(UIButton *)sender 61 | { 62 | 63 | NSLog(@">>>>>>>>>>>>%ld",(long)sender.tag); 64 | 65 | 66 | } 67 | 68 | 69 | 70 | #pragma mark - 懒加载 71 | - (UIButton *)backButton 72 | { 73 | if (!_backButton) { 74 | 75 | #define button_Width 40 76 | _backButton = [[UIButton alloc] initWithFrame:CGRectMake(ZGiReader_edge_10, NavigationBar_Height - ZGiReader_edge_10 - button_Width, button_Width, button_Width)]; 77 | _backButton.tag = 100; 78 | 79 | _backButton.backgroundColor = zgRc4randomColor; 80 | } 81 | return _backButton; 82 | } 83 | 84 | 85 | - (UIView *)topView 86 | { 87 | if (!_topView) { 88 | _topView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, K_SCREEN_WIDTH, NavigationBar_Height)]; 89 | _topView.backgroundColor = ZGiReader_ThemeFontColor; 90 | // _topView.hidden = YES; 91 | self.isShow = YES; 92 | [_topView addSubview: self.backButton]; 93 | [self.backButton addTarget:self action:@selector(buttonClickWithSender:) forControlEvents:UIControlEventTouchUpInside]; 94 | } 95 | return _topView; 96 | } 97 | 98 | - (UIView *)bottomView 99 | { 100 | if (!_bottomView) { 101 | _bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, K_SCREEN_HEIGHT - ZGiReaderTopAndBottomBar_BottomViewHeight, K_SCREEN_WIDTH, ZGiReaderTopAndBottomBar_BottomViewHeight)]; 102 | _bottomView.backgroundColor = ZGiReader_ThemeFontColor; 103 | // _bottomView.hidden = YES; 104 | } 105 | return _bottomView; 106 | } 107 | 108 | 109 | 110 | 111 | 112 | - (void)didReceiveMemoryWarning { 113 | [super didReceiveMemoryWarning]; 114 | // Dispose of any resources that can be recreated. 115 | } 116 | 117 | /* 118 | #pragma mark - Navigation 119 | 120 | // In a storyboard-based application, you will often want to do a little preparation before navigation 121 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 122 | // Get the new view controller using [segue destinationViewController]. 123 | // Pass the selected object to the new view controller. 124 | } 125 | */ 126 | 127 | @end 128 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/ZGiReaderViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderViewController.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/7/26. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGBaseViewController.h" 10 | #import "ZGiReaderGlobalModel.h" 11 | 12 | @interface ZGiReaderViewController : ZGBaseViewController 13 | @property (strong, nonatomic) ZGiReaderGlobalModel *globalModel; 14 | @property (nonatomic, strong) NSDictionary *attributes; 15 | 16 | 17 | /** 18 | 当前章节要展示的内容 19 | 20 | @param text 当前章节内容 21 | */ 22 | - (void)loadText:(NSString *)text; 23 | @end 24 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReader/ZGiReaderViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderViewController.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/7/26. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGiReaderViewController.h" 10 | #import "ZGiReaderCollectionView.h" 11 | #import "ZGiReaderCollectionViewFlowLayout.h" 12 | #import "ZGiReaderPageCell.h" 13 | #import "NSString+ZGiReaderPaging.h" 14 | #import "ZGiReaderCurrentTempView.h" 15 | #import "ZGiReaderTopAndBottomBarController.h" 16 | 17 | #define NetworkExceptionPromptString @"获取章节失败,请尝试重新加载"//网络异常提示字符串 18 | static NSString * cell_id = @"cellid"; 19 | @interface ZGiReaderViewController () 20 | @property(nonatomic,strong)ZGiReaderCollectionView * readerCollectionView; 21 | @property (strong, nonatomic) ZGiReaderCollectionViewFlowLayout *flowLayout; 22 | @property (nonatomic, strong) NSMutableArray *rangeArray; 23 | @property (nonatomic, strong) NSString *chapterTextString; 24 | @property (nonatomic, strong) ZGiReaderCurrentTempView * iReaderCurrentTempView; 25 | 26 | @property (nonatomic, strong) ZGiReaderTopAndBottomBarController * iReaderTopAndBottomBarController; 27 | 28 | @property(nonatomic, assign)CGPoint touchBeganPoint; 29 | @end 30 | 31 | @implementation ZGiReaderViewController 32 | 33 | - (void)viewDidLoad { 34 | [super viewDidLoad]; 35 | 36 | 37 | [self setupUI]; 38 | 39 | 40 | } 41 | 42 | - (void)setupUI 43 | { 44 | 45 | [self.view addSubview:self.readerCollectionView]; 46 | // [self.view addSubview:self.iReaderCurrentTempView]; 47 | 48 | UITapGestureRecognizer * tapGesRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(callToolBar:)]; 49 | //tapGesRec.delegate = self; 50 | [self.readerCollectionView addGestureRecognizer:tapGesRec]; 51 | // [self.view addSubview:self.iReaderTopAndBottomBar]; 52 | // [self addChildViewController:self.iReaderTopAndBottomBarController]; 53 | [self.view addSubview:self.iReaderTopAndBottomBarController.view]; 54 | } 55 | 56 | #pragma mark - 处理手势冲突 57 | 58 | //- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { 59 | // if ([touch.view class] == [ZGiReaderPageView class]) { 60 | // return YES; 61 | // }else { 62 | // return NO; 63 | // } 64 | //} 65 | 66 | 67 | 68 | 69 | - (void)loadText:(NSString *)text 70 | { 71 | //去除文章开头和结尾的空格和换行,防止出现空白页 72 | text = [text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 73 | if ([text rangeOfString:@"(null)"].location != NSNotFound) { 74 | text = [text stringByReplacingOccurrencesOfString:@"(null)" withString:NetworkExceptionPromptString]; 75 | } 76 | 77 | self.chapterTextString = text; 78 | NSMutableDictionary * attributes = [NSMutableDictionary dictionaryWithCapacity:5]; 79 | UIFont * font = [UIFont systemFontOfSize:20]; 80 | [attributes setValue:font forKey:NSFontAttributeName]; 81 | [attributes setValue:@(1.0) forKey:NSKernAttributeName]; 82 | [attributes setValue:@(1.0) forKey:NSKernAttributeName]; 83 | // UIColor *color = [E_CommonManager color];//颜色暂时去掉 84 | //[attributes setValue:color forKey:NSForegroundColorAttributeName]; 85 | NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 86 | paragraphStyle.lineSpacing = 10;//self.lineSpace;//行距 87 | // paragraphStyle.paragraphSpacing = 0.0;//段距 88 | paragraphStyle.alignment = NSTextAlignmentJustified; 89 | [attributes setValue:paragraphStyle forKey:NSParagraphStyleAttributeName]; 90 | self.attributes = [attributes copy]; 91 | self.rangeArray = [[text paginationWithAttributes:self.attributes constrainedToSize:CGSizeMake(K_SCREEN_WIDTH - 2*offSet_x, K_SCREEN_HEIGHT - label_Height - offSet_y)] mutableCopy]; 92 | // if (completion) { 93 | // completion(); 94 | // } 95 | 96 | 97 | // [self.globalModel loadText:text completion:^{ 98 | //// self.collectionViewModel.text = self.globalModel.text; 99 | //// self.collectionViewModel.attributes = self.globalModel.attributes; 100 | //// self.collectionViewModel.dataArray = self.globalModel.rangeArray; 101 | //// self.collectionViewModel.bgColor = self.globalModel.bgColor; 102 | //// // self.collectionViewModel.fontSize = self.globalModel.fontSize; 103 | //// self.view.backgroundColor = self.globalModel.bgColor; 104 | //// _chapterEndView.backgroundColor = self.view.backgroundColor;//[UIColor redColor]; 105 | //// 106 | //// _collectionView.backgroundColor = self.view.backgroundColor; 107 | //// [self.collectionView reloadData]; 108 | //// 109 | //// self.modelController.text = self.globalModel.text; 110 | //// self.modelController.attributes = self.globalModel.attributes; 111 | //// self.modelController.pageData = self.globalModel.rangeArray; 112 | // }]; 113 | 114 | // if (Current_ChapterIndex < 0) { 115 | // [self.novelTitleLabel setText:@""]; 116 | // }else{ 117 | // [self.novelTitleLabel setText:[NSString stringWithFormat:@"%@",[E_ReaderDataSource shareInstance].name]]; 118 | // } 119 | // 120 | // 121 | // [self recvBcast]; 122 | // //手机电量 123 | // [UIDevice currentDevice].batteryMonitoringEnabled = YES; 124 | // double deviceLevel = [UIDevice currentDevice].batteryLevel; 125 | // NSString *device = [NSString stringWithFormat:@"%.0f",deviceLevel*10]; 126 | // 127 | // NSString *bat = [NSString stringWithFormat:@"battery_%@",device]; 128 | // if (Current_ChapterIndex < 0) { 129 | // [self.batteryImage setImage:[UIImage imageNamed:@""]]; 130 | // }else{ 131 | // [self.batteryImage setImage:[UIImage imageNamed:bat]]; 132 | // } 133 | // 134 | // @weakify(self); 135 | // [self.readerTool startMonitorTimeWithBlock:^(NSDate *currentDate) { 136 | // @strongify(self); 137 | // NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 138 | // [dateFormatter setDateFormat:@"HH:mm"]; 139 | // NSString *datestr = [dateFormatter stringFromDate:currentDate]; 140 | // if (Current_ChapterIndex < 0) { 141 | // self.timeLabel.text = @""; 142 | // }else{ 143 | // self.timeLabel.text = datestr; 144 | // } 145 | // 146 | // 147 | // }]; 148 | // 149 | // //时间label 150 | // _timeLabel.textColor = kTextColor; 151 | // //进度label 152 | // _progressLabel.textColor = kTextColor; 153 | // //小说标题label 154 | // _novelTitleLabel.textColor = kTextColor; 155 | // //章节标题label 156 | // _chapterTitleLabel.textColor = kTextColor; 157 | 158 | } 159 | 160 | #pragma mark - 数据源 161 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 162 | { 163 | return self.rangeArray.count; 164 | } 165 | 166 | // The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath: 167 | - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 168 | { 169 | ZGiReaderPageCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:cell_id forIndexPath:indexPath]; 170 | 171 | 172 | NSString *subText = [self.chapterTextString substringWithRange:NSRangeFromString(self.rangeArray[indexPath.row])]; 173 | [cell.pageView setText:[[NSAttributedString alloc] initWithString:subText attributes:self.attributes]]; 174 | 175 | 176 | 177 | [self.iReaderCurrentTempView.pageView setText:[[NSAttributedString alloc] initWithString:subText attributes:self.attributes]]; 178 | 179 | cell.contentView.backgroundColor = ZGiReader_backgroundColor; 180 | return cell; 181 | } 182 | 183 | 184 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView 185 | { 186 | return 1; 187 | } 188 | 189 | 190 | #pragma mark - 手势 191 | #pragma mark - 自定义手势 192 | - (void)callToolBar:(UITapGestureRecognizer *)tap{ 193 | CGPoint startP = [tap locationInView:self.view]; 194 | 195 | 196 | [self showOrHiddenIReaderTopAndBottomBarControllerViewWithPoint:startP]; 197 | 198 | NSLog(@"开始(%f,%f)",startP.x,startP.y); 199 | } 200 | 201 | 202 | /** 203 | 展示或隐藏设置栏 204 | @param point 手势坐标 205 | */ 206 | - (void)showOrHiddenIReaderTopAndBottomBarControllerViewWithPoint:(CGPoint)point 207 | { 208 | if (point.x < K_SCREEN_WIDTH*2/3 && point.x > K_SCREEN_WIDTH/3 &&point.y < K_SCREEN_HEIGHT*2/3 && point.y > K_SCREEN_HEIGHT/3) { 209 | 210 | [self.iReaderTopAndBottomBarController hiddenOrShowZGiReaderTopAndBottomBar]; 211 | if (self.iReaderTopAndBottomBarController.view.superview == self.view) { 212 | [self performSelector:@selector(iReaderTopAndBottomBarControllerViewRemoveFromSuperView) withObject:self afterDelay:ZGiReader_afterDelay]; 213 | }else{ 214 | [self.view addSubview:self.iReaderTopAndBottomBarController.view]; 215 | } 216 | } 217 | } 218 | 219 | - (void)iReaderTopAndBottomBarControllerViewRemoveFromSuperView 220 | { 221 | [self.iReaderTopAndBottomBarController.view removeFromSuperview]; 222 | } 223 | 224 | // 根据touches集合获取对应的触摸点 225 | - (CGPoint)pointWithTouches:(NSSet *)touches 226 | { 227 | UITouch *touch = [touches anyObject]; 228 | 229 | return [touch locationInView:self.view]; 230 | } 231 | 232 | 233 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 234 | { 235 | CGPoint startP = [self pointWithTouches:touches]; 236 | NSLog(@"开始(%f,%f)",startP.x,startP.y); 237 | 238 | // CGPoint startP = [tap locationInView:self.view]; 239 | 240 | [self showOrHiddenIReaderTopAndBottomBarControllerViewWithPoint:startP]; 241 | 242 | if ([event allTouches].count == 1) { 243 | 244 | 245 | } 246 | } 247 | 248 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 249 | { 250 | // 获取移动点 251 | CGPoint moveP = [self pointWithTouches:touches]; 252 | NSLog(@"正在画(%f,%f)",moveP.x,moveP.y); 253 | if ([event allTouches].count > 1){ 254 | 255 | }else if ([event allTouches].count == 1) { 256 | 257 | } 258 | 259 | 260 | } 261 | 262 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 263 | { 264 | NSLog(@"画完"); 265 | if ([event allTouches].count > 1){ 266 | // [self.superview touchesMoved:touches withEvent:event]; 267 | } 268 | } 269 | 270 | - (void) didTurnPageBackward { 271 | // _interactionLocked = NO; 272 | // [self didTurnToPageAtIndex:_currentPageIndex]; 273 | } 274 | 275 | - (void) didTurnPageForward { 276 | // _interactionLocked = NO; 277 | // self.currentPageIndex = self.currentPageIndex + _numberOfVisiblePages; 278 | // [self didTurnToPageAtIndex:_currentPageIndex]; 279 | } 280 | 281 | 282 | 283 | 284 | 285 | 286 | #pragma mark - 懒加载 287 | - (ZGiReaderTopAndBottomBarController *)iReaderTopAndBottomBarController 288 | { 289 | if (!_iReaderTopAndBottomBarController) { 290 | _iReaderTopAndBottomBarController = [[ZGiReaderTopAndBottomBarController alloc] init]; 291 | } 292 | return _iReaderTopAndBottomBarController; 293 | } 294 | 295 | 296 | 297 | 298 | - (ZGiReaderCurrentTempView *)iReaderCurrentTempView 299 | { 300 | if (!_iReaderCurrentTempView) { 301 | _iReaderCurrentTempView = [[ZGiReaderCurrentTempView alloc] initWithFrame:self.view.bounds]; 302 | //[self.view addSubview:_iReaderCurrentTempView]; 303 | // _iReaderCurrentTempView.hidden = YES; 304 | } 305 | _iReaderCurrentTempView.backgroundColor = ZGiReader_backgroundColor; 306 | return _iReaderCurrentTempView; 307 | } 308 | - (ZGiReaderCollectionViewFlowLayout *)flowLayout 309 | { 310 | if (!_flowLayout) { 311 | _flowLayout = [[ZGiReaderCollectionViewFlowLayout alloc] init]; 312 | } 313 | return _flowLayout; 314 | } 315 | - (UICollectionView *)readerCollectionView 316 | { 317 | if (!_readerCollectionView) { 318 | ZGiReaderCollectionView * readerCollectionView = [[ZGiReaderCollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:self.flowLayout]; 319 | _readerCollectionView = readerCollectionView; 320 | _readerCollectionView.backgroundColor = ZGiReader_backgroundColor;//[UIColor redColor]; 321 | _readerCollectionView.dataSource = self; 322 | _readerCollectionView.delegate = self; 323 | [_readerCollectionView registerClass:[ZGiReaderPageCell class] forCellWithReuseIdentifier:cell_id]; 324 | _readerCollectionView.pagingEnabled = YES; 325 | } 326 | 327 | return _readerCollectionView; 328 | } 329 | 330 | 331 | - (void)didReceiveMemoryWarning { 332 | [super didReceiveMemoryWarning]; 333 | // Dispose of any resources that can be recreated. 334 | } 335 | /* 336 | #pragma mark - Navigation 337 | 338 | // In a storyboard-based application, you will often want to do a little preparation before navigation 339 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 340 | // Get the new view controller using [segue destinationViewController]. 341 | // Pass the selected object to the new view controller. 342 | } 343 | */ 344 | - (NSDictionary *)attributes 345 | { 346 | if (!_attributes) { 347 | NSMutableDictionary * attributes = [NSMutableDictionary dictionaryWithCapacity:5]; 348 | UIFont * font = [UIFont systemFontOfSize:15]; 349 | [attributes setValue:font forKey:NSFontAttributeName]; 350 | [attributes setValue:@(1.0) forKey:NSKernAttributeName]; 351 | [attributes setValue:@(1.0) forKey:NSKernAttributeName]; 352 | UIColor *color = ZGiReader_ContentFontColor;//[E_CommonManager color]; 353 | [attributes setValue:color forKey:NSForegroundColorAttributeName]; 354 | NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 355 | paragraphStyle.lineSpacing = 20;//self.lineSpace;//行距 356 | // paragraphStyle.paragraphSpacing = 0.0;//段距 357 | paragraphStyle.alignment = NSTextAlignmentJustified; 358 | [attributes setValue:paragraphStyle forKey:NSParagraphStyleAttributeName]; 359 | _attributes = [attributes copy]; 360 | } 361 | return _attributes; 362 | } 363 | 364 | @end 365 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReaderAppInfoManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderAppInfoManager.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/1. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZGiReaderAppInfoManager : NSObject 12 | ///判断是否是iphoneX 13 | + (BOOL)iPhoneMachineName; 14 | @end 15 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReaderAppInfoManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderAppInfoManager.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/1. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGiReaderAppInfoManager.h" 10 | #import 11 | #import "ZGiReaderHeader.h" 12 | @implementation ZGiReaderAppInfoManager 13 | 14 | + (BOOL)iPhoneMachineName 15 | { 16 | if (K_SCREEN_HEIGHT == 812) { 17 | return YES; 18 | }else{ 19 | return NO; 20 | } 21 | } 22 | @end 23 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReaderHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // Header.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/1. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #ifndef Header_h 10 | #define Header_h 11 | 12 | 13 | #import "JJPreventCrash.h" 14 | 15 | 16 | 17 | #define K_SCREEN_HEIGHT [[UIScreen mainScreen] bounds].size.height 18 | #define K_SCREEN_WIDTH [[UIScreen mainScreen] bounds].size.width 19 | #define NavigationBar_Height ([[UIApplication sharedApplication] statusBarFrame].size.height + 44)//导航栏加状态栏高度 20 | #define offSet_x 10//[E_CommonManager margin]//暂时写死 21 | #define offSet_y 30//([ZGiReaderAppInfoManager iPhoneMachineName] ? 54:30)//暂时写死 22 | #define label_Height 30 23 | #define ZGiReader_edge_10 10//边缘宽度 24 | 25 | #define ZGiReaderTopAndBottomBar_BottomViewHeight 60 26 | 27 | 28 | 29 | #define ZGiReader_pageView_Width (K_SCREEN_WIDTH - offSet_x * 2)//每一页的宽 30 | #define ZGiReader_pageView_Height ( K_SCREEN_HEIGHT - offSet_y - label_Height)//每一页的高 31 | #define ZGiReader_pageView_Size CGSizeMake(ZGiReader_pageView_Width, ZGiReader_pageView_Height)//每一页的大小 32 | #define ZGiReader_pageView_Frame CGRectMake(offSet_x, offSet_y,ZGiReader_pageView_Width,ZGiReader_pageView_Height) 33 | 34 | #define ZGiReader_backgroundColor [UIColor colorWithRed:240/255.0 green:240/255.0 blue:240/255.0 alpha:1] 35 | 36 | #define ZGiReader_ThemeFontColor [UIColor colorWithRed:30/255.0 green:123/255.0 blue:94/255.0 alpha:1.0f]//主体颜色 37 | #define ZGiReader_ContentFontColor [UIColor blackColor] 38 | 39 | #define zgRc4randomColor [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1]; 40 | 41 | 42 | #define ZGiReader_afterDelay 0.3 43 | 44 | 45 | #endif /* Header_h */ 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReaderReadUtilites.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderReadUtilites.h 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/2. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ZGiReaderChapterModel.h" 11 | 12 | @interface ZGiReaderReadUtilites : NSObject 13 | +(NSString *)encodeWithURL:(NSURL *)url; 14 | 15 | /** 16 | 过滤拆分内容,适用于从网上下载的全本小说,通过分成章节。快速展示 17 | 18 | @param text 要过滤拆分的内容 19 | @return 返回过滤好的每一个章节数组 20 | */ 21 | + (NSArray *)returnFilterSplitContentText:(NSString *)text; 22 | 23 | 24 | 25 | /** 26 | 过滤拆分内容,适用于从网上下载的全本小说,通过分成章节。快速展示 27 | 28 | @param url 本地路径 29 | @return 返回过滤好的每一个章节数组 30 | */ 31 | +(NSArray *)encodeReturnFilterSplitContentTextWithURL:(NSURL *)url; 32 | @end 33 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/ZGiReaderReadUtilites.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderReadUtilites.m 3 | // ZGiReader 4 | // 5 | // Created by 杨振国 on 2018/8/2. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import "ZGiReaderReadUtilites.h" 10 | #import "JJPreventCrash.h" 11 | 12 | 13 | @implementation ZGiReaderReadUtilites 14 | +(NSString *)encodeWithURL:(NSURL *)url 15 | { 16 | if (!url) { 17 | return @""; 18 | } 19 | NSString *content = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil]; 20 | if (!content) { 21 | content = [NSString stringWithContentsOfURL:url encoding:0x80000632 error:nil]; 22 | } 23 | if (!content) { 24 | content = [NSString stringWithContentsOfURL:url encoding:0x80000631 error:nil]; 25 | } 26 | if (!content) { 27 | return @""; 28 | } 29 | return jjString(content); 30 | 31 | } 32 | 33 | + (NSArray *)returnFilterSplitContentText:(NSString *)text 34 | { 35 | __block NSMutableArray * arrayM = [NSMutableArray array]; 36 | NSString *parten = @"[第][0-9一二三四五六七八九十百千万]{1,5}[章回节]{1,2}[^\n]{1,}";//@"第[0-9一二三四五六七八九十百千]*[章回].*"; 37 | NSError* error = NULL; 38 | NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:parten options:NSRegularExpressionCaseInsensitive error:&error]; 39 | 40 | NSArray* match = [reg matchesInString:text options:NSMatchingReportCompletion range:NSMakeRange(0, [text length])]; 41 | 42 | if (match.count != 0) 43 | { 44 | __block NSRange lastRange = NSMakeRange(0, 0); 45 | [match enumerateObjectsUsingBlock:^(NSTextCheckingResult * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 46 | NSRange range = [obj range]; 47 | NSInteger local = range.location; 48 | if (idx == 0) { 49 | 50 | NSString * title = @"福利"; 51 | NSUInteger len = local; 52 | NSString * cont = [text substringWithRange:NSMakeRange(0, len)]; 53 | NSLog(@"章节名1--%@",title); 54 | NSLog(@"内容1--%@",cont); 55 | 56 | 57 | ZGiReaderChapterModel * model = [[ZGiReaderChapterModel alloc] init]; 58 | model.title = jjString(title); 59 | model.chapterContent = jjString(cont); 60 | arrayM = [JJPreventCrash jjAddObjectWithArrayM:arrayM addObject:model]; 61 | 62 | } 63 | if (idx > 0 ) { 64 | 65 | NSLog(@"章节名2--%@",[text substringWithRange:lastRange]); 66 | NSUInteger len = local-lastRange.location; 67 | NSLog(@"内容2--%@",[text substringWithRange:NSMakeRange(lastRange.location, len)]); 68 | 69 | 70 | // NSDictionary * dict = @{@"title":,@"content":jjString([text substringWithRange:NSMakeRange(lastRange.location, len)])}; 71 | 72 | ZGiReaderChapterModel * model = [[ZGiReaderChapterModel alloc] init]; 73 | model.title = jjString([text substringWithRange:lastRange]); 74 | model.chapterContent = jjString([text substringWithRange:NSMakeRange(lastRange.location, len)]); 75 | arrayM = [JJPreventCrash jjAddObjectWithArrayM:arrayM addObject:model]; 76 | } 77 | if (idx == match.count-1) { 78 | 79 | NSLog(@"章节名3--%@",[text substringWithRange:range]); 80 | 81 | NSLog(@"内容3--%@",[text substringWithRange:NSMakeRange(local, text.length-local)]); 82 | 83 | 84 | 85 | ZGiReaderChapterModel * model = [[ZGiReaderChapterModel alloc] init]; 86 | model.title = jjString([text substringWithRange:range]); 87 | model.chapterContent = jjString([text substringWithRange:NSMakeRange(local, text.length-local)]); 88 | arrayM = [JJPreventCrash jjAddObjectWithArrayM:arrayM addObject:model]; 89 | } 90 | lastRange = range; 91 | }]; 92 | } 93 | else{ 94 | NSLog(@"内容4--%@",text); 95 | } 96 | 97 | 98 | 99 | return arrayM; 100 | } 101 | 102 | 103 | 104 | +(NSArray *)encodeReturnFilterSplitContentTextWithURL:(NSURL *)url 105 | { 106 | 107 | return [self returnFilterSplitContentText:[self encodeWithURL:url]]; 108 | 109 | } 110 | 111 | @end 112 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderController/test.txt: -------------------------------------------------------------------------------- 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 |   大量的蓝花,晶莹点点,犹若梦幻,有些醉人,遍开在沙漠中,非常不真实。 65 | 66 |   这种植物一尺多高,通体如蓝珊瑚般透亮,花瓣一条条,妖艳而迷人,宛若盛放在另一片国度,带着魔性,吸引人的心神。 67 | 68 |   楚风退后一步,然而,身后也已满是这种植物,蓝光流动,一眼望不到边。 69 | 70 |   他很吃惊,仔细的看着,努力辨认,这像极了彼岸花,一条条花瓣展开,又向后弯曲,极其美丽。 71 | 72 |   不过,彼岸花红的鲜艳,而它却是蓝色的,从未听闻有蓝色彼岸花。 73 | 74 |   彼岸花真实存在,带着浓烈的宗教色彩,关于它有太多的传说,但楚风不信这些,只为眼前的景象而惊。 75 | 76 |   沙漠干燥、缺水,只有极其稀少的耐旱植物偶尔可见,零星散落着。而彼岸花喜欢阴森、潮湿的环境,无论如何也不该在这里出现,还如此的妖艳。 77 | 78 |   这里遍地都是,一眼望不到尽头。 79 | 80 |   大漠浩瀚,薄雾染蓝了落日,浸透了天边,而整片空旷无垠的沙漠都生出蓝色的彼岸花,说不出的奇异、神秘! 81 | 82 |   一缕淡淡的芬芳飘漾,让人沉迷。 83 | 84 |   楚风用力摇头,小心的迈步,避开这些花,他发现只有一个地带没有这种植物,那就是———黄河古道。 85 | 86 |   在岁月中多次变迁,几经改道,它贯穿这片大漠,如今已近干涸,蓝色彼岸花开遍两岸,拥簇着它。 87 | 88 |   花开两岸,彼此遥见。 89 | 90 |   终于,太阳沉下去了,而也正是在此时,这些植物盛放,花开到极致,化作蓝色的海洋,流光溢彩。 91 | 92 |   虽然暮色降临,但这里蓝色光泽缭绕,极致炫目,艳丽的出奇。 93 | 94 |   楚风站在黄河古道上,心中无法宁静,但是他却不作停留,沿河道快速前进。 95 | 96 |   天色渐暗,最后的落日余晖也已不见了。 97 | 98 |   蓝色的大漠光彩点点,而后突然间,砰然一声,所有蓝色彼岸花怒放后,竟然在一瞬间同时凋零。 99 | 100 |   妖艳的花瓣枯萎,接着整株的植物开始干枯,它们失去色彩,耗尽生机,迅速发黄,而后碎裂,像是在一瞬间失去了数十年。 101 | 102 |   “砰!” 103 | 104 |   最后的刹那,遍地干枯的蓝色彼岸花寸寸断裂,化成了粉末。 105 | 106 |   这诡异的景象,很难解释。 107 | 108 |   它们如同烟花般,短暂的绚烂,美丽到极致,而后便凋零,成为灰烬。 109 | 110 |   枯黄的粉末落在沙地间,在暮色中很难辨出,而此时蓝雾也早已消失,大漠恢复了原样,像是什么都不曾发生过,再次宁静。 111 | 112 |   楚风没有驻足,大步前行,在暮色中,他翻过许多座沙丘,终于见到了地平线上的山影,要离开大漠了。 113 | 114 |   天色渐黑,他终于走出来了,清晰的看到了山地,也隐约间看到了山脚下牧民的帐篷。 115 | 116 |   再回头时,身后大漠浩瀚,很寂静,跟平日没什么两样。 117 | 118 |   山地前方,灯火摇曳,离山脚下还较远时就听到了一些嘈杂声,那里不平静,像是有什么事情正在发生。 119 | 120 |   此外,还有牛羊等牲畜惶恐的叫声,以及藏獒沉闷的低吼声。 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 |   仿佛有一轮炫目的蓝色大日被浓雾包裹着,在那里沉浮,虽然隔着很远,但不时射出光芒,如同闪电般。 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 |   清晨,红彤彤的太阳跃出地平线,灿灿的朝霞滑过山丘,落在帐篷前,草地上,尽显朝气蓬勃之象。 189 | 190 |   楚风告别这个部族,再次上路。 191 | 192 |   他一路向西,进入高原。 193 | 194 |   沿途,他了解到,那神秘的蓝雾波及范围极广,最起码所走过的区域都曾出现。 195 | 196 |   “不会又是一起神秘变故吧?”他自语。 197 | 198 |   历史上那几次,曾闹出很大的风波,到现在还没有确切答案呢。 199 | 200 |   藏区的天空格外的蓝,云层洁白,离地面很低,仿佛稍微一伸手就能触碰到,戈壁、山地、草场都很宁静,这里像是一片与世无争的净土。 201 | 202 |   一路上,楚风听到很多传闻。 203 | 204 |   有牧民说,圣山上的活佛苏醒了,所以才有蓝光流淌,大雾弥漫,遮拢四方。 205 | 206 |   还有人说是金刚菩提神树在生长,要开花结果了。 207 | 208 |   “龙獒要出世了!”也有人这样说。 209 | 210 |   在当地人看来,真正的獒生在野外,可与狮虎为敌,而被人所豢养的不属于真獒。更有一种传说,圣山中有龙獒,数百年能出现一头,力大无穷,可以降魔。 211 | 212 |   数日后,楚风临近圣山区域。 213 | 214 |   他已经了解到,沿途各地都曾出现淡淡的蓝雾,多半跟历史上的那几次一样,又是一次重大的异变。 215 | 216 |   同时,这也意味着,又像前几次那样,一般的人始终都不会了解到内因! 217 | 218 |   甚至,大部分人都不知道会引发怎样的后果。 219 | 220 |   说也奇怪,本已是深秋季节,藏区的天气应该很冷才对,可近几日来,楚风一路西行,却渐渐感觉到了一股暖意。 221 | 222 |   前些天,黄叶凋零,败叶满地,而现在却不同了。 223 | 224 |   树上残存的叶子仿佛又恢复了生气,不再枯黄,不再飘落。 225 | 226 |   尤其是临近昆仑,沿途上,无论是野草,还是荆棘树木等,在暖和的天气中绿的发亮,生机勃勃。 227 | 228 |   已是深秋,却缺少那种萧瑟。 229 | 230 |   “天气变暖了,难道是异变导致的?”楚风猜测。 231 | 232 |   终于,昆仑山在望。 233 | 234 |   隔着很远,就感觉到一种压迫感。 235 | 236 |   巍峨高大的山脉,气势磅礴,连绵而恢宏,宛若天地的脊梁,横亘在那里。 237 | 238 |   它壮阔而雄浑,无以伦比,古之大山莫出其右者。 239 | 240 |   这片山脉承载着无穷的传说,自古至今都笼罩着极其浓重的神话色彩。 241 | 242 |   原本进入藏区后楚风就要踏上回程了,然而一路上不断听闻到昆仑山异动,曾蓝光烁烁,他想临近看一看。 243 | 244 |   “就是这里。” 245 | 246 |   楚风到了目的地,站在山脚下,巍巍巨山犹若神之巨城,恢宏而庞大,坐落在西部大地上,苍莽与雄浑之气扑面而来。 247 | 248 |   这仅是昆仑山脉的一小段而已,前些天的那个傍晚这块区域曾经蓝光炽盛,附近的人都看到了,不过这些日子罕有人敢真正走近。 249 | 250 |   楚风进山,逐渐攀登。 251 | 252 |   山势渐高,有些陡峭,巨石横陈,路越发不好走,而一路上草木葱郁,在这深秋季节明显不正常。 253 | 254 |   “前些天真的发生过地震?”楚风观察着。 255 | 256 |   山体上有龟裂的痕迹,地表有不少粗大的裂缝,还有明显是从山势较高处滚下的巨石,一些崖壁更是断落。 257 | 258 |   就是这座巨山,曾经发生异常景象。 259 | 260 |   “这是什么?” 261 | 262 |   楚风看到一块巨石,上面有字,刻痕很深,被土石埋着大部分。 263 | 264 |   地震后,山体小部分断落、滑坡,这巨石是从地下深处显露出来的。 265 | 266 |   大石上有一层绿意,像是干枯的苔藓。 267 | 268 |   “西⋯⋯王!” 269 | 270 |   楚风用手抚摸石上的刻字,认出这两个字,这是金文,一种年代非常久远的文字,古时多刻于钟鼎之上。 271 | 272 |   一般人很难辨识。 273 | 274 |   一刹那,浮思不断,楚风出神,怎么会是这两个字? 275 | 276 |   在这里见到西王二字,怎能不让人作出联想,在那上古时代还真有西王母不成? 277 | 278 |   “或许只是古人来此凭吊所留下的碑文吧。”楚风摇头,自我解释。 279 | 280 |   “有些不对!” 281 | 282 |   忽然,他怔住了,在抚摸那刻字痕迹时,他发现所谓的“干枯苔藓”不正常。 283 | 284 |   “绿铜锈!”这个发现让他心中一震。 285 | 286 |   这块碑曾被尘封,埋在山体中,仔细想来也不会有什么苔藓才对,它所历经的时代十分漫长,直到剧烈地震后才重见天光。 287 | 288 |   它竟为青铜材质! 289 | 290 |   可是,这么大的一块古铜属实罕见。 291 | 292 |   “殷墟出土的司母戊鼎也不足两千斤,便号称最大青铜古器,而这块铜碑⋯⋯” 293 | 294 |   楚风推开一些土石,保守估计,这块青铜最起码也得重达五六千斤,实在骇人听闻,在古代这绝对是一块稀世重器。 295 | 296 |   它绿锈斑斑,一看就是埋了漫长岁月的古物。 297 | 298 |   如果是石碑,楚风还认为是前人来此凭吊所留,现在这么大一块铜碑,他不确定了。 299 | 300 |   在那遥远的古代,仅为了怀古,谁能消耗的起? 301 | 302 |   好久不见^_^新书圣墟开始上传,会员点击、推荐票、收藏,请大家伸伸手吧。 303 | 304 |   书评区非常火热,也有很多人飘红,谢谢大家的热情,谢谢所有书友。 305 | 306 |    307 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderTests/ZGiReaderTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderTests.m 3 | // ZGiReaderTests 4 | // 5 | // Created by 杨振国 on 2018/7/26. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZGiReaderTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ZGiReaderTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ZGiReader/ZGiReaderUITests/ZGiReaderUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZGiReaderUITests.m 3 | // ZGiReaderUITests 4 | // 5 | // Created by 杨振国 on 2018/7/26. 6 | // Copyright © 2018年 aikutv. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZGiReaderUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ZGiReaderUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /破解VIP视频软件.dmg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/123456github/ZGiReader/c92b0272e6476f8862eea490e2cdf34c857ebc39/破解VIP视频软件.dmg --------------------------------------------------------------------------------