├── .gitignore ├── README.md ├── WFReader.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── wufuhu.xcuserdatad │ └── xcschemes │ ├── WFReader.xcscheme │ └── xcschememanagement.plist ├── WFReader ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── EReader │ ├── Mode │ │ ├── E_CommonManager.h │ │ ├── E_CommonManager.m │ │ ├── E_ContantFile.h │ │ ├── E_EveryChapter.h │ │ ├── E_EveryChapter.m │ │ ├── E_Mark.h │ │ ├── E_Mark.m │ │ ├── E_Paging.h │ │ ├── E_Paging.mm │ │ ├── E_ReaderDataSource.h │ │ ├── E_ReaderDataSource.m │ │ ├── NSDate+NSDate_E_Date.h │ │ └── NSDate+NSDate_E_Date.m │ ├── View │ │ ├── E_CursorView.h │ │ ├── E_CursorView.m │ │ ├── E_DrawerView.h │ │ ├── E_DrawerView.m │ │ ├── E_HUDView.h │ │ ├── E_HUDView.m │ │ ├── E_ListView.h │ │ ├── E_ListView.m │ │ ├── E_MagnifiterView.h │ │ ├── E_MagnifiterView.m │ │ ├── E_MarkTableViewCell.h │ │ ├── E_MarkTableViewCell.m │ │ ├── E_ReaderView.h │ │ ├── E_ReaderView.m │ │ ├── E_SearchTableViewCell.h │ │ ├── E_SearchTableViewCell.m │ │ ├── E_SettingBottomBar.h │ │ ├── E_SettingBottomBar.m │ │ ├── E_SettingTopBar.h │ │ ├── E_SettingTopBar.m │ │ ├── ILSlider.h │ │ └── ILSlider.m │ ├── ViewController │ │ ├── E_CommentViewController.h │ │ ├── E_CommentViewController.m │ │ ├── E_ReaderViewController.h │ │ ├── E_ReaderViewController.m │ │ ├── E_ScrollViewController.h │ │ ├── E_ScrollViewController.m │ │ ├── E_SearchViewController.h │ │ ├── E_SearchViewController.m │ │ ├── E_WebViewControler.h │ │ └── E_WebViewControler.m │ └── resource │ │ ├── Chapter1.txt │ │ ├── Chapter2.txt │ │ ├── Chapter3.txt │ │ ├── Chapter4.txt │ │ ├── Chapter5.txt │ │ ├── Chapter6.txt │ │ ├── Chapter7.txt │ │ ├── friend@2x.png │ │ ├── magnifiter@2x.png │ │ ├── menuClose.png │ │ ├── r_drag-dot@2x.png │ │ ├── r_ribbonRed@2x.png │ │ ├── reader_bg1@2x.png │ │ ├── reader_bg2@2x.png │ │ ├── reader_bg3@2x.png │ │ ├── reader_bg4@2x.png │ │ ├── reader_bg5@2x.png │ │ ├── reader_bg_s@2x.png │ │ ├── reader_comments@2x.png │ │ ├── reader_cover@2x.png │ │ ├── reader_font_decrease@2x.png │ │ ├── reader_font_increase@2x.png │ │ ├── reader_more@2x.png │ │ ├── sina@2x.png │ │ └── weixin@2x.png ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── ThirdPart │ ├── CDSideBarController.h │ ├── CDSideBarController.m │ ├── MJRefresh │ │ ├── MJRefresh.bundle │ │ │ └── arrow@2x.png │ │ ├── MJRefresh.h │ │ ├── MJRefreshBaseView.h │ │ ├── MJRefreshBaseView.m │ │ ├── MJRefreshConst.h │ │ ├── MJRefreshConst.m │ │ ├── MJRefreshFooterView.h │ │ ├── MJRefreshFooterView.m │ │ ├── MJRefreshHeaderView.h │ │ ├── MJRefreshHeaderView.m │ │ ├── UIScrollView+Extension.h │ │ ├── UIScrollView+Extension.m │ │ ├── UIScrollView+MJRefresh.h │ │ ├── UIScrollView+MJRefresh.m │ │ ├── UIView+Extension.h │ │ └── UIView+Extension.m │ ├── NJKWebViewProgress │ │ ├── NJKWebViewProgress.h │ │ ├── NJKWebViewProgress.m │ │ ├── NJKWebViewProgressView.h │ │ └── NJKWebViewProgressView.m │ ├── UIImage+ImageEffects.h │ └── UIImage+ImageEffects.m ├── ViewController.h ├── ViewController.m └── main.m └── WFReaderTests ├── Info.plist └── WFReaderTests.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | # Pods/ 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WFReader 2 | a simple reader 3 | 网络版本 转https://github.com/TigerWf/EReader 4 | -------------------------------------------------------------------------------- /WFReader.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WFReader.xcodeproj/xcuserdata/wufuhu.xcuserdatad/xcschemes/WFReader.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /WFReader.xcodeproj/xcuserdata/wufuhu.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WFReader.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | D22DE5171A4C14A500E75F4E 16 | 17 | primary 18 | 19 | 20 | D22DE5301A4C14A500E75F4E 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /WFReader/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WFReader 4 | // 5 | // Created by 阿虎 on 14/12/25. 6 | // Copyright (c) 2014年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /WFReader/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // WFReader 4 | // 5 | // Created by 阿虎 on 14/12/25. 6 | // Copyright (c) 2014年 tigerwf. 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 | // UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.Default, animated: true) 21 | [[UIApplication sharedApplication] setStatusBarHidden:YES]; 22 | return YES; 23 | } 24 | 25 | - (void)applicationWillResignActive:(UIApplication *)application { 26 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 27 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 28 | } 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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 | - (void)applicationWillEnterForeground:(UIApplication *)application { 36 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 37 | } 38 | 39 | - (void)applicationDidBecomeActive:(UIApplication *)application { 40 | // 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. 41 | } 42 | 43 | - (void)applicationWillTerminate:(UIApplication *)application { 44 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /WFReader/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /WFReader/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 | 26 | -------------------------------------------------------------------------------- /WFReader/EReader/Mode/E_CommonManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_CommonManager.h 3 | // E_Reader 4 | // 5 | // Created by 阿虎 on 14-8-8. 6 | // Copyright (c) 2014年 tiger. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "E_ContantFile.h" 11 | /** 12 | * 公共管理类 13 | */ 14 | 15 | 16 | @interface E_CommonManager : NSObject 17 | 18 | 19 | /** 20 | * 保存页码 21 | * 22 | * @param currentChapter 现页码 23 | */ 24 | + (void)saveCurrentPage:(NSInteger)currentPage; 25 | 26 | 27 | 28 | /** 29 | * 获得之前看的页码 30 | * 31 | * @return 页码数 32 | */ 33 | + (NSUInteger)Manager_getPageBefore; 34 | 35 | /** 36 | * 保存章节 37 | * 38 | * @param currentChapter 现章节 39 | */ 40 | + (void)saveCurrentChapter:(NSInteger)currentChapter; 41 | 42 | /** 43 | * 获得主题背景 44 | * 45 | * @return 主题背景id 46 | */ 47 | + (NSInteger)Manager_getReadTheme; 48 | 49 | 50 | /** 51 | * 保存主题ID 52 | * 53 | * @param currentThemeID 主题ID 54 | */ 55 | + (void)saveCurrentThemeID:(NSInteger)currentThemeID; 56 | 57 | /** 58 | * 获得之前看的章节 59 | * 60 | * @return 章节数 61 | */ 62 | + (NSUInteger)Manager_getChapterBefore; 63 | 64 | /** 65 | * 获得字号 66 | * 67 | * @return 字号大小 68 | */ 69 | + (NSUInteger)fontSize; 70 | 71 | 72 | /** 73 | * 存储字号 74 | * 75 | * @param fontSize 存储的字号大小 76 | */ 77 | + (void)saveFontSize:(NSUInteger)fontSize; 78 | 79 | 80 | /** 81 | * 检查当前页是否加了书签 82 | * 83 | * @param currentRange 当前range 84 | * @param currentChapter 85 | * @return 是否加了书签 86 | */ 87 | + (BOOL)checkIfHasBookmark:(NSRange)currentRange withChapter:(NSInteger)currentChapter; 88 | 89 | /** 90 | * 保存书签 91 | * 92 | * @param currentChapter 当前章节 93 | * @param chapterRange 当前页起始的一段文字的range 94 | */ 95 | + (void)saveCurrentMark:(NSInteger)currentChapter andChapterRange:(NSRange)chapterRange byChapterContent:(NSString *)chapterContent; 96 | 97 | /** 98 | * 获得书签数组 99 | * 100 | * @return 书签数组 101 | */ 102 | + (NSMutableArray *)Manager_getMark; 103 | 104 | @end 105 | -------------------------------------------------------------------------------- /WFReader/EReader/Mode/E_CommonManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_CommonManager.m 3 | // E_Reader 4 | // 5 | // Created by 阿虎 on 14-8-8. 6 | // Copyright (c) 2014年 tiger. All rights reserved. 7 | // 8 | 9 | #import "E_CommonManager.h" 10 | #import "E_ContantFile.h" 11 | #import "E_Mark.h" 12 | 13 | @implementation E_CommonManager 14 | 15 | 16 | + (NSInteger)Manager_getReadTheme{ 17 | 18 | NSString *themeID = [[NSUserDefaults standardUserDefaults] objectForKey:SAVETHEME]; 19 | 20 | if (themeID == nil) { 21 | 22 | return 1; 23 | 24 | }else{ 25 | 26 | return [themeID integerValue]; 27 | 28 | } 29 | 30 | } 31 | 32 | 33 | + (void)saveCurrentThemeID:(NSInteger)currentThemeID{ 34 | 35 | [[NSUserDefaults standardUserDefaults] setValue:@(currentThemeID) forKey:SAVETHEME]; 36 | [[NSUserDefaults standardUserDefaults] synchronize]; 37 | 38 | } 39 | 40 | + (NSUInteger)Manager_getPageBefore{ 41 | 42 | NSString *pageID = [[NSUserDefaults standardUserDefaults] objectForKey:SAVEPAGE]; 43 | 44 | if (pageID == nil) { 45 | 46 | return 0; 47 | 48 | }else{ 49 | 50 | return [pageID integerValue]; 51 | 52 | } 53 | 54 | } 55 | 56 | + (void)saveCurrentPage:(NSInteger)currentPage{ 57 | 58 | [[NSUserDefaults standardUserDefaults] setValue:@(currentPage) forKey:SAVEPAGE]; 59 | [[NSUserDefaults standardUserDefaults] synchronize]; 60 | 61 | } 62 | 63 | 64 | + (NSUInteger)Manager_getChapterBefore 65 | { 66 | NSString *chapterID = [[NSUserDefaults standardUserDefaults] objectForKey:OPEN]; 67 | 68 | if (chapterID == nil) { 69 | 70 | return 1; 71 | 72 | }else{ 73 | 74 | return [chapterID integerValue]; 75 | 76 | } 77 | 78 | } 79 | 80 | + (void)saveCurrentChapter:(NSInteger)currentChapter{ 81 | 82 | [[NSUserDefaults standardUserDefaults] setValue:@(currentChapter) forKey:OPEN]; 83 | [[NSUserDefaults standardUserDefaults] synchronize]; 84 | 85 | } 86 | 87 | 88 | 89 | + (NSUInteger)fontSize 90 | { 91 | NSUInteger fontSize = [[NSUserDefaults standardUserDefaults] integerForKey:FONT_SIZE]; 92 | if (fontSize == 0) { 93 | fontSize = 20; 94 | } 95 | return fontSize; 96 | } 97 | 98 | + (void)saveFontSize:(NSUInteger)fontSize 99 | { 100 | [[NSUserDefaults standardUserDefaults] setValue:@(fontSize) forKey:FONT_SIZE]; 101 | [[NSUserDefaults standardUserDefaults] synchronize]; 102 | } 103 | 104 | 105 | #pragma mark- 书签保存 106 | 107 | + (void)saveCurrentMark:(NSInteger)currentChapter andChapterRange:(NSRange)chapterRange byChapterContent:(NSString *)chapterContent{ 108 | 109 | NSDate *senddate=[NSDate date]; 110 | NSDateFormatter *dateformatter=[[NSDateFormatter alloc] init]; 111 | [dateformatter setDateFormat:@"YYYY-MM-dd"]; 112 | NSString *locationString=[dateformatter stringFromDate:senddate]; 113 | 114 | E_Mark *eMark = [[E_Mark alloc] init]; 115 | eMark.markRange = NSStringFromRange(chapterRange); 116 | eMark.markChapter = [NSString stringWithFormat:@"%d",currentChapter]; 117 | eMark.markContent = [chapterContent substringWithRange:chapterRange]; 118 | eMark.markTime = locationString; 119 | 120 | NSLog(@"chapterRange == %@",NSStringFromRange(chapterRange)); 121 | 122 | if (![self checkIfHasBookmark:chapterRange withChapter:currentChapter]) {//没加书签 123 | 124 | NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:epubBookName]; 125 | NSMutableArray *oldSaveArray = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 126 | if (oldSaveArray.count == 0) { 127 | 128 | NSMutableArray *newSaveArray = [[NSMutableArray alloc] init]; 129 | [newSaveArray addObject:eMark]; 130 | [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:newSaveArray] forKey:epubBookName]; 131 | 132 | }else{ 133 | 134 | [oldSaveArray addObject:eMark]; 135 | [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:oldSaveArray] forKey:epubBookName]; 136 | } 137 | 138 | [[NSUserDefaults standardUserDefaults] synchronize]; 139 | 140 | }else{//有书签 141 | 142 | NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:epubBookName]; 143 | NSMutableArray *oldSaveArray = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 144 | for (int i = 0 ; i < oldSaveArray.count; i ++) { 145 | 146 | E_Mark *e = (E_Mark *)[oldSaveArray objectAtIndex:i]; 147 | 148 | if (((NSRangeFromString(e.markRange).location >= chapterRange.location) && (NSRangeFromString(e.markRange).location < chapterRange.location + chapterRange.length)) && ([e.markChapter isEqualToString:[NSString stringWithFormat:@"%d",currentChapter]])) { 149 | 150 | [oldSaveArray removeObject:e]; 151 | [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:oldSaveArray] forKey:epubBookName]; 152 | 153 | } 154 | } 155 | } 156 | 157 | } 158 | 159 | + (BOOL)checkIfHasBookmark:(NSRange)currentRange withChapter:(NSInteger)currentChapter{ 160 | 161 | NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:epubBookName]; 162 | NSMutableArray *oldSaveArray = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 163 | int k = 0; 164 | for (int i = 0; i < oldSaveArray.count; i ++) { 165 | E_Mark *e = (E_Mark *)[oldSaveArray objectAtIndex:i]; 166 | 167 | if ((NSRangeFromString(e.markRange).location >= currentRange.location) && (NSRangeFromString(e.markRange).location < currentRange.location + currentRange.length) && [e.markChapter isEqualToString:[NSString stringWithFormat:@"%d",currentChapter]]) { 168 | k++; 169 | }else{ 170 | // k++; 171 | } 172 | } 173 | if (k >= 1) { 174 | return YES; 175 | }else{ 176 | return NO; 177 | } 178 | } 179 | 180 | + (NSMutableArray *)Manager_getMark{ 181 | 182 | NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:epubBookName]; 183 | NSMutableArray *oldSaveArray = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 184 | if (oldSaveArray.count == 0) { 185 | return nil; 186 | }else{ 187 | return oldSaveArray; 188 | 189 | } 190 | 191 | } 192 | 193 | @end 194 | -------------------------------------------------------------------------------- /WFReader/EReader/Mode/E_ContantFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_ContantFile.h 3 | // WFReader 4 | // 5 | // Created by 阿虎 on 14/12/25. 6 | // Copyright (c) 2014年 tigerwf. All rights reserved. 7 | // 8 | 9 | #ifndef WFReader_E_ContantFile_h 10 | #define WFReader_E_ContantFile_h 11 | 12 | #define OPEN @"open" 13 | #define SAVEPAGE @"savePage" 14 | #define SAVETHEME @"saveTheme" 15 | #define offSet_x 20 16 | #define offSet_y 40 17 | #define FONT_SIZE @"FONT_SIZE" 18 | #define kBottomBarH 150 19 | 20 | #define FilePath [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] 21 | #define epubBookName @"倚天屠龙记" 22 | #define kScreenW [UIScreen mainScreen].bounds.size.width 23 | 24 | 25 | #define DELAYEXECUTE(delayTime,func) (dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{func;})) 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /WFReader/EReader/Mode/E_EveryChapter.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_EveryChapter.h 3 | // E_Reader 4 | // 5 | // Created by 阿虎 on 14-8-8. 6 | // Copyright (c) 2014年 tiger. All rights reserved. 7 | // 8 | 9 | #import 10 | /** 11 | * 每章的内容与标题 12 | */ 13 | @interface E_EveryChapter : NSObject 14 | 15 | @property (nonatomic,strong) NSString *chapterContent; 16 | @property (nonatomic,strong) NSString *chapterTitle; 17 | 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /WFReader/EReader/Mode/E_EveryChapter.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_EveryChapter.m 3 | // E_Reader 4 | // 5 | // Created by 阿虎 on 14-8-8. 6 | // Copyright (c) 2014年 tiger. All rights reserved. 7 | // 8 | 9 | #import "E_EveryChapter.h" 10 | 11 | @implementation E_EveryChapter 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WFReader/EReader/Mode/E_Mark.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_Mark.h 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/3/2. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface E_Mark : NSObject 12 | 13 | @property (nonatomic,strong) NSString *markChapter; 14 | @property (nonatomic,strong) NSString *markRange; 15 | @property (nonatomic,strong) NSString *markContent; 16 | @property (nonatomic,strong) NSString *markTime; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /WFReader/EReader/Mode/E_Mark.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_Mark.m 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/3/2. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "E_Mark.h" 10 | 11 | #define kMarkChapter @"kMarkChapter" 12 | #define kMarkRange @"kMarkRange" 13 | #define kMarkContent @"kMarkContent" 14 | #define kMarkTime @"kMarkTime" 15 | 16 | @implementation E_Mark 17 | 18 | @synthesize markChapter; 19 | @synthesize markRange; 20 | @synthesize markContent; 21 | @synthesize markTime; 22 | 23 | - (void)encodeWithCoder:(NSCoder *)encoder{ 24 | 25 | [encoder encodeObject:self.markChapter forKey:kMarkChapter]; 26 | [encoder encodeObject:self.markRange forKey:kMarkRange]; 27 | [encoder encodeObject:self.markContent forKey:kMarkContent]; 28 | [encoder encodeObject:self.markTime forKey:kMarkTime]; 29 | } 30 | 31 | - (id)initWithCoder:(NSCoder *)decoder { 32 | 33 | if (self = [super init]) { 34 | 35 | self.markChapter = [decoder decodeObjectForKey:kMarkChapter]; 36 | self.markRange = [decoder decodeObjectForKey:kMarkRange]; 37 | self.markContent = [decoder decodeObjectForKey:kMarkContent]; 38 | self.markTime = [decoder decodeObjectForKey:kMarkTime]; 39 | 40 | } 41 | return self; 42 | } 43 | 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /WFReader/EReader/Mode/E_Paging.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_Paging.h 3 | // E_Reader 4 | // 5 | // Created by 阿虎 on 14-8-8. 6 | // Copyright (c) 2014年 tiger. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "E_ContantFile.h" 12 | /** 13 | * 分页计算并给予内容等 14 | */ 15 | 16 | @interface E_Paging : NSObject 17 | 18 | @property (nonatomic, copy) NSString *contentText; 19 | @property (nonatomic, unsafe_unretained) NSUInteger contentFont; 20 | @property (nonatomic, unsafe_unretained) CGSize textRenderSize; 21 | 22 | /** 23 | * 分页 24 | */ 25 | - (void)paginate; 26 | 27 | 28 | 29 | /** 30 | * 一共分了多少页 31 | * 32 | * @return 一章所分的页数 33 | */ 34 | - (NSUInteger)pageCount; 35 | 36 | 37 | 38 | /** 39 | * 获得page页的文字内容 40 | * 41 | * @param page 页 42 | * 43 | * @return 内容 44 | */ 45 | - (NSString *)stringOfPage:(NSUInteger)page; 46 | 47 | /** 48 | * 根据当前的页码计算范围 - 目的是为了变字号的时候内容偏移不要太多 49 | * 50 | * @param page 当前页码 51 | * 52 | * @return 范围 53 | */ 54 | - (NSRange)rangeOfPage:(NSUInteger)page; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /WFReader/EReader/Mode/E_Paging.mm: -------------------------------------------------------------------------------- 1 | // 2 | // E_Paging.mm 3 | // E_Reader 4 | // 5 | // Created by 阿虎 on 14-8-8. 6 | // Copyright (c) 2014年 tiger. All rights reserved. 7 | // 8 | 9 | 10 | #import "E_Paging.h" 11 | 12 | #import 13 | #include 14 | #include 15 | #include 16 | 17 | #define CHAR_PER_LOAD 50000 18 | 19 | using namespace std; 20 | 21 | @interface E_Paging () 22 | 23 | @end 24 | 25 | @implementation E_Paging 26 | { 27 | vector _pageOffsets; 28 | } 29 | 30 | 31 | - (void)paginate 32 | { 33 | //清空 34 | _pageOffsets.clear(); 35 | 36 | NSString *buffer = [self subStringWithRange:NSMakeRange(0, CHAR_PER_LOAD)]; 37 | NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:buffer]; 38 | buffer = nil; // 马上释放 39 | 40 | NSDictionary *strAttr = [self stringAttrWithFont:self.contentFont]; 41 | [attrString setAttributes:strAttr range:NSMakeRange(0, attrString.length)]; 42 | CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef) attrString); 43 | CGPathRef path = CGPathCreateWithRect(CGRectMake(0, 0, _textRenderSize.width, _textRenderSize.height), NULL); 44 | 45 | int currentOffset = 0; 46 | int currentInnerOffset = 0; 47 | BOOL hasMorePages = YES; 48 | 49 | // 防止死循环,如果在同一个位置获取CTFrame超过2次,则跳出循环 50 | int preventDeadLoopSign = currentOffset; 51 | int samePlaceRepeatCount = 0; 52 | 53 | while (hasMorePages) { 54 | if (preventDeadLoopSign == currentOffset) { 55 | 56 | ++samePlaceRepeatCount; 57 | 58 | } else { 59 | 60 | samePlaceRepeatCount = 0; 61 | } 62 | 63 | if (samePlaceRepeatCount > 1) { 64 | // 退出循环前检查一下最后一页是否已经加上 65 | if (_pageOffsets.size() == 0) { 66 | 67 | _pageOffsets.push_back(currentOffset); 68 | 69 | } else { 70 | 71 | NSUInteger lastOffset = _pageOffsets.back(); 72 | 73 | if (lastOffset != currentOffset) { 74 | 75 | _pageOffsets.push_back(currentOffset); 76 | } 77 | } 78 | break; 79 | } 80 | 81 | _pageOffsets.push_back(currentOffset); 82 | 83 | CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(currentInnerOffset, 0), path, NULL); 84 | CFRange range = CTFrameGetVisibleStringRange(frame); 85 | 86 | if ((range.location + range.length) != attrString.length) { 87 | 88 | currentOffset += range.length; 89 | currentInnerOffset += range.length; 90 | 91 | } else if ((range.location + range.length) == attrString.length && (currentOffset + range.length) != [_contentText length]) { 92 | // 加载后面的 93 | CFRelease(frame); frame = NULL; 94 | CFRelease(frameSetter); 95 | 96 | _pageOffsets.pop_back(); 97 | 98 | buffer = [self subStringWithRange:NSMakeRange(currentOffset, CHAR_PER_LOAD)]; 99 | attrString = [[NSMutableAttributedString alloc] initWithString:buffer]; 100 | [attrString setAttributes:strAttr range:NSMakeRange(0, attrString.length)]; 101 | buffer = nil; 102 | 103 | currentInnerOffset = 0; 104 | 105 | frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef) attrString); 106 | } else { 107 | // 已经分完,提示跳出循环 108 | hasMorePages = NO; 109 | } 110 | if (frame) CFRelease(frame); 111 | } 112 | 113 | CGPathRelease(path); 114 | CFRelease(frameSetter); 115 | 116 | } 117 | 118 | - (NSUInteger)pageCount { 119 | 120 | return _pageOffsets.size(); 121 | } 122 | 123 | 124 | - (NSString *)stringOfPage:(NSUInteger)page { 125 | 126 | if (page >= [self pageCount]) return @""; 127 | 128 | NSUInteger head = _pageOffsets[page]; 129 | 130 | NSUInteger tail = _contentText.length; 131 | if (page+1 < [self pageCount]) { 132 | 133 | tail = _pageOffsets[page+1]; 134 | } 135 | 136 | return [self subStringWithRange:NSMakeRange(head, tail-head)]; 137 | } 138 | 139 | //***////////////////////////////////////////////// 140 | 141 | - (NSString *)subStringWithRange:(NSRange)range 142 | { 143 | if (range.location == NSNotFound) return @""; 144 | 145 | NSUInteger head = range.location; 146 | if (head >= _contentText.length) return @""; 147 | 148 | NSUInteger tail = (range.location + range.length); 149 | tail = tail > _contentText.length ? _contentText.length : tail; 150 | 151 | if ((NSUInteger)(tail - head) == 4294602370) { 152 | 153 | return @""; 154 | } 155 | 156 | return [_contentText substringWithRange:NSMakeRange(head, tail - head)]; 157 | } 158 | 159 | - (NSRange)rangeOfPage:(NSUInteger)page { 160 | 161 | if (page >= _pageOffsets.size()) { 162 | return NSMakeRange(NSNotFound, 0); 163 | } 164 | 165 | if (page < _pageOffsets.size() - 1) { 166 | return NSMakeRange(_pageOffsets[page], _pageOffsets[page + 1] - _pageOffsets[page]); 167 | } 168 | 169 | return NSMakeRange(_pageOffsets[page], _contentText.length - _pageOffsets[page]); 170 | } 171 | 172 | - (NSDictionary *)stringAttrWithFont:(NSUInteger )fontSize 173 | { 174 | UIFont *font = [UIFont systemFontOfSize:fontSize]; 175 | NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 176 | paragraphStyle.lineSpacing = font.pointSize / 2; 177 | paragraphStyle.alignment = NSTextAlignmentJustified; 178 | return @{NSParagraphStyleAttributeName: paragraphStyle, NSFontAttributeName:font}; 179 | } 180 | 181 | @end 182 | -------------------------------------------------------------------------------- /WFReader/EReader/Mode/E_ReaderDataSource.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_ReaderDataSource.h 3 | // E_Reader 4 | // 5 | // Created by 阿虎 on 14-8-8. 6 | // Copyright (c) 2014年 tiger. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "E_EveryChapter.h" 11 | /** 12 | * 书籍内容来源部分 退出的时候页码存储未写,根据实际情况去存 13 | */ 14 | @interface E_ReaderDataSource : NSObject 15 | 16 | //当前章节数 17 | @property (unsafe_unretained, nonatomic) NSUInteger currentChapterIndex; 18 | 19 | //总章节数 20 | @property (unsafe_unretained, nonatomic) NSUInteger totalChapter; 21 | 22 | @property (copy , nonatomic) NSMutableString *totalString;//全文 23 | 24 | @property (strong , nonatomic) NSMutableArray *everyChapterRange;//每章节的range 25 | /** 26 | * 单例 27 | * 28 | * @return 实例 29 | */ 30 | + (E_ReaderDataSource *)shareInstance; 31 | 32 | 33 | /** 34 | * 通过传入id来获取章节信息 35 | * 36 | * @return 章节类 37 | */ 38 | - (E_EveryChapter *)openChapter; 39 | 40 | /** 41 | * 章节跳转 42 | * 43 | * @param clickChapter 跳转章节数 44 | * 45 | * @return 该章节 46 | */ 47 | - (E_EveryChapter *)openChapter:(NSInteger)clickChapter; 48 | 49 | /** 50 | * 打开得页数 51 | * 52 | * @return 返回页数 53 | */ 54 | - (NSUInteger)openPage; 55 | 56 | /** 57 | * 获得下一章内容 58 | * 59 | * @return 章节类 60 | */ 61 | - (E_EveryChapter *)nextChapter; 62 | 63 | 64 | /** 65 | * 获得上一章内容 66 | * 67 | * @return 章节类 68 | */ 69 | - (E_EveryChapter *)preChapter; 70 | 71 | /** 72 | * 全文搜索 73 | * 74 | * @param keyWord 要搜索的关键字 75 | * 76 | * @return 搜索的关键字所在的位置 77 | */ 78 | - (NSMutableArray *)searchWithKeyWords:(NSString *)keyWord; 79 | 80 | 81 | /** 82 | * 获得全文 83 | */ 84 | - (void)resetTotalString; 85 | 86 | 87 | /** 88 | * 获得指定章节的第一个字在整篇文章中的位置 89 | * 90 | * @param page 指定章节 91 | * 92 | * @return 位置 93 | */ 94 | - (NSInteger)getChapterBeginIndex:(NSInteger)page; 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /WFReader/EReader/Mode/E_ReaderDataSource.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_ReaderDataSource.m 3 | // E_Reader 4 | // 5 | // Created by 阿虎 on 14-8-8. 6 | // Copyright (c) 2014年 tiger. All rights reserved. 7 | // 8 | 9 | #import "E_ReaderDataSource.h" 10 | #import "E_CommonManager.h" 11 | #import "E_HUDView.h" 12 | 13 | 14 | @implementation E_ReaderDataSource 15 | 16 | + (E_ReaderDataSource *)shareInstance{ 17 | 18 | static E_ReaderDataSource *dataSource; 19 | static dispatch_once_t onceToken; 20 | 21 | dispatch_once(&onceToken, ^{ 22 | 23 | dataSource = [[E_ReaderDataSource alloc] init]; 24 | 25 | 26 | }); 27 | 28 | return dataSource; 29 | } 30 | 31 | 32 | - (E_EveryChapter *)openChapter:(NSInteger)clickChapter{ 33 | 34 | _currentChapterIndex = clickChapter; 35 | 36 | E_EveryChapter *chapter = [[E_EveryChapter alloc] init]; 37 | 38 | NSString *chapter_num = [NSString stringWithFormat:@"Chapter%ld",_currentChapterIndex]; 39 | NSString *path1 = [[NSBundle mainBundle] pathForResource:chapter_num ofType:@"txt"]; 40 | chapter.chapterContent = [NSString stringWithContentsOfFile:path1 encoding:4 error:NULL]; 41 | 42 | return chapter; 43 | } 44 | 45 | - (E_EveryChapter *)openChapter{ 46 | NSUInteger index = [E_CommonManager Manager_getChapterBefore]; 47 | 48 | _currentChapterIndex = index; 49 | 50 | E_EveryChapter *chapter = [[E_EveryChapter alloc] init]; 51 | 52 | NSString *chapter_num = [NSString stringWithFormat:@"Chapter%ld",_currentChapterIndex]; 53 | NSString *path1 = [[NSBundle mainBundle] pathForResource:chapter_num ofType:@"txt"]; 54 | chapter.chapterContent = [NSString stringWithContentsOfFile:path1 encoding:4 error:NULL]; 55 | 56 | return chapter; 57 | } 58 | 59 | - (NSUInteger)openPage{ 60 | 61 | NSUInteger index = [E_CommonManager Manager_getPageBefore]; 62 | return index; 63 | 64 | } 65 | 66 | 67 | - (E_EveryChapter *)nextChapter{ 68 | 69 | if (_currentChapterIndex >= _totalChapter) { 70 | [E_HUDView showMsg:@"没有更多内容了" inView:nil]; 71 | return nil; 72 | 73 | }else{ 74 | _currentChapterIndex++; 75 | 76 | E_EveryChapter *chapter = [E_EveryChapter new]; 77 | chapter.chapterContent = readTextData(_currentChapterIndex); 78 | 79 | return chapter; 80 | 81 | } 82 | 83 | } 84 | 85 | - (E_EveryChapter *)preChapter{ 86 | 87 | if (_currentChapterIndex <= 1) { 88 | [E_HUDView showMsg:@"已经是第一页了" inView:nil]; 89 | return nil; 90 | 91 | }else{ 92 | _currentChapterIndex --; 93 | 94 | E_EveryChapter *chapter = [E_EveryChapter new]; 95 | chapter.chapterContent = readTextData(_currentChapterIndex); 96 | 97 | return chapter; 98 | } 99 | } 100 | 101 | - (void)resetTotalString{ 102 | 103 | _totalString = [NSMutableString string]; 104 | _everyChapterRange = [NSMutableArray array]; 105 | 106 | for (int i = 1; i < INT_MAX; i ++) { 107 | 108 | if (readTextData(i) != nil) { 109 | 110 | NSUInteger location = _totalString.length; 111 | [_totalString appendString:readTextData(i)]; 112 | NSUInteger length = _totalString.length - location; 113 | NSRange chapterRange = NSMakeRange(location, length); 114 | [_everyChapterRange addObject:NSStringFromRange(chapterRange)]; 115 | 116 | 117 | }else{ 118 | break; 119 | } 120 | } 121 | 122 | } 123 | 124 | - (NSInteger)getChapterBeginIndex:(NSInteger)page{ 125 | 126 | NSInteger index = 0; 127 | for (int i = 1; i < page; i ++) { 128 | 129 | if (readTextData(i) != nil) { 130 | 131 | index += readTextData(i).length; 132 | // NSLog(@"index == %ld",index); 133 | 134 | }else{ 135 | break; 136 | } 137 | } 138 | return index; 139 | } 140 | 141 | - (NSMutableArray *)searchWithKeyWords:(NSString *)keyWord{ 142 | //关键字为空 则返回空数组 143 | if (keyWord == nil || [keyWord isEqualToString:@""]) { 144 | return nil; 145 | } 146 | 147 | NSMutableArray *searchResult = [[NSMutableArray alloc] initWithCapacity:0];//内容 148 | NSMutableArray *whichChapter = [[NSMutableArray alloc] initWithCapacity:0];//内容所在章节 149 | NSMutableArray *locationResult = [[NSMutableArray alloc] initWithCapacity:0];//搜索内容所在range 150 | NSMutableArray *feedBackResult = [[NSMutableArray alloc] initWithCapacity:0];//上面3个数组集合 151 | 152 | 153 | NSMutableString *blankWord = [NSMutableString string]; 154 | for (int i = 0; i < keyWord.length; i ++) { 155 | 156 | [blankWord appendString:@" "]; 157 | } 158 | 159 | //一次搜索20条 160 | for (int i = 0; i < 20; i++) { 161 | 162 | if ([_totalString rangeOfString:keyWord options:1].location != NSNotFound) { 163 | 164 | NSInteger newLo = [_totalString rangeOfString:keyWord options:1].location; 165 | NSInteger newLen = [_totalString rangeOfString:keyWord options:1].length; 166 | // NSLog(@"newLo == %ld,, newLen == %ld",newLo,newLen); 167 | int temp = 0; 168 | for (int j = 0; j < _everyChapterRange.count; j ++) { 169 | if (newLo > NSRangeFromString([_everyChapterRange objectAtIndex:j]).location) { 170 | temp ++; 171 | }else{ 172 | break; 173 | } 174 | 175 | } 176 | 177 | [whichChapter addObject:[NSString stringWithFormat:@"%d",temp]]; 178 | [locationResult addObject:NSStringFromRange(NSMakeRange(newLo, newLen))]; 179 | 180 | NSRange searchRange = NSMakeRange(newLo, [self doRandomLength:newLo andPreOrNext:NO] == 0?newLen:[self doRandomLength:newLo andPreOrNext:NO]); 181 | 182 | NSString *completeString = [[_totalString substringWithRange:searchRange] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 183 | completeString = [completeString stringByReplacingOccurrencesOfString:@"\r" withString:@""]; 184 | completeString = [completeString stringByReplacingOccurrencesOfString:@"\n" withString:@""]; 185 | [searchResult addObject:completeString]; 186 | 187 | 188 | 189 | [_totalString replaceCharactersInRange:NSMakeRange(newLo, newLen) withString:blankWord]; 190 | 191 | }else{ 192 | break; 193 | } 194 | } 195 | 196 | [feedBackResult addObject:searchResult]; 197 | [feedBackResult addObject:whichChapter]; 198 | [feedBackResult addObject:locationResult]; 199 | return feedBackResult; 200 | 201 | } 202 | 203 | - (NSInteger)doRandomLength:(NSInteger)location andPreOrNext:(BOOL)sender 204 | { 205 | //获取1到x之间的整数 206 | if (sender == YES) { 207 | NSInteger temp = location; 208 | NSInteger value = (arc4random() % 13) + 5; 209 | location -=value; 210 | if (location<0) { 211 | location = temp; 212 | } 213 | 214 | return location; 215 | 216 | } 217 | else 218 | { 219 | 220 | NSInteger value = (arc4random() % 20) + 20; 221 | if (location + value >= _totalString.length) { 222 | value = 0; 223 | }else{ 224 | 225 | } 226 | 227 | return value; 228 | 229 | } 230 | 231 | 232 | } 233 | 234 | static NSString *readTextData(NSUInteger index){ 235 | 236 | NSString *chapter_num = [NSString stringWithFormat:@"Chapter%ld",index]; 237 | NSString *path1 = [[NSBundle mainBundle] pathForResource:chapter_num ofType:@"txt"]; 238 | NSString *content = [NSString stringWithContentsOfFile:path1 encoding:4 error:NULL]; 239 | return content; 240 | } 241 | 242 | @end 243 | -------------------------------------------------------------------------------- /WFReader/EReader/Mode/NSDate+NSDate_E_Date.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+NSDate_E_Date.h 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/3/3. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDate (NSDate_E_Date) 12 | 13 | /* 14 | 是否是今天 15 | */ 16 | - (BOOL)isToday; 17 | 18 | /* 19 | 时间差 20 | */ 21 | - (NSInteger) minutesAfterDate : (NSDate *) aDate; 22 | - (NSInteger) minutesBeforeDate: (NSDate *) aDate; 23 | 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /WFReader/EReader/Mode/NSDate+NSDate_E_Date.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+NSDate_E_Date.m 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/3/3. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "NSDate+NSDate_E_Date.h" 10 | 11 | #define DATE_COMPONENTS (NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekdayCalendarUnit | NSWeekdayOrdinalCalendarUnit) 12 | 13 | #define CURRENT_CALENDAR [NSCalendar currentCalendar] 14 | 15 | #define D_MINUTE 60 16 | 17 | 18 | @implementation NSDate (NSDate_E_Date) 19 | 20 | - (BOOL) isToday{ 21 | 22 | return [self isEqualToDateTime:[NSDate date]]; 23 | } 24 | 25 | - (BOOL) isEqualToDateTime: (NSDate *) aDate{ 26 | 27 | NSDateComponents *components1 = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:self]; 28 | NSDateComponents *components2 = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:aDate]; 29 | return ((components1.year == components2.year) && 30 | (components1.month == components2.month) && 31 | (components1.day == components2.day)); 32 | } 33 | 34 | - (NSInteger) minutesAfterDate: (NSDate *) aDate{ 35 | 36 | NSTimeInterval ti = [self timeIntervalSinceDate:aDate]; 37 | return (NSInteger) (ti / D_MINUTE); 38 | } 39 | 40 | - (NSInteger) minutesBeforeDate: (NSDate *) aDate{ 41 | 42 | NSTimeInterval ti = [aDate timeIntervalSinceDate:self]; 43 | return (NSInteger) (ti / D_MINUTE); 44 | } 45 | 46 | 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_CursorView.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_CursorView.h 3 | // WFReader 4 | // 5 | // Created by 阿虎 on 15/1/29. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | * 光标类 13 | */ 14 | 15 | typedef enum { 16 | CursorLeft = 0, 17 | CursorRight , 18 | 19 | } CursorType; 20 | 21 | @interface E_CursorView : UIView 22 | { 23 | UIImageView *_dragDot; 24 | } 25 | @property (nonatomic,assign) CursorType direction; 26 | @property (nonatomic,assign) float cursorHeight; 27 | @property (nonatomic,retain) UIColor *cursorColor; 28 | @property (nonatomic,assign) CGPoint setupPoint; 29 | 30 | - (id)initWithType:(CursorType)type andHeight:(float)cursorHeight byDrawColor:(UIColor *)drawColor; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_CursorView.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_CursorView.m 3 | // WFReader 4 | // 5 | // Created by 阿虎 on 15/1/29. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "E_CursorView.h" 10 | #define kE_CursorWidth 2 11 | 12 | @implementation E_CursorView 13 | 14 | /* 15 | // Only override drawRect: if you perform custom drawing. 16 | // An empty implementation adversely affects performance during animation. 17 | - (void)drawRect:(CGRect)rect { 18 | // Drawing code 19 | } 20 | */ 21 | 22 | - (id)initWithType:(CursorType)type andHeight:(float)cursorHeight byDrawColor:(UIColor *)drawColor{ 23 | self = [super init]; 24 | if (self) { 25 | _direction = type; 26 | _cursorHeight = cursorHeight; 27 | _cursorColor = drawColor; 28 | self.clipsToBounds = NO; 29 | 30 | } 31 | return self; 32 | 33 | } 34 | 35 | 36 | - (void)setSetupPoint:(CGPoint)setupPoint{ 37 | 38 | self.backgroundColor = _cursorColor; 39 | 40 | if (_dragDot) { 41 | [_dragDot removeFromSuperview]; 42 | _dragDot = nil; 43 | } 44 | 45 | _dragDot = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"r_drag-dot.png"]]; 46 | 47 | if (_direction == CursorLeft) { 48 | self.frame = CGRectMake(setupPoint.x - kE_CursorWidth, setupPoint.y - _cursorHeight, kE_CursorWidth, _cursorHeight); 49 | _dragDot.frame = CGRectMake(-7, -8, 15, 17); 50 | 51 | }else{ 52 | self.frame = CGRectMake(setupPoint.x, setupPoint.y - _cursorHeight, kE_CursorWidth, _cursorHeight); 53 | _dragDot.frame = CGRectMake(-6, _cursorHeight - 8, 15, 17); 54 | } 55 | [self addSubview:_dragDot]; 56 | } 57 | 58 | - (void)dealloc{ 59 | 60 | 61 | } 62 | @end 63 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_DrawerView.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_DrawerView.h 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/2/15. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "E_ListView.h" 11 | #import "E_Mark.h" 12 | 13 | @protocol E_DrawerViewDelegate 14 | 15 | - (void)openTapGes; 16 | - (void)turnToClickChapter:(NSInteger)chapterIndex; 17 | - (void)turnToClickMark:(E_Mark *)eMark; 18 | 19 | @end 20 | 21 | @interface E_DrawerView : UIView{ 22 | 23 | E_ListView *_listView; 24 | } 25 | @property(nonatomic, strong) UIView *parent; 26 | @property(nonatomic, assign) iddelegate; 27 | 28 | - (id)initWithFrame:(CGRect)frame parentView:(UIView *)p; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_DrawerView.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_DrawerView.m 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/2/15. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "E_DrawerView.h" 10 | #import "UIImage+ImageEffects.h" 11 | #define ListViewW (3* self.frame.size.width/4) 12 | 13 | @implementation E_DrawerView 14 | 15 | - (id)initWithFrame:(CGRect)frame parentView:(UIView *)p{ 16 | self = [super initWithFrame:frame]; 17 | if (self) { 18 | 19 | self.backgroundColor = [UIColor clearColor]; 20 | self.parent = p; 21 | self.alpha = 0; 22 | UIImage *background = [self blurredSnapshot]; 23 | UIImageView *backgroundView = [[UIImageView alloc] initWithFrame:self.bounds]; 24 | backgroundView.image = background; 25 | [self addSubview:backgroundView]; 26 | 27 | 28 | 29 | UITapGestureRecognizer *tapGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideDrawView)]; 30 | tapGes.delegate = self; 31 | [self addGestureRecognizer:tapGes]; 32 | 33 | [self configUI]; 34 | 35 | } 36 | return self; 37 | 38 | } 39 | 40 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{ 41 | 42 | CGPoint touchPoint = [touch locationInView:self]; 43 | CGRect blurRect = CGRectMake(ListViewW, 0, self.frame.size.width - ListViewW, self.frame.size.height); 44 | if (CGRectContainsPoint(blurRect, touchPoint)) { 45 | return YES; 46 | }else{ 47 | return NO; 48 | } 49 | 50 | } 51 | 52 | 53 | - (void)hideDrawView{ 54 | 55 | [UIView animateWithDuration:0.25 animations:^{ 56 | _listView.frame = CGRectMake(-ListViewW, 0, ListViewW, self.frame.size.height); 57 | self.alpha = 0.0; 58 | } completion:^(BOOL finished) { 59 | [_listView removeFromSuperview]; 60 | _listView = nil; 61 | [_delegate openTapGes]; 62 | [self removeFromSuperview]; 63 | }]; 64 | 65 | 66 | } 67 | 68 | - (void)removeE_ListView{ 69 | 70 | [_listView removeFromSuperview]; 71 | _listView = nil; 72 | [_delegate openTapGes]; 73 | [self removeFromSuperview]; 74 | 75 | } 76 | 77 | - (void)configUI{ 78 | 79 | if (_listView == nil) { 80 | 81 | _listView = [[E_ListView alloc] initWithFrame:CGRectMake(- ListViewW, 0, ListViewW, self.frame.size.height)]; 82 | _listView.delegate = self; 83 | [self addSubview:_listView]; 84 | 85 | [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{ 86 | _listView.frame = CGRectMake(0, 0, ListViewW, self.frame.size.height); 87 | self.alpha = 1.0; 88 | } completion:^(BOOL finished) { 89 | 90 | }]; 91 | 92 | 93 | 94 | }else{ 95 | 96 | 97 | } 98 | 99 | 100 | } 101 | 102 | - (void)clickMark:(E_Mark *)eMark{ 103 | 104 | [UIView animateWithDuration:0.25 animations:^{ 105 | _listView.frame = CGRectMake(-ListViewW, 0, ListViewW, self.frame.size.height); 106 | self.alpha = 0.0; 107 | } completion:^(BOOL finished) { 108 | [_listView removeFromSuperview]; 109 | _listView = nil; 110 | [_delegate openTapGes]; 111 | [_delegate turnToClickMark:eMark]; 112 | [self removeFromSuperview]; 113 | }]; 114 | 115 | } 116 | 117 | - (void)clickChapter:(NSInteger)chaperIndex{ 118 | 119 | [UIView animateWithDuration:0.25 animations:^{ 120 | _listView.frame = CGRectMake(-ListViewW, 0, ListViewW, self.frame.size.height); 121 | self.alpha = 0.0; 122 | } completion:^(BOOL finished) { 123 | [_listView removeFromSuperview]; 124 | _listView = nil; 125 | [_delegate openTapGes]; 126 | [_delegate turnToClickChapter:chaperIndex]; 127 | [self removeFromSuperview]; 128 | }]; 129 | 130 | } 131 | 132 | - (UIImage *)blurredSnapshot { 133 | 134 | UIGraphicsBeginImageContextWithOptions(CGSizeMake(CGRectGetWidth(self.parent.frame), CGRectGetHeight(self.parent.frame)), NO, 1.0f); 135 | [self.parent drawViewHierarchyInRect:CGRectMake(0, 0, CGRectGetWidth(self.parent.frame), CGRectGetHeight(self.parent.frame)) afterScreenUpdates:NO]; 136 | UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext(); 137 | UIImage *blurredSnapshotImage = [snapshotImage applyLightEffect]; 138 | 139 | 140 | UIGraphicsEndImageContext(); 141 | 142 | return blurredSnapshotImage; 143 | } 144 | 145 | @end 146 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_HUDView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZHX_HUDView.h 3 | // ZHX 4 | // 5 | // Created by 吴福虎 on 14-1-6. 6 | // Copyright (c) 2014年 阿虎. All rights reserved. 7 | // 8 | /* 9 | 弹出视图 10 | */ 11 | 12 | #import 13 | 14 | @interface E_HUDView : UIView 15 | { 16 | UIFont *msgFont; 17 | } 18 | @property (nonatomic, copy) NSString *msg; 19 | @property (nonatomic, retain) UILabel *labelText; 20 | @property (nonatomic, assign) float leftMargin; 21 | @property (nonatomic, assign) float topMargin; 22 | @property (nonatomic, assign) float animationLeftScale; 23 | @property (nonatomic, assign) float animationTopScale; 24 | @property (nonatomic, assign) float totalDuration; 25 | 26 | + (void)showMsg:(NSString *)msg inView:(UIView*)theView; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_HUDView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZHX_HUDView.m 3 | // ZHX 4 | // 5 | // Created by 吴福虎 on 14-1-6. 6 | // Copyright (c) 2014年 阿虎. All rights reserved. 7 | // 8 | 9 | #import "E_HUDView.h" 10 | 11 | @implementation E_HUDView 12 | @synthesize msg; 13 | @synthesize leftMargin; 14 | @synthesize topMargin; 15 | @synthesize animationLeftScale; 16 | @synthesize animationTopScale; 17 | @synthesize totalDuration; 18 | @synthesize labelText; 19 | 20 | - (id)initWithFrame:(CGRect)frame{ 21 | 22 | self = [super initWithFrame:frame]; 23 | if (self) { 24 | // Initialization code 25 | } 26 | return self; 27 | } 28 | 29 | + (void)showMsg:(NSString *)msg inView:(UIView*)theView{ 30 | 31 | E_HUDView *alert = [[E_HUDView alloc] initWithMsg:msg]; 32 | if (!theView){ 33 | [[self getUnhiddenFrontWindowOfApplication] addSubview:alert]; 34 | } 35 | else{ 36 | [[E_HUDView getWindow] addSubview:alert]; 37 | } 38 | [alert showAlert]; 39 | 40 | } 41 | 42 | - (void)showAlert{ 43 | 44 | self.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.8]; 45 | self.alpha = 0.0; 46 | CGPoint center=[E_HUDView getWindow].center; 47 | // //调整位置 48 | // center.y -= (int)((SCREEN_HEIGHT - self.frame.size.height) / 164.0f * 36 / 2); 49 | self.center=center; 50 | CAKeyframeAnimation* opacityAnimation= [CAKeyframeAnimation animationWithKeyPath:@"opacity"]; 51 | 52 | opacityAnimation.duration = totalDuration; 53 | opacityAnimation.cumulative = YES; 54 | opacityAnimation.repeatCount = 1; 55 | opacityAnimation.removedOnCompletion = NO; 56 | opacityAnimation.fillMode = kCAFillModeBoth; 57 | opacityAnimation.values = [NSArray arrayWithObjects: 58 | [NSNumber numberWithFloat:0.2], 59 | [NSNumber numberWithFloat:0.92], 60 | [NSNumber numberWithFloat:0.92], 61 | [NSNumber numberWithFloat:0.1], nil]; 62 | 63 | opacityAnimation.keyTimes = [NSArray arrayWithObjects: 64 | [NSNumber numberWithFloat:0.0f], 65 | [NSNumber numberWithFloat:0.08f], 66 | [NSNumber numberWithFloat:0.92f], 67 | [NSNumber numberWithFloat:1.0f], nil]; 68 | 69 | opacityAnimation.timingFunctions = [NSArray arrayWithObjects: 70 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn], 71 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], 72 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], nil]; 73 | 74 | 75 | CAKeyframeAnimation* scaleAnimation =[CAKeyframeAnimation animationWithKeyPath:@"transform.scale"]; 76 | scaleAnimation.duration = totalDuration; 77 | scaleAnimation.cumulative = YES; 78 | scaleAnimation.repeatCount = 1; 79 | scaleAnimation.removedOnCompletion = NO; 80 | scaleAnimation.fillMode = kCAFillModeForwards; 81 | scaleAnimation.values = [NSArray arrayWithObjects: 82 | [NSNumber numberWithFloat:self.animationTopScale], 83 | [NSNumber numberWithFloat:1.0f], 84 | [NSNumber numberWithFloat:1.0f], 85 | [NSNumber numberWithFloat:self.animationTopScale], 86 | nil]; 87 | 88 | scaleAnimation.keyTimes = [NSArray arrayWithObjects: 89 | [NSNumber numberWithFloat:0.0f], 90 | [NSNumber numberWithFloat:0.085f], 91 | [NSNumber numberWithFloat:0.92f], 92 | [NSNumber numberWithFloat:1.0f], nil]; 93 | 94 | scaleAnimation.timingFunctions = [NSArray arrayWithObjects: 95 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn], 96 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], 97 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], nil]; 98 | 99 | 100 | 101 | CAAnimationGroup *group = [CAAnimationGroup animation]; 102 | group.duration = totalDuration; 103 | group.delegate = self; 104 | group.animations = [NSArray arrayWithObjects:opacityAnimation,scaleAnimation, nil]; 105 | [self.layer addAnimation:group forKey:@"group"]; 106 | 107 | } 108 | 109 | 110 | - (id)initWithMsg:(NSString*)_msg{ 111 | 112 | if (self = [super init]) { 113 | 114 | self.msg = _msg; 115 | self.leftMargin = 20; 116 | 117 | self.topMargin = 10; 118 | self.totalDuration = 1.2f; 119 | 120 | self.animationTopScale = 1.2; 121 | self.animationLeftScale = 1.2; 122 | 123 | msgFont = [UIFont systemFontOfSize:14.0f]; 124 | CGSize textSize = [self getSizeFromString:msg]; 125 | 126 | self.bounds = CGRectMake(0, 0, 160, 50); 127 | self.labelText = [[UILabel alloc] init]; 128 | labelText.text = _msg; 129 | labelText.numberOfLines = 0; 130 | labelText.font = msgFont; 131 | labelText.backgroundColor = [UIColor clearColor]; 132 | labelText.textColor = [UIColor whiteColor]; 133 | labelText.textAlignment = NSTextAlignmentCenter; 134 | [labelText setFrame:CGRectMake((160 - textSize.width) / 2, 18,textSize.width, textSize.height)]; 135 | [self addSubview:labelText]; 136 | self.layer.cornerRadius = 10; 137 | 138 | } 139 | return self; 140 | } 141 | 142 | + (UIWindow *) getUnhiddenFrontWindowOfApplication{ 143 | 144 | NSArray *windows = [[UIApplication sharedApplication] windows]; 145 | NSInteger windowCnt = [windows count]; 146 | for (int i = windowCnt - 1; i >= 0; i--) { 147 | UIWindow* window = [windows objectAtIndex:i]; 148 | if (FALSE == window.hidden) { 149 | //定制:防止产生bar提示,用的是新增window,排除这个window 150 | if (window.frame.size.height > 50.0f) { 151 | return window; 152 | } 153 | } 154 | } 155 | return NULL; 156 | } 157 | 158 | + (UIWindow*)getWindow{ 159 | 160 | UIWindow* window = [UIApplication sharedApplication].keyWindow; 161 | if (!window) { 162 | window = [[UIApplication sharedApplication].windows objectAtIndex:0]; 163 | } 164 | return window; 165 | } 166 | 167 | - (CGSize)getSizeFromString:(NSString*)_theString{ 168 | 169 | UIFont *theFont = msgFont; 170 | CGSize size = CGSizeMake(160, 2000); 171 | CGSize tempSize = [_theString sizeWithFont:theFont constrainedToSize:size lineBreakMode:NSLineBreakByWordWrapping]; 172 | return tempSize; 173 | } 174 | 175 | 176 | @end 177 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_ListView.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_ListView.h 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/2/15. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "E_CommonManager.h" 11 | #import "E_Mark.h" 12 | 13 | @protocol E_ListViewDelegate 14 | 15 | - (void)clickMark:(E_Mark *)eMark; 16 | - (void)clickChapter:(NSInteger)chaperIndex; 17 | - (void)removeE_ListView; 18 | 19 | @end 20 | 21 | @interface E_ListView : UIView{ 22 | 23 | UISegmentedControl *_segmentControl; 24 | NSInteger dataCount; 25 | NSMutableArray *_dataSource; 26 | CGFloat _panStartX; 27 | BOOL _isMenu; 28 | BOOL _isMark; 29 | BOOL _isNote; 30 | 31 | } 32 | @property (nonatomic,assign)iddelegate; 33 | 34 | @property (nonatomic,strong)UITableView *listView; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_ListView.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_ListView.m 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/2/15. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "E_ListView.h" 10 | #import "E_ReaderDataSource.h" 11 | #import "E_MarkTableViewCell.h" 12 | 13 | 14 | @implementation E_ListView 15 | 16 | - (id)initWithFrame:(CGRect)frame{ 17 | 18 | if (self = [super initWithFrame:frame]) { 19 | 20 | self.userInteractionEnabled = YES; 21 | self.backgroundColor = [UIColor colorWithRed:240/255.0 green:239/255.0 blue:234/255.0 alpha:1.0]; 22 | _dataSource = [[NSMutableArray alloc] initWithCapacity:0]; 23 | dataCount = [E_ReaderDataSource shareInstance].totalChapter; 24 | [self configListView]; 25 | 26 | UIPanGestureRecognizer *panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panEListView:)]; 27 | [self addGestureRecognizer:panGes]; 28 | 29 | } 30 | return self; 31 | } 32 | 33 | - (void)panEListView:(UIPanGestureRecognizer *)recongnizer{ 34 | CGPoint touchPoint = [recongnizer locationInView:self]; 35 | switch (recongnizer.state) { 36 | case UIGestureRecognizerStateBegan:{ 37 | _panStartX = touchPoint.x; 38 | } 39 | break; 40 | 41 | case UIGestureRecognizerStateChanged:{ 42 | CGFloat offSetX = touchPoint.x - _panStartX; 43 | CGRect newFrame = self.frame; 44 | //NSLog(@"offSetX == %f",offSetX); 45 | newFrame.origin.x += offSetX; 46 | if (newFrame.origin.x >= 0){//试图向上滑动 阻止 47 | 48 | newFrame.origin.x = 0; 49 | self.frame = newFrame; 50 | return; 51 | }else{ 52 | self.frame = newFrame; 53 | } 54 | 55 | 56 | } 57 | 58 | break; 59 | 60 | case UIGestureRecognizerStateEnded:{ 61 | 62 | float duringTime = (self.frame.size.width + self.frame.origin.x)/self.frame.size.width * 0.25; 63 | if (self.frame.origin.x < 0) { 64 | [UIView animateWithDuration:duringTime animations:^{ 65 | self.frame = CGRectMake(-self.frame.size.width , 0, self.frame.size.width, self.frame.size.height); 66 | } completion:^(BOOL finished) { 67 | [_delegate removeE_ListView]; 68 | }]; 69 | 70 | } 71 | } 72 | break; 73 | 74 | case UIGestureRecognizerStateCancelled: 75 | 76 | break; 77 | 78 | default: 79 | break; 80 | } 81 | 82 | 83 | } 84 | 85 | 86 | 87 | - (void)configListView{ 88 | 89 | _isMenu = YES; 90 | _isMark = NO; 91 | _isNote = NO; 92 | 93 | [self configListViewHeader]; 94 | 95 | _listView = [[UITableView alloc] initWithFrame:CGRectMake(0, 80, self.frame.size.width, self.frame.size.height - 80 - 60)]; 96 | _listView.delegate = self; 97 | _listView.dataSource = self; 98 | _listView.backgroundColor = [UIColor clearColor]; 99 | [self addSubview:_listView]; 100 | 101 | UIButton *otherBtn = [UIButton buttonWithType:0]; 102 | otherBtn.frame = CGRectMake(70, self.frame.size.height - 40, self.frame.size.width - 140, 20); 103 | otherBtn.layer.borderWidth = 1.0; 104 | otherBtn.layer.cornerRadius = 2.0; 105 | otherBtn.titleLabel.font = [UIFont systemFontOfSize:16]; 106 | [otherBtn setTitleColor:[UIColor colorWithRed:233/255.0 green:64/255.0 blue:64/255.0 alpha:1.0] forState:0]; 107 | [otherBtn setTitle:@"备用按钮" forState:0]; 108 | otherBtn.layer.borderColor = [UIColor colorWithRed:233/255.0 green:64/255.0 blue:64/255.0 alpha:1.0].CGColor; 109 | [self addSubview:otherBtn]; 110 | 111 | } 112 | 113 | - (void)configListViewHeader{ 114 | 115 | NSArray *segmentedArray = @[@"目录",@"书签"]; 116 | _segmentControl = [[UISegmentedControl alloc] initWithItems:segmentedArray]; 117 | _segmentControl.frame = CGRectMake(15, 30, self.bounds.size.width - 30 , 40); 118 | _segmentControl.selectedSegmentIndex = 0; 119 | _segmentControl.tintColor = [UIColor colorWithRed:233/255.0 green:64/255.0 blue:64/255.0 alpha:1.0]; 120 | [self addSubview:_segmentControl]; 121 | [_segmentControl addTarget:self action:@selector(segmentAction:) forControlEvents:UIControlEventValueChanged]; 122 | NSDictionary *dict = [NSDictionary dictionaryWithObject:[UIFont systemFontOfSize:17] forKey:NSFontAttributeName]; 123 | [_segmentControl setTitleTextAttributes:dict forState:0]; 124 | 125 | } 126 | 127 | - (void)segmentAction:(UISegmentedControl *)sender{ 128 | 129 | NSInteger index = sender.selectedSegmentIndex; 130 | switch (index) { 131 | case 0:{ 132 | _isMenu = YES; 133 | _isMark = NO; 134 | _isNote = NO; 135 | dataCount = [E_ReaderDataSource shareInstance].totalChapter; 136 | [_listView reloadData]; 137 | } 138 | break; 139 | case 1:{ 140 | _isMenu = NO; 141 | _isMark = YES; 142 | _isNote = NO; 143 | _dataSource = [E_CommonManager Manager_getMark]; 144 | [_listView reloadData]; 145 | } 146 | break; 147 | // case 2:{ 148 | // _isMenu = NO; 149 | // _isMark = NO; 150 | // _isNote = YES; 151 | // 152 | // } 153 | // 154 | // break; 155 | 156 | default: 157 | break; 158 | } 159 | } 160 | 161 | 162 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 163 | 164 | if (_isMark) { 165 | return 100; 166 | } 167 | 168 | return 50; 169 | } 170 | 171 | 172 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 173 | 174 | if (_isMark) { 175 | return _dataSource.count; 176 | } 177 | return dataCount; 178 | 179 | } 180 | 181 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 182 | 183 | if (_isMark) { 184 | [_delegate clickMark:[_dataSource objectAtIndex:indexPath.row]]; 185 | return; 186 | } 187 | 188 | [_delegate clickChapter:indexPath.row]; 189 | 190 | } 191 | 192 | 193 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 194 | 195 | if (_isMenu == YES) { 196 | static NSString *cellStr = @"menuCell"; 197 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellStr]; 198 | if (cell == nil) { 199 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellStr]; 200 | } 201 | cell.backgroundColor = [UIColor clearColor]; 202 | cell.textLabel.text = [NSString stringWithFormat:@"第%ld章",indexPath.row + 1]; 203 | return cell; 204 | 205 | }else if(_isMark){ 206 | 207 | static NSString *cellStr = @"markCell"; 208 | E_MarkTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellStr]; 209 | if (cell == nil) { 210 | cell = [[E_MarkTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellStr]; 211 | } 212 | cell.backgroundColor = [UIColor clearColor]; 213 | cell.chapterLbl.text = [NSString stringWithFormat:@"第%@章",[(E_Mark *)[_dataSource objectAtIndex:indexPath.row] markChapter]]; 214 | cell.timeLbl.text = [(E_Mark *)[_dataSource objectAtIndex:indexPath.row] markTime]; 215 | cell.contentLbl.text = [(E_Mark *)[_dataSource objectAtIndex:indexPath.row] markContent]; 216 | return cell; 217 | 218 | }else{ 219 | static NSString *cellStr = @"noteCell"; 220 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellStr]; 221 | if (cell == nil) { 222 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellStr]; 223 | } 224 | cell.backgroundColor = [UIColor clearColor]; 225 | cell.textLabel.text = [NSString stringWithFormat:@"第%ld章",indexPath.row + 1]; 226 | return cell; 227 | 228 | } 229 | return nil; 230 | } 231 | 232 | /* 233 | // Only override drawRect: if you perform custom drawing. 234 | // An empty implementation adversely affects performance during animation. 235 | - (void)drawRect:(CGRect)rect { 236 | // Drawing code 237 | } 238 | */ 239 | 240 | @end 241 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_MagnifiterView.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_MagnifiterView.h 3 | // WFReader 4 | // 5 | // Created by 阿虎 on 15/1/29. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | * 放大镜类 13 | */ 14 | @interface E_MagnifiterView : UIView 15 | 16 | @property (weak, nonatomic) UIView *viewToMagnify; 17 | @property (nonatomic) CGPoint touchPoint; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_MagnifiterView.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_MagnifiterView.m 3 | // WFReader 4 | // 5 | // Created by 阿虎 on 15/1/29. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "E_MagnifiterView.h" 10 | 11 | @implementation E_MagnifiterView 12 | 13 | - (id)initWithFrame:(CGRect)frame { 14 | 15 | if (self = [super initWithFrame:CGRectMake(0, 0, 80, 80)]) { 16 | self.layer.borderColor = [[UIColor lightGrayColor] CGColor]; 17 | self.layer.borderWidth = 1; 18 | self.layer.cornerRadius = 40; 19 | self.layer.masksToBounds = YES; 20 | } 21 | return self; 22 | } 23 | 24 | - (void)setTouchPoint:(CGPoint)touchPoint { 25 | 26 | _touchPoint = touchPoint; 27 | self.center = CGPointMake(touchPoint.x, touchPoint.y - 70); 28 | [self setNeedsDisplay]; 29 | } 30 | 31 | - (void)drawRect:(CGRect)rect { 32 | 33 | CGContextRef context = UIGraphicsGetCurrentContext(); 34 | CGContextTranslateCTM(context, self.frame.size.width * 0.5,self.frame.size.height * 0.5); 35 | CGContextScaleCTM(context, 1.5, 1.5); 36 | CGContextTranslateCTM(context, -1 * (_touchPoint.x), -1 * (_touchPoint.y)); 37 | [self.viewToMagnify.layer renderInContext:context]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_MarkTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_MarkTableViewCell.h 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/3/2. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface E_MarkTableViewCell : UITableViewCell 12 | 13 | @property (nonatomic,strong) UILabel *chapterLbl; 14 | @property (nonatomic,strong) UILabel *timeLbl; 15 | @property (nonatomic,strong) UILabel *contentLbl; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_MarkTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_MarkTableViewCell.m 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/3/2. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "E_MarkTableViewCell.h" 10 | #import "E_ContantFile.h" 11 | 12 | @implementation E_MarkTableViewCell 13 | 14 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 15 | { 16 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 17 | if (self) { 18 | // Initialization code 19 | _chapterLbl = [[UILabel alloc] initWithFrame:CGRectMake(20, 5, 200, 20)]; 20 | _chapterLbl.textColor = [UIColor redColor]; 21 | _chapterLbl.font = [UIFont systemFontOfSize:15]; 22 | [self.contentView addSubview:_chapterLbl]; 23 | 24 | 25 | _timeLbl = [[UILabel alloc] initWithFrame:CGRectMake(kScreenW*3/4 - 125, 5, 110, 20)]; 26 | _timeLbl.textColor = [UIColor redColor]; 27 | _timeLbl.textAlignment = NSTextAlignmentRight; 28 | _timeLbl.font = [UIFont systemFontOfSize:14]; 29 | [self.contentView addSubview:_timeLbl]; 30 | 31 | _contentLbl = [[UILabel alloc] initWithFrame:CGRectMake(25, 28, kScreenW*3/4 - 50, 60)]; 32 | _contentLbl.numberOfLines = 3; 33 | _contentLbl.font = [UIFont systemFontOfSize:16]; 34 | _contentLbl.textColor = [UIColor blackColor]; 35 | [self.contentView addSubview:_contentLbl]; 36 | } 37 | return self; 38 | } 39 | 40 | - (void)awakeFromNib 41 | { 42 | // Initialization code 43 | } 44 | 45 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated 46 | { 47 | [super setSelected:selected animated:animated]; 48 | 49 | // Configure the view for the selected state 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_ReaderView.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_ReaderView.h 3 | // E_Reader 4 | // 5 | // Created by 阿虎 on 14-8-8. 6 | // Copyright (c) 2014年 tiger. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | #import "E_MagnifiterView.h" 12 | #import "E_CursorView.h" 13 | 14 | /** 15 | * 显示文本类 16 | */ 17 | 18 | @protocol E_ReaderViewDelegate 19 | 20 | - (void)shutOffGesture:(BOOL)yesOrNo; 21 | - (void)hideSettingToolBar; 22 | - (void)ciBa:(NSString *)ciBasString; 23 | 24 | @end 25 | 26 | @interface E_ReaderView : UIView 27 | 28 | @property(unsafe_unretained, nonatomic)NSUInteger font; 29 | @property(copy, nonatomic)NSString *text; 30 | 31 | @property (strong, nonatomic) E_CursorView *leftCursor; 32 | @property (strong, nonatomic) E_CursorView *rightCursor; 33 | @property (strong, nonatomic) E_MagnifiterView *magnifierView; 34 | @property (assign, nonatomic) iddelegate; 35 | @property (strong, nonatomic) UIImage *magnifiterImage; 36 | @property (copy , nonatomic) NSString *keyWord; 37 | 38 | - (void)render; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_SearchTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_SearchTableViewCell.h 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/2/28. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface E_SearchTableViewCell : UITableViewCell 12 | 13 | @property (nonatomic,strong) UILabel *chapterLbl; 14 | 15 | @property (nonatomic,strong) UILabel *contentLbl; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_SearchTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_SearchTableViewCell.m 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/2/28. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "E_SearchTableViewCell.h" 10 | #import "E_ContantFile.h" 11 | 12 | @implementation E_SearchTableViewCell 13 | 14 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 15 | { 16 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 17 | if (self) { 18 | 19 | _chapterLbl = [[UILabel alloc] initWithFrame:CGRectMake(20, 5, 200, 20)]; 20 | _chapterLbl.textColor = [UIColor grayColor]; 21 | _chapterLbl.font = [UIFont systemFontOfSize:15]; 22 | [self.contentView addSubview:_chapterLbl]; 23 | 24 | 25 | _contentLbl = [[UILabel alloc] initWithFrame:CGRectMake(20, 29, kScreenW - 40, 24)]; 26 | _contentLbl.textColor = [UIColor blackColor]; 27 | _contentLbl.lineBreakMode = NSLineBreakByTruncatingMiddle; 28 | _contentLbl.font = [UIFont systemFontOfSize:17]; 29 | [self.contentView addSubview:_contentLbl]; 30 | 31 | } 32 | return self; 33 | } 34 | 35 | 36 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 37 | [super setSelected:selected animated:animated]; 38 | 39 | // Configure the view for the selected state 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_SettingBottomBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_SettingBottomBar.h 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/2/13. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | /** 13 | * 底部设置条 14 | */ 15 | @protocol E_SettingBottomBarDelegate 16 | 17 | - (void)shutOffPageViewControllerGesture:(BOOL)yesOrNo; 18 | - (void)fontSizeChanged:(int)fontSize;//改变字号 19 | - (void)callDrawerView;//侧边栏 20 | - (void)turnToNextChapter;//下一章 21 | - (void)turnToPreChapter;//上一章 22 | - (void)sliderToChapterPage:(NSInteger)chapterIndex; 23 | - (void)themeButtonAction:(id)myself themeIndex:(NSInteger)theme; 24 | - (void)callCommentView; 25 | 26 | 27 | @end 28 | 29 | 30 | @interface E_SettingBottomBar : UIView 31 | 32 | @property (nonatomic,strong) UIButton *smallFont; 33 | @property (nonatomic,strong) UIButton *bigFont; 34 | @property (nonatomic,assign) iddelegate; 35 | @property (nonatomic,assign) NSInteger chapterTotalPage; 36 | @property (nonatomic,assign) NSInteger chapterCurrentPage; 37 | @property (nonatomic,assign) NSInteger currentChapter; 38 | 39 | - (void)changeSliderRatioNum:(float)percentNum; 40 | 41 | - (void)showToolBar; 42 | 43 | - (void)hideToolBar; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_SettingBottomBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_SettingBottomBar.m 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/2/13. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "E_SettingBottomBar.h" 10 | #import "E_ContantFile.h" 11 | #import "E_CommonManager.h" 12 | #import "ILSlider.h" 13 | #import "E_HUDView.h" 14 | 15 | #define MAX_FONT_SIZE 27 16 | #define MIN_FONT_SIZE 17 17 | #define MIN_TIPS @"字体已到最小" 18 | #define MAX_TIPS @"字体已到最大" 19 | 20 | @implementation E_SettingBottomBar 21 | { 22 | ILSlider *ilSlider; 23 | UILabel *showLbl; 24 | BOOL isFirstShow; 25 | } 26 | 27 | - (id)initWithFrame:(CGRect)frame{ 28 | 29 | self = [super initWithFrame:frame]; 30 | if (self) { 31 | self.backgroundColor = [UIColor colorWithRed:59/255.0 green:59/255.0 blue:59/255.0 alpha:1.0]; 32 | isFirstShow = YES; 33 | [self configUI]; 34 | } 35 | return self; 36 | 37 | } 38 | 39 | 40 | - (void)configUI{ 41 | 42 | UIButton *menuBtn = [UIButton buttonWithType:0]; 43 | [menuBtn setImage:[UIImage imageNamed:@"reader_cover.png"] forState:0]; 44 | [menuBtn addTarget:self action:@selector(showDrawerView) forControlEvents:UIControlEventTouchUpInside]; 45 | menuBtn.frame = CGRectMake(10, self.frame.size.height - 54, 60, 44); 46 | [self addSubview:menuBtn]; 47 | 48 | UIButton *commentBtn = [UIButton buttonWithType:0]; 49 | [commentBtn setImage:[UIImage imageNamed:@"reader_comments.png"] forState:0]; 50 | [commentBtn addTarget:self action:@selector(showCommentView) forControlEvents:UIControlEventTouchUpInside]; 51 | commentBtn.frame = CGRectMake(self.frame.size.width - 70, self.frame.size.height - 54, 60, 44); 52 | [self addSubview:commentBtn]; 53 | 54 | 55 | _bigFont = [UIButton buttonWithType:0]; 56 | _bigFont.frame = CGRectMake(110 + (self.frame.size.width - 200)/2, self.frame.size.height - 54, (self.frame.size.width - 200)/2, 44); 57 | [_bigFont setImage:[UIImage imageNamed:@"reader_font_increase.png"] forState:0]; 58 | _bigFont.backgroundColor = [UIColor clearColor]; 59 | 60 | [_bigFont addTarget:self action:@selector(changeBig) forControlEvents:UIControlEventTouchUpInside]; 61 | 62 | [self addSubview:_bigFont]; 63 | 64 | _smallFont = [UIButton buttonWithType:0]; 65 | 66 | [_smallFont setImage:[UIImage imageNamed:@"reader_font_decrease.png"] forState:0]; 67 | [_smallFont addTarget:self action:@selector(changeSmall) forControlEvents:UIControlEventTouchUpInside]; 68 | _smallFont.frame = CGRectMake(90, self.frame.size.height - 54, (self.frame.size.width - 200)/2, 44); 69 | [self addSubview:_smallFont]; 70 | 71 | 72 | showLbl = [[UILabel alloc] initWithFrame:CGRectMake(70, self.frame.size.height - kBottomBarH - 70, self.frame.size.width - 140 , 60)]; 73 | showLbl.backgroundColor = [UIColor colorWithRed:59/255.0 green:59/255.0 blue:59/255.0 alpha:1.0]; 74 | [showLbl setTextColor:[UIColor whiteColor]]; 75 | showLbl.font = [UIFont systemFontOfSize:18]; 76 | showLbl.textAlignment = NSTextAlignmentCenter; 77 | showLbl.numberOfLines = 2; 78 | showLbl.alpha = 0.7; 79 | showLbl.hidden = YES; 80 | [self addSubview:showLbl]; 81 | 82 | ilSlider = [[ILSlider alloc] initWithFrame:CGRectMake(50, self.frame.size.height - 54 - 40 - 50 , self.frame.size.width - 100, 40) direction:ILSliderDirectionHorizonal]; 83 | ilSlider.maxValue = 3; 84 | ilSlider.minValue = 1; 85 | 86 | [ilSlider sliderChangeBlock:^(CGFloat value) { 87 | 88 | if (!isFirstShow) { 89 | showLbl.hidden = NO; 90 | double percent = (value - ilSlider.minValue)/(ilSlider.maxValue - ilSlider.minValue); 91 | showLbl.text = [NSString stringWithFormat:@"第%ld章\n%.1f%@",_currentChapter,percent*100,@"%"]; 92 | } 93 | isFirstShow = NO; 94 | 95 | 96 | }]; 97 | 98 | [ilSlider sliderTouchEndBlock:^(CGFloat value) { 99 | 100 | showLbl.hidden = YES; 101 | float percent = (value - ilSlider.minValue)/(ilSlider.maxValue - ilSlider.minValue); 102 | NSInteger page = (NSInteger)round(percent * _chapterTotalPage); 103 | if (page == 0) { 104 | page = 1; 105 | } 106 | [_delegate sliderToChapterPage:page]; 107 | }]; 108 | 109 | [self addSubview:ilSlider]; 110 | 111 | //前一章 按钮 112 | UIButton *preChapterBtn = [UIButton buttonWithType:0]; 113 | preChapterBtn.frame = CGRectMake(5, self.frame.size.height - 54 - 40 - 50, 40, 40); 114 | preChapterBtn.backgroundColor = [UIColor clearColor]; 115 | [preChapterBtn setTitle:@"上一章" forState:0]; 116 | [preChapterBtn addTarget:self action:@selector(goToPreChapter) forControlEvents:UIControlEventTouchUpInside]; 117 | preChapterBtn.titleLabel.font = [UIFont systemFontOfSize:12.0]; 118 | [preChapterBtn setTitleColor:[UIColor whiteColor] forState:0]; 119 | [self addSubview:preChapterBtn]; 120 | 121 | //后一章 按钮 122 | UIButton *nextChapterBtn = [UIButton buttonWithType:0]; 123 | nextChapterBtn.frame = CGRectMake(self.frame.size.width - 45, self.frame.size.height - 54 - 40 - 50, 40, 40); 124 | nextChapterBtn.backgroundColor = [UIColor clearColor]; 125 | [nextChapterBtn setTitle:@"下一章" forState:0]; 126 | [nextChapterBtn addTarget:self action:@selector(goToNextChapter) forControlEvents:UIControlEventTouchUpInside]; 127 | nextChapterBtn.titleLabel.font = [UIFont systemFontOfSize:12.0]; 128 | [nextChapterBtn setTitleColor:[UIColor whiteColor] forState:0]; 129 | [self addSubview:nextChapterBtn]; 130 | 131 | //主题颜色滚动条 132 | UIScrollView *themeScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(30, self.frame.size.height - 54 - 50 , self.frame.size.width - 60, 40)]; 133 | themeScroll.backgroundColor = [UIColor clearColor]; 134 | [self addSubview:themeScroll]; 135 | 136 | NSInteger themeID = [E_CommonManager Manager_getReadTheme]; 137 | 138 | for (int i = 1; i <= 4; i ++) { 139 | 140 | UIButton * themeButton = [UIButton buttonWithType:UIButtonTypeCustom]; 141 | themeButton.layer.cornerRadius = 2.0f; 142 | themeButton.autoresizingMask = UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleBottomMargin; 143 | themeButton.frame = CGRectMake(0 + 36*i + (self.frame.size.width - 60 - 6 *36)*(i - 1)/3, 2, 36, 36); 144 | 145 | if (i == 1) { 146 | [themeButton setBackgroundColor:[UIColor whiteColor]]; 147 | 148 | }else{ 149 | [themeButton setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:@"reader_bg%d.png",i]] forState:UIControlStateNormal]; 150 | [themeButton setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:@"reader_bg%d.png",i]] forState:UIControlStateSelected]; 151 | } 152 | 153 | if (i == themeID) { 154 | themeButton.selected = YES; 155 | } 156 | 157 | [themeButton setImage:[UIImage imageNamed:[NSString stringWithFormat:@"reader_bg_s.png"]] forState:UIControlStateSelected]; 158 | [themeButton setImage:[UIImage imageNamed:[NSString stringWithFormat:@"reader_bg_s.png"]] forState:UIControlStateHighlighted]; 159 | themeButton.tag = 7000+i; 160 | [themeButton addTarget:self action:@selector(themeButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; 161 | [themeScroll addSubview:themeButton]; 162 | 163 | } 164 | } 165 | 166 | 167 | - (void)themeButtonPressed:(UIButton *)sender{ 168 | 169 | [sender setSelected:YES]; 170 | 171 | for (int i = 1; i <= 5; i++) { 172 | UIButton * button = (UIButton *)[self viewWithTag:7000+i]; 173 | if (button.tag != sender.tag) { 174 | [button setSelected:NO]; 175 | } 176 | } 177 | 178 | [_delegate themeButtonAction:self themeIndex:sender.tag-7000]; 179 | [E_CommonManager saveCurrentThemeID:sender.tag-7000]; 180 | } 181 | 182 | - (void)goToNextChapter{ 183 | 184 | [_delegate turnToNextChapter]; 185 | 186 | } 187 | 188 | - (void)goToPreChapter{ 189 | 190 | [_delegate turnToPreChapter]; 191 | 192 | } 193 | 194 | #pragma mark - 小 195 | - (void)changeSmall 196 | { 197 | NSUInteger fontSize = [E_CommonManager fontSize]; 198 | if (fontSize <= MIN_FONT_SIZE) { 199 | [E_HUDView showMsg:MIN_TIPS inView:self]; 200 | return; 201 | } 202 | fontSize--; 203 | [E_CommonManager saveFontSize:fontSize]; 204 | [self updateFontButtons]; 205 | [_delegate fontSizeChanged:(int)fontSize]; 206 | [_delegate shutOffPageViewControllerGesture:NO]; 207 | } 208 | 209 | - (void)changeBig 210 | { 211 | NSUInteger fontSize = [E_CommonManager fontSize]; 212 | if (fontSize >= MAX_FONT_SIZE) { 213 | [E_HUDView showMsg:MAX_TIPS inView:self]; 214 | return; 215 | } 216 | fontSize++; 217 | [E_CommonManager saveFontSize:fontSize]; 218 | [self updateFontButtons]; 219 | [_delegate fontSizeChanged:(int)fontSize]; 220 | [_delegate shutOffPageViewControllerGesture:NO]; 221 | 222 | } 223 | 224 | 225 | - (void)updateFontButtons 226 | { 227 | NSUInteger fontSize = [E_CommonManager fontSize]; 228 | _bigFont.enabled = fontSize < MAX_FONT_SIZE; 229 | _smallFont.enabled = fontSize > MIN_FONT_SIZE; 230 | } 231 | 232 | - (void)showDrawerView{ 233 | 234 | [_delegate callDrawerView]; 235 | 236 | } 237 | 238 | - (void)changeSliderRatioNum:(float)percentNum{ 239 | 240 | ilSlider.ratioNum = percentNum; 241 | 242 | } 243 | 244 | - (void)showCommentView{ 245 | 246 | [_delegate callCommentView]; 247 | } 248 | 249 | 250 | 251 | 252 | - (void)showToolBar{ 253 | 254 | CGRect newFrame = self.frame; 255 | newFrame.origin.y -= kBottomBarH; 256 | float currentPage = [[NSString stringWithFormat:@"%ld",_chapterCurrentPage] floatValue] + 1; 257 | float totalPage = [[NSString stringWithFormat:@"%ld",_chapterTotalPage] floatValue]; 258 | if (currentPage == 1) {//强行放置头部 259 | ilSlider.ratioNum = 0; 260 | }else{ 261 | ilSlider.ratioNum = currentPage/totalPage; 262 | } 263 | 264 | [UIView animateWithDuration:0.18 animations:^{ 265 | self.frame = newFrame; 266 | } completion:^(BOOL finished) { 267 | 268 | }]; 269 | 270 | 271 | } 272 | 273 | - (void)hideToolBar{ 274 | 275 | CGRect newFrame = self.frame; 276 | newFrame.origin.y += kBottomBarH; 277 | [UIView animateWithDuration:0.18 animations:^{ 278 | self.frame = newFrame; 279 | } completion:^(BOOL finished) { 280 | [self removeFromSuperview]; 281 | 282 | 283 | }]; 284 | 285 | } 286 | /* 287 | // Only override drawRect: if you perform custom drawing. 288 | // An empty implementation adversely affects performance during animation. 289 | - (void)drawRect:(CGRect)rect { 290 | // Drawing code 291 | } 292 | */ 293 | 294 | @end 295 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_SettingTopBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_SettingBar.h 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/2/13. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | /** 11 | * 顶部设置条 12 | */ 13 | 14 | @protocol E_SettingTopBarDelegate 15 | 16 | - (void)goBack;//退出 17 | - (void)showMultifunctionButton; 18 | 19 | @end 20 | 21 | @interface E_SettingTopBar : UIView 22 | 23 | @property(nonatomic,assign)iddelegate; 24 | 25 | - (void)showToolBar; 26 | 27 | - (void)hideToolBar; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /WFReader/EReader/View/E_SettingTopBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_SettingBar.m 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/2/13. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "E_SettingTopBar.h" 10 | 11 | @implementation E_SettingTopBar 12 | 13 | - (id)initWithFrame:(CGRect)frame{ 14 | self = [super initWithFrame:frame]; 15 | if (self) { 16 | self.backgroundColor = [UIColor colorWithRed:59/255.0 green:59/255.0 blue:59/255.0 alpha:1.0]; 17 | [self configUI]; 18 | } 19 | return self; 20 | 21 | } 22 | 23 | 24 | - (void)configUI{ 25 | 26 | UIButton *backBtn = [UIButton buttonWithType:0]; 27 | backBtn.frame = CGRectMake(10, 20, 60, 44); 28 | [backBtn setTitle:@" 返回" forState:0]; 29 | backBtn.backgroundColor = [UIColor clearColor]; 30 | [backBtn setTitleColor:[UIColor whiteColor] forState:0]; 31 | [backBtn addTarget:self action:@selector(backToFront) forControlEvents:UIControlEventTouchUpInside]; 32 | [self addSubview:backBtn]; 33 | 34 | UIButton *multifunctionBtn = [UIButton buttonWithType:0]; 35 | multifunctionBtn.frame = CGRectMake(self.frame.size.width - 10 - 60, 20, 60, 44); 36 | [multifunctionBtn setImage:[UIImage imageNamed:@"reader_more.png"] forState:0]; 37 | [multifunctionBtn setTitleColor:[UIColor whiteColor] forState:0]; 38 | [multifunctionBtn addTarget:self action:@selector(multifunction) forControlEvents:UIControlEventTouchUpInside]; 39 | [self addSubview:multifunctionBtn]; 40 | 41 | 42 | } 43 | 44 | 45 | - (void)backToFront{ 46 | 47 | [_delegate goBack]; 48 | } 49 | 50 | - (void)multifunction{ 51 | 52 | [_delegate showMultifunctionButton]; 53 | 54 | } 55 | 56 | 57 | - (void)showToolBar{ 58 | 59 | CGRect newFrame = self.frame; 60 | newFrame.origin.y += 64; 61 | [UIView animateWithDuration:0.18 animations:^{ 62 | self.frame = newFrame; 63 | } completion:^(BOOL finished) { 64 | 65 | }]; 66 | 67 | 68 | } 69 | 70 | - (void)hideToolBar{ 71 | 72 | CGRect newFrame = self.frame; 73 | newFrame.origin.y -= 64; 74 | [UIView animateWithDuration:0.18 animations:^{ 75 | self.frame = newFrame; 76 | } completion:^(BOOL finished) { 77 | [self removeFromSuperview]; 78 | 79 | 80 | }]; 81 | 82 | } 83 | /* 84 | // Only override drawRect: if you perform custom drawing. 85 | // An empty implementation adversely affects performance during animation. 86 | - (void)drawRect:(CGRect)rect { 87 | // Drawing code 88 | } 89 | */ 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /WFReader/EReader/View/ILSlider.h: -------------------------------------------------------------------------------- 1 | // 2 | // ILSlider.h 3 | // ILSlider 4 | // 5 | // Created by 吴福虎 on 14-10-17. 6 | // Copyright (c) 2014年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef void(^TouchStateEnd) (CGFloat); 12 | typedef void(^TouchStateChanged) (CGFloat); 13 | 14 | typedef enum { 15 | ILSliderDirectionHorizonal = 0, 16 | ILSliderDirectionVertical = 1 17 | } ILSliderDirection; 18 | 19 | @interface ILSlider : UIControl 20 | 21 | 22 | @property (nonatomic, assign) CGFloat minValue;//最小值 23 | @property (nonatomic, assign) CGFloat maxValue;//最大值 24 | @property (nonatomic, assign) CGFloat value;//滑动值 25 | @property (nonatomic, assign) CGFloat ratioNum;//滑动的比值 26 | 27 | @property (nonatomic, assign) ILSliderDirection direction;//方向 28 | 29 | @property (nonatomic, copy) TouchStateChanged StateChanged; 30 | @property (nonatomic, copy) TouchStateEnd StateEnd; 31 | 32 | 33 | - (id)initWithFrame:(CGRect)frame direction:(ILSliderDirection)direction; 34 | 35 | - (void)sliderChangeBlock:(TouchStateChanged)didChangeBlock; 36 | 37 | - (void)sliderTouchEndBlock:(TouchStateEnd)touchEndBlock; 38 | 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /WFReader/EReader/View/ILSlider.m: -------------------------------------------------------------------------------- 1 | // 2 | // ILSlider.m 3 | // ILSlider 4 | // 5 | // Created by 吴福虎 on 14-10-17. 6 | // Copyright (c) 2014年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "ILSlider.h" 10 | 11 | @interface ILSlider () 12 | 13 | @property (nonatomic, strong) UIColor *lineColor;//整条线的颜色 14 | @property (nonatomic, strong) UIColor *slidedLineColor;//滑动过的线的颜色 15 | @property (nonatomic, strong) UIColor *circleColor;//圆的颜色 16 | 17 | @property (nonatomic, assign) CGFloat lineWidth;//线的宽度 18 | @property (nonatomic, assign) CGFloat circleRadius;//圆的半径 19 | @property (nonatomic, assign) BOOL isSliding;//是否正在滑动 20 | 21 | @end 22 | 23 | @implementation ILSlider 24 | 25 | - (id)initWithFrame:(CGRect)frame direction:(ILSliderDirection)direction{ 26 | self = [super initWithFrame:frame]; 27 | if (self) { 28 | self.backgroundColor = [UIColor clearColor]; 29 | 30 | _minValue = 0; 31 | _maxValue = 1; 32 | 33 | _direction = direction; 34 | _lineColor = [UIColor whiteColor]; 35 | _slidedLineColor = [UIColor redColor]; 36 | _circleColor = [UIColor whiteColor]; 37 | 38 | _ratioNum = 0.0;//缺省为0 39 | _lineWidth = 1; 40 | _circleRadius = 10; 41 | 42 | 43 | } 44 | return self; 45 | 46 | } 47 | 48 | 49 | 50 | - (void)drawRect:(CGRect)rect { 51 | 52 | CGContextRef context = UIGraphicsGetCurrentContext(); 53 | 54 | 55 | //画总体的线 56 | CGContextSetStrokeColorWithColor(context, _lineColor.CGColor);//画笔颜色 57 | CGContextSetLineWidth(context, _lineWidth);//线的宽度 58 | 59 | CGFloat startLineX = (_direction == ILSliderDirectionHorizonal ? _circleRadius : (self.frame.size.width - _lineWidth) / 2); 60 | CGFloat startLineY = (_direction == ILSliderDirectionHorizonal ? (self.frame.size.height - _lineWidth) / 2 : _circleRadius);//起点 61 | 62 | CGFloat endLineX = (_direction == ILSliderDirectionHorizonal ? self.frame.size.width - _circleRadius : (self.frame.size.width - _lineWidth) / 2); 63 | CGFloat endLineY = (_direction == ILSliderDirectionHorizonal ? (self.frame.size.height - _lineWidth) / 2 : self.frame.size.height- _circleRadius);//终点 64 | 65 | CGContextMoveToPoint(context, startLineX, startLineY); 66 | CGContextAddLineToPoint(context, endLineX, endLineY); 67 | CGContextClosePath(context); 68 | CGContextStrokePath(context); 69 | 70 | 71 | //画已滑动进度的线 72 | CGContextSetStrokeColorWithColor(context, _slidedLineColor.CGColor);//画笔颜色 73 | CGContextSetLineWidth(context, _lineWidth);//线的宽度 74 | 75 | CGFloat slidedLineX = (_direction == ILSliderDirectionHorizonal ? MAX(_circleRadius, (_ratioNum * self.frame.size.width - _circleRadius)) : startLineX); 76 | 77 | CGFloat slidedLineY = (_direction == ILSliderDirectionHorizonal ? startLineY : MAX(_circleRadius, (_ratioNum * self.frame.size.height - _circleRadius))); 78 | 79 | CGContextMoveToPoint(context, startLineX, startLineY); 80 | CGContextAddLineToPoint(context, slidedLineX, slidedLineY); 81 | CGContextClosePath(context); 82 | CGContextStrokePath(context); 83 | 84 | //外层圆 85 | CGFloat penWidth = 1.f; 86 | CGContextSetStrokeColorWithColor(context, _circleColor.CGColor);//画笔颜色 87 | CGContextSetLineWidth(context, penWidth);//线的宽度 88 | 89 | CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor);//填充颜色 90 | 91 | CGContextSetShadow(context, CGSizeMake(1, 1), 1.f);//阴影 92 | 93 | CGFloat circleX = (_direction == ILSliderDirectionHorizonal ? MAX(_circleRadius + penWidth, slidedLineX - penWidth ) : startLineX); 94 | CGFloat circleY = (_direction == ILSliderDirectionHorizonal ? startLineY : MAX(_circleRadius + penWidth, slidedLineY - penWidth)); 95 | CGContextAddArc(context, circleX, circleY, _circleRadius, 0, 2 * M_PI, 0); //添加一个圆 96 | CGContextDrawPath(context, kCGPathFillStroke); //绘制路径加填充 97 | 98 | 99 | //内层圆 100 | CGContextSetStrokeColorWithColor(context, nil); 101 | CGContextSetLineWidth(context, 0); 102 | CGContextSetFillColorWithColor(context, _circleColor.CGColor); 103 | CGContextAddArc(context, circleX, circleY, _circleRadius / 2, 0, 2 * M_PI, 0); 104 | CGContextDrawPath(context, kCGPathFillStroke); 105 | 106 | } 107 | 108 | #pragma mark 触摸 109 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 110 | [self updateTouchPoint:touches]; 111 | [self callbackTouchEnd:NO]; 112 | } 113 | 114 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 115 | [self updateTouchPoint:touches]; 116 | [self callbackTouchEnd:NO]; 117 | } 118 | 119 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 120 | [self updateTouchPoint:touches]; 121 | [self callbackTouchEnd:YES]; 122 | } 123 | 124 | - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { 125 | [self updateTouchPoint:touches]; 126 | [self callbackTouchEnd:YES]; 127 | } 128 | 129 | 130 | - (void)updateTouchPoint:(NSSet*)touches { 131 | 132 | CGPoint touchPoint = [[touches anyObject] locationInView:self]; 133 | self.ratioNum = (_direction == ILSliderDirectionHorizonal ? touchPoint.x : touchPoint.y) / (_direction == ILSliderDirectionHorizonal ? self.frame.size.width : self.frame.size.height); 134 | // NSLog(@"_ratioNum == %f",_ratioNum); 135 | } 136 | 137 | - (void)setRatioNum:(CGFloat)ratioNum { 138 | if (_ratioNum != ratioNum) { 139 | _ratioNum = ratioNum; 140 | 141 | self.value = _minValue + ratioNum * (_maxValue - _minValue); 142 | } 143 | // NSLog(@"_value = %f",_value); 144 | } 145 | 146 | - (void)setValue:(CGFloat)value { 147 | 148 | if (value != _value) { 149 | if (value < _minValue) { 150 | _value = _minValue; 151 | return; 152 | } else if (value > _maxValue) { 153 | _value = _maxValue; 154 | return; 155 | } 156 | _value = value; 157 | 158 | [self setNeedsDisplay]; 159 | 160 | if (_StateChanged) { 161 | _StateChanged(value); 162 | } 163 | } 164 | } 165 | 166 | 167 | - (void)sliderChangeBlock:(TouchStateChanged)didChangeBlock{ 168 | 169 | _StateChanged = didChangeBlock; 170 | 171 | } 172 | 173 | - (void)sliderTouchEndBlock:(TouchStateEnd)touchEndBlock{ 174 | 175 | _StateEnd = touchEndBlock; 176 | 177 | } 178 | 179 | 180 | - (void)callbackTouchEnd:(BOOL)isTouchEnd { 181 | 182 | _isSliding = !isTouchEnd; 183 | 184 | if (isTouchEnd == YES) { 185 | _StateEnd(_value); 186 | } 187 | 188 | 189 | } 190 | @end 191 | -------------------------------------------------------------------------------- /WFReader/EReader/ViewController/E_CommentViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_CommentViewController.h 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/2/27. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | /** 11 | * 评论视图控制器 12 | */ 13 | @interface E_CommentViewController : UIViewController 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WFReader/EReader/ViewController/E_CommentViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_CommentViewController.m 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/2/27. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "E_CommentViewController.h" 10 | 11 | @interface E_CommentViewController () 12 | 13 | @end 14 | 15 | @implementation E_CommentViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | self.view.backgroundColor = [UIColor whiteColor]; 20 | 21 | UILabel *titleLbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, 44)]; 22 | [titleLbl setText:@"评论页"]; 23 | titleLbl.font = [UIFont systemFontOfSize:20]; 24 | titleLbl.textAlignment = NSTextAlignmentCenter; 25 | [self.view addSubview:titleLbl]; 26 | 27 | 28 | UIButton *backBtn = [UIButton buttonWithType:0]; 29 | backBtn.frame = CGRectMake(10, 20, 60, 44); 30 | [backBtn setTitle:@" 返回" forState:0]; 31 | backBtn.backgroundColor = [UIColor clearColor]; 32 | [backBtn setTitleColor:[UIColor blackColor] forState:0]; 33 | [backBtn addTarget:self action:@selector(backToFront) forControlEvents:UIControlEventTouchUpInside]; 34 | [self.view addSubview:backBtn]; 35 | 36 | UIButton *clickBtn = [UIButton buttonWithType:0]; 37 | clickBtn.frame = CGRectMake(0, 80, self.view.frame.size.width, 88); 38 | [clickBtn setTitle:@"涉及到富文本排版,参见https://github.com/TigerWf/WFCoretext" forState:0]; 39 | clickBtn.titleLabel.numberOfLines = 2; 40 | clickBtn.backgroundColor = [UIColor clearColor]; 41 | [clickBtn setTitleColor:[UIColor blackColor] forState:0]; 42 | clickBtn.titleLabel.textAlignment = NSTextAlignmentCenter; 43 | [clickBtn addTarget:self action:@selector(clickBtn) forControlEvents:UIControlEventTouchUpInside]; 44 | [self.view addSubview:clickBtn]; 45 | 46 | 47 | 48 | 49 | 50 | // Do any additional setup after loading the view. 51 | } 52 | 53 | 54 | - (void)clickBtn{ 55 | 56 | NSString *urlText = [NSString stringWithFormat:@"https://github.com/TigerWf/WFCoretext"]; 57 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlText]]; 58 | } 59 | 60 | 61 | 62 | - (void)backToFront{ 63 | 64 | [self dismissViewControllerAnimated:YES completion:NULL]; 65 | 66 | } 67 | 68 | - (void)didReceiveMemoryWarning { 69 | [super didReceiveMemoryWarning]; 70 | // Dispose of any resources that can be recreated. 71 | } 72 | 73 | /* 74 | #pragma mark - Navigation 75 | 76 | // In a storyboard-based application, you will often want to do a little preparation before navigation 77 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 78 | // Get the new view controller using [segue destinationViewController]. 79 | // Pass the selected object to the new view controller. 80 | } 81 | */ 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /WFReader/EReader/ViewController/E_ReaderViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_ReaderViewController.h 3 | // E_Reader 4 | // 5 | // Created by 阿虎 on 14-8-8. 6 | // Copyright (c) 2014年 tiger. All rights reserved. 7 | // 8 | 9 | #import 10 | /** 11 | * 显示阅读内容 12 | */ 13 | 14 | @protocol E_ReaderViewControllerDelegate 15 | 16 | - (void)shutOffPageViewControllerGesture:(BOOL)yesOrNo; 17 | - (void)hideTheSettingBar; 18 | - (void)ciBaWithString:(NSString *)ciBaString; 19 | 20 | @end 21 | 22 | 23 | @interface E_ReaderViewController : UIViewController 24 | 25 | @property (nonatomic,assign) iddelegate; 26 | @property (nonatomic,unsafe_unretained) NSUInteger currentPage; 27 | @property (nonatomic,unsafe_unretained) NSUInteger totalPage; 28 | @property (nonatomic,strong) NSString *text; 29 | @property (nonatomic,unsafe_unretained) NSUInteger font; 30 | @property (nonatomic, copy) NSString *chapterTitle; 31 | @property (nonatomic, unsafe_unretained,readonly) CGSize readerTextSize; 32 | @property (nonatomic,strong) UIImage *themeBgImage; 33 | @property (nonatomic,strong) NSString *keyWord; 34 | 35 | - (CGSize)readerTextSize; 36 | 37 | @end 38 | 39 | -------------------------------------------------------------------------------- /WFReader/EReader/ViewController/E_ReaderViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_ReaderViewController.m 3 | // E_Reader 4 | // 5 | // Created by 阿虎 on 14-8-8. 6 | // Copyright (c) 2014年 tiger. All rights reserved. 7 | // 8 | 9 | #import "E_ReaderViewController.h" 10 | #import "E_ReaderView.h" 11 | #import "E_CommonManager.h" 12 | 13 | #define MAX_FONT_SIZE 27 14 | #define MIN_FONT_SIZE 17 15 | 16 | @interface E_ReaderViewController () 17 | { 18 | E_ReaderView *_readerView; 19 | } 20 | 21 | @end 22 | 23 | @implementation E_ReaderViewController 24 | 25 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 26 | { 27 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 28 | if (self) { 29 | // Custom initialization 30 | } 31 | return self; 32 | } 33 | 34 | - (void)viewDidLoad 35 | { 36 | [super viewDidLoad]; 37 | 38 | _readerView = [[E_ReaderView alloc] initWithFrame:CGRectMake(offSet_x, offSet_y, self.view.frame.size.width - 2 * offSet_x, self.view.frame.size.height - offSet_y - 20)]; 39 | _readerView.keyWord = _keyWord; 40 | _readerView.magnifiterImage = _themeBgImage; 41 | _readerView.delegate = self; 42 | [self.view addSubview:_readerView]; 43 | 44 | } 45 | 46 | #pragma mark - ReaderViewDelegate 47 | - (void)shutOffGesture:(BOOL)yesOrNo{ 48 | [_delegate shutOffPageViewControllerGesture:yesOrNo]; 49 | } 50 | 51 | - (void)ciBa:(NSString *)ciBaString{ 52 | 53 | [_delegate ciBaWithString:ciBaString]; 54 | } 55 | 56 | - (void)hideSettingToolBar{ 57 | [_delegate hideTheSettingBar]; 58 | } 59 | 60 | - (void)setFont:(NSUInteger )font_ 61 | { 62 | _readerView.font = font_; 63 | } 64 | 65 | - (void)setText:(NSString *)text 66 | { 67 | _text = text; 68 | _readerView.text = text; 69 | 70 | [_readerView render]; 71 | } 72 | 73 | - (NSUInteger )font 74 | { 75 | return _readerView.font; 76 | } 77 | 78 | 79 | - (void)didReceiveMemoryWarning 80 | { 81 | [super didReceiveMemoryWarning]; 82 | // Dispose of any resources that can be recreated. 83 | } 84 | 85 | - (CGSize)readerTextSize 86 | { 87 | return _readerView.bounds.size; 88 | } 89 | @end 90 | -------------------------------------------------------------------------------- /WFReader/EReader/ViewController/E_ScrollViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_ScrollViewController.h 3 | // E_Reader 4 | // 5 | // Created by 阿虎 on 14-8-8. 6 | // Copyright (c) 2014年 tiger. All rights reserved. 7 | // 8 | 9 | #import 10 | /** 11 | * 放置阅读页的控制器 12 | */ 13 | @interface E_ScrollViewController : UIViewController 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WFReader/EReader/ViewController/E_SearchViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_SearchViewController.h 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/2/28. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIScrollView+MJRefresh.h" 11 | 12 | /** 13 | * 搜索页面 14 | */ 15 | @protocol E_SearchViewControllerDelegate 16 | 17 | - (void)turnToClickSearchResult:(NSString *)chapter withRange:(NSRange)searchRange andKeyWord:(NSString *)keyWord; 18 | 19 | @end 20 | 21 | @interface E_SearchViewController : UIViewController 22 | 23 | @property(nonatomic,assign)iddelegate; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /WFReader/EReader/ViewController/E_SearchViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_SearchViewController.m 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/2/28. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "E_SearchViewController.h" 10 | #import "E_CommonManager.h" 11 | #import "E_ReaderDataSource.h" 12 | #import "E_SearchTableViewCell.h" 13 | @interface E_SearchViewController (){ 14 | 15 | UITextField *_searchTextField; 16 | UITableView *_searchResultView; 17 | BOOL _isFirstTime; 18 | NSMutableArray *_dataSource; 19 | BOOL _isSearch; 20 | NSString *_keyWord; 21 | } 22 | @end 23 | 24 | @implementation E_SearchViewController 25 | 26 | - (void)viewDidLoad { 27 | [super viewDidLoad]; 28 | 29 | _isFirstTime = YES; 30 | _isSearch = NO; 31 | UIImage *_themeImage = nil; 32 | NSInteger themeID = [E_CommonManager Manager_getReadTheme]; 33 | if (themeID == 1) { 34 | _themeImage = nil; 35 | self.view.backgroundColor = [UIColor whiteColor]; 36 | }else{ 37 | _themeImage = [UIImage imageNamed:[NSString stringWithFormat:@"reader_bg%ld.png",(long)themeID]]; 38 | self.view.backgroundColor = [UIColor colorWithPatternImage:_themeImage]; 39 | } 40 | 41 | 42 | _dataSource = [[NSMutableArray alloc] initWithCapacity:0]; 43 | 44 | [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade]; 45 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; 46 | 47 | UIView *navView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 72)]; 48 | navView.backgroundColor = [UIColor colorWithRed:59/255.0 green:59/255.0 blue:59/255.0 alpha:1.0]; 49 | [self.view addSubview:navView]; 50 | 51 | UIButton *backBtn = [UIButton buttonWithType:0]; 52 | backBtn.frame = CGRectMake(self.view.frame.size.width - 60, 20, 60, 44); 53 | [backBtn setTitle:@"取消" forState:0]; 54 | backBtn.titleLabel.font = [UIFont systemFontOfSize:18]; 55 | backBtn.backgroundColor = [UIColor clearColor]; 56 | [backBtn setTitleColor:[UIColor whiteColor] forState:0]; 57 | [backBtn addTarget:self action:@selector(backToFront) forControlEvents:UIControlEventTouchUpInside]; 58 | [self.view addSubview:backBtn]; 59 | 60 | UIImageView *textFieldBg = [[UIImageView alloc] initWithFrame:CGRectMake(15, 25, self.view.frame.size.width - 75, 36)]; 61 | textFieldBg.layer.cornerRadius = 3; 62 | textFieldBg.backgroundColor = [UIColor whiteColor]; 63 | [textFieldBg.layer setBorderWidth:1.0]; 64 | textFieldBg.userInteractionEnabled = YES; 65 | 66 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 67 | CGColorRef colorref = CGColorCreate(colorSpace,(CGFloat[]){ 230/255.0, 230/255.0, 230/255.0, 1 }); 68 | [textFieldBg.layer setBorderColor:colorref]; 69 | [self.view addSubview:textFieldBg]; 70 | CGColorSpaceRelease(colorSpace); 71 | 72 | UIImageView *fangdajingBg = [[UIImageView alloc] initWithFrame:CGRectMake(10, 12, 13, 13)]; 73 | fangdajingBg.image = [UIImage imageNamed:@"magnifiter.png"]; 74 | [textFieldBg addSubview:fangdajingBg]; 75 | 76 | 77 | _searchTextField = [[UITextField alloc] initWithFrame:CGRectMake(45,28,textFieldBg.frame.size.width-30,32)]; 78 | _searchTextField.delegate = self; 79 | _searchTextField.placeholder = @"输入一个关键词"; 80 | [self.view addSubview:_searchTextField]; 81 | 82 | _searchResultView = [[UITableView alloc] initWithFrame:CGRectMake(0, navView.frame.size.height, self.view.frame.size.width, self.view.frame.size.height - navView.frame.size.height)]; 83 | _searchResultView.delegate = self; 84 | _searchResultView.dataSource = self; 85 | _searchResultView.backgroundColor = [UIColor clearColor]; 86 | [self.view addSubview:_searchResultView]; 87 | [_searchResultView addFooterWithTarget:self action:@selector(loadMoreInfo)]; 88 | _searchResultView.hidden = YES; 89 | 90 | } 91 | 92 | - (void)loadMoreInfo{ 93 | 94 | [_searchResultView footerEndRefreshing]; 95 | NSMutableArray *tempArray = [[E_ReaderDataSource shareInstance] searchWithKeyWords:_searchTextField.text]; 96 | 97 | [[_dataSource objectAtIndex:0] addObjectsFromArray:[tempArray objectAtIndex:0]]; 98 | [[_dataSource objectAtIndex:1] addObjectsFromArray:[tempArray objectAtIndex:1]]; 99 | [[_dataSource objectAtIndex:2] addObjectsFromArray:[tempArray objectAtIndex:2]]; 100 | [_searchResultView reloadData]; 101 | 102 | } 103 | 104 | #pragma mark - textFieldDelegate 105 | - (BOOL)textFieldShouldReturn:(UITextField *)textField{ 106 | 107 | 108 | [[E_ReaderDataSource shareInstance] resetTotalString]; 109 | 110 | [_dataSource removeAllObjects]; 111 | NSMutableArray *tempArray = [[E_ReaderDataSource shareInstance] searchWithKeyWords:textField.text]; 112 | _keyWord = textField.text; 113 | [_dataSource addObject:[tempArray objectAtIndex:0]]; 114 | [_dataSource addObject:[tempArray objectAtIndex:1]]; 115 | [_dataSource addObject:[tempArray objectAtIndex:2]]; 116 | 117 | [_searchTextField resignFirstResponder]; 118 | _isSearch = YES; 119 | _searchResultView.hidden = NO; 120 | [_searchResultView reloadData]; 121 | return YES; 122 | 123 | } 124 | 125 | 126 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 127 | 128 | return 60; 129 | } 130 | 131 | 132 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 133 | 134 | if (_isSearch == NO) { 135 | return 0; 136 | }else{ 137 | return [[_dataSource objectAtIndex:0] count]; 138 | } 139 | 140 | } 141 | 142 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 143 | static NSString *cellStr = @"listCell"; 144 | E_SearchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellStr]; 145 | if (cell == nil) { 146 | cell = [[E_SearchTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellStr]; 147 | } 148 | cell.backgroundColor = [UIColor clearColor]; 149 | 150 | cell.chapterLbl.text = [NSString stringWithFormat:@"第%@章",[[_dataSource objectAtIndex:1] objectAtIndex:indexPath.row]]; 151 | 152 | 153 | //寻找并变色 154 | NSMutableString *attString = [NSMutableString stringWithString:[[_dataSource objectAtIndex:0] objectAtIndex:indexPath.row]]; 155 | NSMutableArray *rangeArray = [NSMutableArray array]; 156 | NSMutableString *blankWord = [NSMutableString string]; 157 | for (int i = 0; i < _searchTextField.text.length; i ++) { 158 | 159 | [blankWord appendString:@" "]; 160 | } 161 | for (int i = 0; i < INT_MAX; i++) { 162 | 163 | if ([attString rangeOfString:_searchTextField.text options:1].location != NSNotFound){ 164 | NSInteger newLo = [attString rangeOfString:_searchTextField.text options:1].location; 165 | NSInteger newLen = [attString rangeOfString:_searchTextField.text options:1].length; 166 | NSRange newRange = NSMakeRange(newLo, newLen); 167 | [rangeArray addObject:NSStringFromRange(newRange)]; 168 | [attString replaceCharactersInRange:newRange withString:blankWord]; 169 | 170 | }else{ 171 | 172 | break; 173 | } 174 | } 175 | 176 | NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:[[_dataSource objectAtIndex:0] objectAtIndex:indexPath.row]]; 177 | for (int i = 0; i < rangeArray.count; i ++) { 178 | [str addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSRangeFromString([rangeArray objectAtIndex:i])]; 179 | } 180 | cell.contentLbl.attributedText = str; 181 | 182 | return cell; 183 | } 184 | 185 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 186 | 187 | [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade]; 188 | 189 | [_delegate turnToClickSearchResult:[[_dataSource objectAtIndex:1] objectAtIndex:indexPath.row] withRange:NSRangeFromString([[_dataSource objectAtIndex:2] objectAtIndex:indexPath.row]) andKeyWord:_keyWord]; 190 | [self dismissViewControllerAnimated:YES completion:NULL]; 191 | 192 | } 193 | 194 | - (void)backToFront{ 195 | 196 | [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade]; 197 | [_searchTextField resignFirstResponder]; 198 | [self dismissViewControllerAnimated:YES completion:NULL]; 199 | 200 | } 201 | 202 | - (void)didReceiveMemoryWarning { 203 | [super didReceiveMemoryWarning]; 204 | // Dispose of any resources that can be recreated. 205 | } 206 | 207 | /* 208 | #pragma mark - Navigation 209 | 210 | // In a storyboard-based application, you will often want to do a little preparation before navigation 211 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 212 | // Get the new view controller using [segue destinationViewController]. 213 | // Pass the selected object to the new view controller. 214 | } 215 | */ 216 | 217 | @end 218 | -------------------------------------------------------------------------------- /WFReader/EReader/ViewController/E_WebViewControler.h: -------------------------------------------------------------------------------- 1 | // 2 | // E_WebViewControler.h 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/3/3. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "NJKWebViewProgressView.h" 11 | #import "NJKWebViewProgress.h" 12 | /** 13 | * 浏览器视图控制器 14 | */ 15 | @interface E_WebViewControler : UIViewController 16 | { 17 | UIWebView *_webView; 18 | NJKWebViewProgressView *_progressView; 19 | NJKWebViewProgress *_progressProxy; 20 | NSString *_selectString; 21 | 22 | } 23 | 24 | - (id)initWithSelectString:(NSString *)selectString; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /WFReader/EReader/ViewController/E_WebViewControler.m: -------------------------------------------------------------------------------- 1 | // 2 | // E_WebViewControler.m 3 | // WFReader 4 | // 5 | // Created by 吴福虎 on 15/3/3. 6 | // Copyright (c) 2015年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "E_WebViewControler.h" 10 | 11 | 12 | @implementation E_WebViewControler 13 | 14 | 15 | - (id)initWithSelectString:(NSString *)selectString{ 16 | 17 | if (self = [super init]) { 18 | 19 | NSString *completeString = [selectString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 20 | completeString = [completeString stringByReplacingOccurrencesOfString:@"\r" withString:@""]; 21 | completeString = [completeString stringByReplacingOccurrencesOfString:@"\n" withString:@""]; 22 | _selectString = [completeString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 23 | 24 | self.view.backgroundColor = [UIColor whiteColor]; 25 | 26 | 27 | } 28 | return self; 29 | 30 | } 31 | 32 | - (void)viewDidLoad { 33 | 34 | [super viewDidLoad]; 35 | 36 | UILabel *titleLbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 64)]; 37 | [titleLbl setText:@"词霸"]; 38 | [titleLbl setTextColor:[UIColor whiteColor]]; 39 | titleLbl.font = [UIFont systemFontOfSize:20]; 40 | titleLbl.textAlignment = NSTextAlignmentCenter; 41 | titleLbl.backgroundColor = [UIColor colorWithRed:59/255.0 green:59/255.0 blue:59/255.0 alpha:1.0]; 42 | [self.view addSubview:titleLbl]; 43 | 44 | UIButton *backBtn = [UIButton buttonWithType:0]; 45 | backBtn.frame = CGRectMake(10, 20, 60, 44); 46 | [backBtn setTitle:@" 返回" forState:0]; 47 | backBtn.backgroundColor = [UIColor clearColor]; 48 | [backBtn setTitleColor:[UIColor whiteColor] forState:0]; 49 | [backBtn addTarget:self action:@selector(backToFront) forControlEvents:UIControlEventTouchUpInside]; 50 | [self.view addSubview:backBtn]; 51 | 52 | _webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 64)]; 53 | [self.view addSubview:_webView]; 54 | 55 | _progressProxy = [[NJKWebViewProgress alloc] init]; 56 | _webView.delegate = _progressProxy; 57 | _progressProxy.webViewProxyDelegate = self; 58 | _progressProxy.progressDelegate = self; 59 | 60 | CGFloat progressBarHeight = 2.f; 61 | 62 | CGRect barFrame = CGRectMake(0, 64, self.view.frame.size.width ,progressBarHeight); 63 | _progressView = [[NJKWebViewProgressView alloc] initWithFrame:barFrame]; 64 | _progressView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; 65 | [self.view addSubview:_progressView]; 66 | 67 | NSURLRequest *req = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://www.iciba.com/%@",_selectString]]]; 68 | [_webView loadRequest:req]; 69 | 70 | } 71 | 72 | - (void)backToFront{ 73 | 74 | [self dismissViewControllerAnimated:YES completion:NULL]; 75 | 76 | } 77 | 78 | #pragma mark - NJKWebViewProgressDelegate 79 | -(void)webViewProgress:(NJKWebViewProgress *)webViewProgress updateProgress:(float)progress{ 80 | 81 | [_progressView setProgress:progress animated:YES]; 82 | 83 | } 84 | 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /WFReader/EReader/resource/Chapter1.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 | -------------------------------------------------------------------------------- /WFReader/EReader/resource/Chapter2.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 |   嘴上虽是这么说,可眼里却是满满的笑意。 -------------------------------------------------------------------------------- /WFReader/EReader/resource/Chapter3.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 |   容她陆清离再好的教养,当见到面前这个自己背叛在先还理直气壮的男人时,也早已全线崩塌了。 -------------------------------------------------------------------------------- /WFReader/EReader/resource/Chapter4.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 |   “现在12周,再过一阵子,反应应该就会减轻很多了,回去好好调理吧,吃点清淡的。” 27 |   清离闭上眼睛。然后听到门响,脚步声,清欢快步走到她的床前。 28 |   伴着医院浓重的消毒水气味,清欢无声地看着面前的清离。 29 |   四周寂静的要死,清离的脸色却是出奇的平静。 30 |   她早就知道,该来的总会来。 31 |   只是,她太熟悉清欢的性子了,她承认什么都好,只是不能承认席慕尧有了小三的事实。 32 |   “姐,你是说,你和姐夫,已经离婚了?” 33 |   “是。”清离淡淡的说着:“没什么特别的原因,可能是婚姻生活太久了,彼此都麻木了吧。” 34 |   天知道,她多希望自己说出的是事实。如果她能再麻木一些,那该多好。 -------------------------------------------------------------------------------- /WFReader/EReader/resource/Chapter5.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 |   见清离盯着自己的眼神,林叶嫣有片刻失神,她清楚的知道,自己面前这个女人,是个什么样的角色,这个陆清离,市长大人最得意的千金,显然,并不是一块软豆腐,不会任人宰割。 -------------------------------------------------------------------------------- /WFReader/EReader/resource/Chapter6.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 |   而巧的是,他刚一走进这里,就见到了面前的这一幕。 -------------------------------------------------------------------------------- /WFReader/EReader/resource/Chapter7.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 |   而肚子里那个仅仅三个月的宝宝,她到底该留,还是该…… -------------------------------------------------------------------------------- /WFReader/EReader/resource/friend@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/friend@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/magnifiter@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/magnifiter@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/menuClose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/menuClose.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/r_drag-dot@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/r_drag-dot@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/r_ribbonRed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/r_ribbonRed@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/reader_bg1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/reader_bg1@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/reader_bg2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/reader_bg2@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/reader_bg3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/reader_bg3@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/reader_bg4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/reader_bg4@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/reader_bg5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/reader_bg5@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/reader_bg_s@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/reader_bg_s@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/reader_comments@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/reader_comments@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/reader_cover@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/reader_cover@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/reader_font_decrease@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/reader_font_decrease@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/reader_font_increase@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/reader_font_increase@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/reader_more@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/reader_more@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/sina@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/sina@2x.png -------------------------------------------------------------------------------- /WFReader/EReader/resource/weixin@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/EReader/resource/weixin@2x.png -------------------------------------------------------------------------------- /WFReader/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /WFReader/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UIViewControllerBasedStatusBarAppearance 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /WFReader/ThirdPart/CDSideBarController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CDSideBarController.h 3 | // CDSideBar 4 | // 5 | // Created by Christophe Dellac on 9/11/14. 6 | // Copyright (c) 2014 Christophe Dellac. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | /** 13 | * change by tiger -- 14 | */ 15 | @protocol CDSideBarControllerDelegate 16 | 17 | - (void)menuButtonClicked:(int)index; 18 | - (void)changeGestureRecognizers; 19 | 20 | @end 21 | 22 | @interface CDSideBarController : NSObject 23 | { 24 | UIView *_backgroundMenuView; 25 | UIButton *_menuButton; 26 | NSMutableArray *_buttonList; 27 | } 28 | 29 | 30 | @property (nonatomic, retain) UIColor *menuColor; 31 | @property (nonatomic) BOOL isOpen; 32 | @property (nonatomic, retain) UITapGestureRecognizer *singleTap; 33 | @property (nonatomic, retain) id delegate; 34 | 35 | - (CDSideBarController*)initWithImages:(NSArray*)buttonList; 36 | - (void)insertMenuButtonOnView:(UIView*)view atPosition:(CGPoint)position; 37 | - (void)showMenu; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /WFReader/ThirdPart/CDSideBarController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CDSideBarController.m 3 | // CDSideBar 4 | // 5 | // Created by Christophe Dellac on 9/11/14. 6 | // Copyright (c) 2014 Christophe Dellac. All rights reserved. 7 | // 8 | 9 | #import "CDSideBarController.h" 10 | 11 | @implementation CDSideBarController 12 | 13 | @synthesize menuColor = _menuColor; 14 | @synthesize isOpen = _isOpen; 15 | 16 | #pragma mark - 17 | #pragma mark Init 18 | 19 | - (CDSideBarController*)initWithImages:(NSArray*)images 20 | { 21 | // _menuButton = [UIButton buttonWithType:UIButtonTypeCustom]; 22 | // _menuButton.frame = CGRectMake(0, 0, 40, 40); 23 | // [_menuButton setImage:[UIImage imageNamed:@"menuIcon.png"] forState:UIControlStateNormal]; 24 | // [_menuButton addTarget:self action:@selector(showMenu) forControlEvents:UIControlEventTouchUpInside]; 25 | 26 | _backgroundMenuView = [[UIView alloc] init]; 27 | _menuColor = [UIColor whiteColor]; 28 | _buttonList = [[NSMutableArray alloc] initWithCapacity:images.count]; 29 | 30 | int index = 0; 31 | for (UIImage *image in [images copy]) 32 | { 33 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 34 | [button setImage:image forState:UIControlStateNormal]; 35 | button.frame = CGRectMake(20, 50 + (80 * index), 50, 50); 36 | button.tag = index; 37 | [button addTarget:self action:@selector(onMenuButtonClick:) forControlEvents:UIControlEventTouchUpInside]; 38 | [_buttonList addObject:button]; 39 | ++index; 40 | } 41 | return self; 42 | } 43 | 44 | - (void)insertMenuButtonOnView:(UIView*)view atPosition:(CGPoint)position 45 | { 46 | 47 | _singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissMenu)]; 48 | [view addGestureRecognizer:_singleTap]; 49 | 50 | for (UIButton *button in _buttonList) 51 | { 52 | [_backgroundMenuView addSubview:button]; 53 | } 54 | 55 | _backgroundMenuView.frame = CGRectMake(view.frame.size.width, 0, 90, view.frame.size.height); 56 | _backgroundMenuView.backgroundColor = [UIColor colorWithRed:59/255.0 green:59/255.0 blue:59/255.0 alpha:1.0]; 57 | [view addSubview:_backgroundMenuView]; 58 | } 59 | 60 | #pragma mark - 61 | #pragma mark Menu button action 62 | 63 | - (void)dismissMenuWithSelection:(UIButton*)button 64 | { 65 | [UIView animateWithDuration:0.3f 66 | delay:0.0f 67 | usingSpringWithDamping:.2f 68 | initialSpringVelocity:10.f 69 | options:0 animations:^{ 70 | button.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.2, 1.2); 71 | } 72 | completion:^(BOOL finished) { 73 | [self dismissMenu]; 74 | }]; 75 | } 76 | 77 | - (void)dismissMenu 78 | { 79 | if (_isOpen) 80 | { 81 | _isOpen = !_isOpen; 82 | [self performDismissAnimation]; 83 | } 84 | } 85 | 86 | - (void)showMenu 87 | { 88 | if (!_isOpen) 89 | { 90 | _isOpen = !_isOpen; 91 | [self performSelectorInBackground:@selector(performOpenAnimation) withObject:nil]; 92 | } 93 | } 94 | 95 | - (void)onMenuButtonClick:(UIButton*)button 96 | { 97 | if ([self.delegate respondsToSelector:@selector(menuButtonClicked:)]) 98 | [self.delegate menuButtonClicked:button.tag]; 99 | [self dismissMenuWithSelection:button]; 100 | } 101 | 102 | #pragma mark - 103 | #pragma mark - Animations 104 | 105 | - (void)performDismissAnimation 106 | { 107 | 108 | 109 | [UIView animateWithDuration:0.4 animations:^{ 110 | _backgroundMenuView.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, 0, 0); 111 | } completion:^(BOOL finished) { 112 | [_delegate changeGestureRecognizers]; 113 | }]; 114 | } 115 | 116 | - (void)performOpenAnimation 117 | { 118 | dispatch_async(dispatch_get_main_queue(), ^{ 119 | [UIView animateWithDuration:0.4 animations:^{ 120 | _backgroundMenuView.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, -90, 0); 121 | }]; 122 | }); 123 | for (UIButton *button in _buttonList) 124 | { 125 | [NSThread sleepForTimeInterval:0.02f]; 126 | dispatch_async(dispatch_get_main_queue(), ^{ 127 | button.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, 20, 0); 128 | [UIView animateWithDuration:0.3f 129 | delay:0.3f 130 | usingSpringWithDamping:.3f 131 | initialSpringVelocity:10.f 132 | options:0 animations:^{ 133 | button.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, 0, 0); 134 | } 135 | completion:^(BOOL finished) { 136 | }]; 137 | }); 138 | } 139 | } 140 | 141 | @end 142 | -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/MJRefresh.bundle/arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TigerWf/WFReader/73ca5c016b5adbf491969065813e2a48634bbc56/WFReader/ThirdPart/MJRefresh/MJRefresh.bundle/arrow@2x.png -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/MJRefresh.h: -------------------------------------------------------------------------------- 1 | 2 | #import "UIScrollView+MJRefresh.h" 3 | 4 | /** 5 | MJ友情提示: 6 | 1. 添加头部控件的方法 7 | [self.tableView addHeaderWithTarget:self action:@selector(headerRereshing)]; 8 | 或者 9 | [self.tableView addHeaderWithCallback:^{ }]; 10 | 11 | 2. 添加尾部控件的方法 12 | [self.tableView addFooterWithTarget:self action:@selector(footerRereshing)]; 13 | 或者 14 | [self.tableView addFooterWithCallback:^{ }]; 15 | 16 | 3. 可以在MJRefreshConst.h和MJRefreshConst.m文件中自定义显示的文字内容和文字颜色 17 | 18 | 4. 本框架兼容iOS6\iOS7,iPhone\iPad横竖屏 19 | 20 | 5.自动进入刷新状态 21 | 1> [self.tableView headerBeginRefreshing]; 22 | 2> [self.tableView footerBeginRefreshing]; 23 | 24 | 6.结束刷新 25 | 1> [self.tableView headerEndRefreshing]; 26 | 2> [self.tableView footerEndRefreshing]; 27 | */ -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/MJRefreshBaseView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshBaseView.h 3 | // MJRefresh 4 | // 5 | // Created by mj on 13-3-4. 6 | // Copyright (c) 2013年 itcast. All rights reserved. 7 | 8 | #import 9 | 10 | @class MJRefreshBaseView; 11 | 12 | #pragma mark - 控件的刷新状态 13 | typedef enum { 14 | MJRefreshStatePulling = 1, // 松开就可以进行刷新的状态 15 | MJRefreshStateNormal = 2, // 普通状态 16 | MJRefreshStateRefreshing = 3, // 正在刷新中的状态 17 | MJRefreshStateWillRefreshing = 4 18 | } MJRefreshState; 19 | 20 | #pragma mark - 控件的类型 21 | typedef enum { 22 | MJRefreshViewTypeHeader = -1, // 头部控件 23 | MJRefreshViewTypeFooter = 1 // 尾部控件 24 | } MJRefreshViewType; 25 | 26 | /** 27 | 类的声明 28 | */ 29 | @interface MJRefreshBaseView : UIView 30 | #pragma mark - 父控件 31 | @property (nonatomic, weak, readonly) UIScrollView *scrollView; 32 | @property (nonatomic, assign, readonly) UIEdgeInsets scrollViewOriginalInset; 33 | 34 | #pragma mark - 内部的控件 35 | @property (nonatomic, weak, readonly) UILabel *statusLabel; 36 | @property (nonatomic, weak, readonly) UIImageView *arrowImage; 37 | @property (nonatomic, weak, readonly) UIActivityIndicatorView *activityView; 38 | 39 | #pragma mark - 回调 40 | /** 41 | * 开始进入刷新状态的监听器 42 | */ 43 | @property (weak, nonatomic) id beginRefreshingTaget; 44 | /** 45 | * 开始进入刷新状态的监听方法 46 | */ 47 | @property (assign, nonatomic) SEL beginRefreshingAction; 48 | /** 49 | * 开始进入刷新状态就会调用 50 | */ 51 | @property (nonatomic, copy) void (^beginRefreshingCallback)(); 52 | 53 | #pragma mark - 刷新相关 54 | /** 55 | * 是否正在刷新 56 | */ 57 | @property (nonatomic, readonly, getter=isRefreshing) BOOL refreshing; 58 | /** 59 | * 开始刷新 60 | */ 61 | - (void)beginRefreshing; 62 | /** 63 | * 结束刷新 64 | */ 65 | - (void)endRefreshing; 66 | 67 | #pragma mark - 交给子类去实现 和 调用 68 | @property (assign, nonatomic) MJRefreshState state; 69 | 70 | /** 71 | * 文字 72 | */ 73 | @property (copy, nonatomic) NSString *pullToRefreshText; 74 | @property (copy, nonatomic) NSString *releaseToRefreshText; 75 | @property (copy, nonatomic) NSString *refreshingText; 76 | @end -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/MJRefreshBaseView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshBaseView.m 3 | // MJRefresh 4 | // 5 | // Created by mj on 13-3-4. 6 | // Copyright (c) 2013年 itcast. All rights reserved. 7 | // 8 | 9 | #import "MJRefreshBaseView.h" 10 | #import "MJRefreshConst.h" 11 | #import "UIView+Extension.h" 12 | #import "UIScrollView+Extension.h" 13 | #import 14 | 15 | @interface MJRefreshBaseView() 16 | { 17 | __weak UILabel *_statusLabel; 18 | __weak UIImageView *_arrowImage; 19 | __weak UIActivityIndicatorView *_activityView; 20 | } 21 | @end 22 | 23 | @implementation MJRefreshBaseView 24 | #pragma mark - 控件初始化 25 | /** 26 | * 状态标签 27 | */ 28 | - (UILabel *)statusLabel 29 | { 30 | if (!_statusLabel) { 31 | UILabel *statusLabel = [[UILabel alloc] init]; 32 | statusLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth; 33 | statusLabel.font = [UIFont boldSystemFontOfSize:13]; 34 | statusLabel.textColor = MJRefreshLabelTextColor; 35 | statusLabel.backgroundColor = [UIColor clearColor]; 36 | statusLabel.textAlignment = NSTextAlignmentCenter; 37 | [self addSubview:_statusLabel = statusLabel]; 38 | } 39 | return _statusLabel; 40 | } 41 | 42 | /** 43 | * 箭头图片 44 | */ 45 | - (UIImageView *)arrowImage 46 | { 47 | if (!_arrowImage) { 48 | UIImageView *arrowImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrow.png"]]; 49 | arrowImage.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; 50 | [self addSubview:_arrowImage = arrowImage]; 51 | } 52 | return _arrowImage; 53 | } 54 | 55 | /** 56 | * 状态标签 57 | */ 58 | - (UIActivityIndicatorView *)activityView 59 | { 60 | if (!_activityView) { 61 | UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 62 | activityView.bounds = self.arrowImage.bounds; 63 | activityView.autoresizingMask = self.arrowImage.autoresizingMask; 64 | [self addSubview:_activityView = activityView]; 65 | } 66 | return _activityView; 67 | } 68 | 69 | #pragma mark - 初始化方法 70 | - (instancetype)initWithFrame:(CGRect)frame { 71 | frame.size.height = MJRefreshViewHeight; 72 | if (self = [super initWithFrame:frame]) { 73 | // 1.自己的属性 74 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth; 75 | self.backgroundColor = [UIColor clearColor]; 76 | 77 | // 2.设置默认状态 78 | self.state = MJRefreshStateNormal; 79 | } 80 | return self; 81 | } 82 | 83 | - (void)layoutSubviews 84 | { 85 | [super layoutSubviews]; 86 | 87 | // 1.箭头 88 | CGFloat arrowX = self.width * 0.5 - 100; 89 | self.arrowImage.center = CGPointMake(arrowX, self.height * 0.5); 90 | 91 | // 2.指示器 92 | self.activityView.center = self.arrowImage.center; 93 | } 94 | 95 | - (void)willMoveToSuperview:(UIView *)newSuperview 96 | { 97 | [super willMoveToSuperview:newSuperview]; 98 | 99 | // 旧的父控件 100 | [self.superview removeObserver:self forKeyPath:MJRefreshContentOffset context:nil]; 101 | 102 | if (newSuperview) { // 新的父控件 103 | [newSuperview addObserver:self forKeyPath:MJRefreshContentOffset options:NSKeyValueObservingOptionNew context:nil]; 104 | 105 | // 设置宽度 106 | self.width = newSuperview.width; 107 | // 设置位置 108 | self.x = 0; 109 | 110 | // 记录UIScrollView 111 | _scrollView = (UIScrollView *)newSuperview; 112 | // 记录UIScrollView最开始的contentInset 113 | _scrollViewOriginalInset = _scrollView.contentInset; 114 | } 115 | } 116 | 117 | #pragma mark - 显示到屏幕上 118 | - (void)drawRect:(CGRect)rect 119 | { 120 | if (self.state == MJRefreshStateWillRefreshing) { 121 | self.state = MJRefreshStateRefreshing; 122 | } 123 | } 124 | 125 | #pragma mark - 刷新相关 126 | #pragma mark 是否正在刷新 127 | - (BOOL)isRefreshing 128 | { 129 | return MJRefreshStateRefreshing == self.state; 130 | } 131 | 132 | #pragma mark 开始刷新 133 | - (void)beginRefreshing 134 | { 135 | if (self.window) { 136 | self.state = MJRefreshStateRefreshing; 137 | } else { 138 | 139 | _state = MJRefreshStateWillRefreshing; 140 | [super setNeedsDisplay]; 141 | } 142 | } 143 | 144 | #pragma mark 结束刷新 145 | - (void)endRefreshing 146 | { 147 | double delayInSeconds = 0.3; 148 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); 149 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 150 | self.state = MJRefreshStateNormal; 151 | }); 152 | } 153 | 154 | #pragma mark - 设置状态 155 | - (void)setPullToRefreshText:(NSString *)pullToRefreshText 156 | { 157 | _pullToRefreshText = [pullToRefreshText copy]; 158 | [self settingLabelText]; 159 | } 160 | - (void)setReleaseToRefreshText:(NSString *)releaseToRefreshText 161 | { 162 | _releaseToRefreshText = [releaseToRefreshText copy]; 163 | [self settingLabelText]; 164 | } 165 | - (void)setRefreshingText:(NSString *)refreshingText 166 | { 167 | _refreshingText = [refreshingText copy]; 168 | [self settingLabelText]; 169 | } 170 | - (void)settingLabelText 171 | { 172 | switch (self.state) { 173 | case MJRefreshStateNormal: 174 | // 设置文字 175 | self.statusLabel.text = self.pullToRefreshText; 176 | break; 177 | case MJRefreshStatePulling: 178 | // 设置文字 179 | self.statusLabel.text = self.releaseToRefreshText; 180 | break; 181 | case MJRefreshStateRefreshing: 182 | // 设置文字 183 | self.statusLabel.text = self.refreshingText; 184 | break; 185 | default: 186 | break; 187 | } 188 | } 189 | 190 | - (void)setState:(MJRefreshState)state 191 | { 192 | // 0.存储当前的contentInset 193 | if (self.state != MJRefreshStateRefreshing) { 194 | _scrollViewOriginalInset = self.scrollView.contentInset; 195 | } 196 | 197 | // 1.一样的就直接返回 198 | if (self.state == state) return; 199 | 200 | // 2.根据状态执行不同的操作 201 | switch (state) { 202 | case MJRefreshStateNormal: // 普通状态 203 | { 204 | // 显示箭头 205 | self.arrowImage.hidden = NO; 206 | 207 | // 停止转圈圈 208 | [self.activityView stopAnimating]; 209 | break; 210 | } 211 | 212 | case MJRefreshStatePulling: 213 | break; 214 | 215 | case MJRefreshStateRefreshing: 216 | { 217 | // 开始转圈圈 218 | [self.activityView startAnimating]; 219 | // 隐藏箭头 220 | self.arrowImage.hidden = YES; 221 | 222 | // 回调 223 | if ([self.beginRefreshingTaget respondsToSelector:self.beginRefreshingAction]) {; 224 | [self.beginRefreshingTaget performSelector:self.beginRefreshingAction withObject:self]; 225 | } 226 | 227 | if (self.beginRefreshingCallback) { 228 | self.beginRefreshingCallback(); 229 | } 230 | break; 231 | } 232 | default: 233 | break; 234 | } 235 | 236 | // 3.存储状态 237 | _state = state; 238 | 239 | // 4.设置文字 240 | [self settingLabelText]; 241 | } 242 | @end -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/MJRefreshConst.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshConst.h 3 | // MJRefresh 4 | // 5 | // Created by mj on 14-1-3. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #ifdef DEBUG 10 | #define MJLog(...) NSLog(__VA_ARGS__) 11 | #else 12 | #define MJLog(...) 13 | #endif 14 | 15 | #define MJColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0] 16 | // 文字颜色 17 | #define MJRefreshLabelTextColor MJColor(150, 150, 150) 18 | 19 | #define MJRefreshViewHeight 64.0 20 | #define MJRefreshFastAnimationDuration 0.25 21 | #define MJRefreshSlowAnimationDuration 0.4 22 | 23 | #define MJRefreshBundleName @"MJRefresh.bundle" 24 | 25 | #define MJRefreshFooterPullToRefresh @"上拉刷新" 26 | #define MJRefreshFooterReleaseToRefresh @"松开刷新" 27 | #define MJRefreshFooterRefreshing @"刷新中" 28 | 29 | #define MJRefreshHeaderPullToRefresh @"下拉刷新" 30 | #define MJRefreshHeaderReleaseToRefresh @"松开刷新" 31 | #define MJRefreshHeaderRefreshing @"刷新中" 32 | #define MJRefreshHeaderTimeKey @"MJRefreshHeaderView" 33 | 34 | #define MJRefreshContentOffset @"contentOffset" 35 | #define MJRefreshContentSize @"contentSize" -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/MJRefreshConst.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshConst.m 3 | // MJRefresh 4 | // 5 | // Created by mj on 14-1-3. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/MJRefreshFooterView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshTableFooterView.h 3 | // MJRefresh 4 | // 5 | // Created by mj on 13-2-26. 6 | // Copyright (c) 2013年 itcast. All rights reserved. 7 | // 上拉加载更多 8 | 9 | #import "MJRefreshBaseView.h" 10 | 11 | @interface MJRefreshFooterView : MJRefreshBaseView 12 | + (instancetype)footer; 13 | @end -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/MJRefreshFooterView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshFooterView.m 3 | // MJRefresh 4 | // 5 | // Created by mj on 13-2-26. 6 | // Copyright (c) 2013年 itcast. All rights reserved. 7 | // 上拉加载更多 8 | 9 | #import "MJRefreshFooterView.h" 10 | #import "MJRefreshConst.h" 11 | #import "UIView+Extension.h" 12 | #import "UIScrollView+Extension.h" 13 | 14 | @interface MJRefreshFooterView() 15 | @property (assign, nonatomic) int lastRefreshCount; 16 | @end 17 | 18 | @implementation MJRefreshFooterView 19 | 20 | + (instancetype)footer 21 | { 22 | return [[MJRefreshFooterView alloc] init]; 23 | } 24 | 25 | - (id)initWithFrame:(CGRect)frame 26 | { 27 | if (self = [super initWithFrame:frame]) { 28 | self.pullToRefreshText = MJRefreshFooterPullToRefresh; 29 | self.releaseToRefreshText = MJRefreshFooterReleaseToRefresh; 30 | self.refreshingText = MJRefreshFooterRefreshing; 31 | } 32 | return self; 33 | } 34 | 35 | - (void)layoutSubviews 36 | { 37 | [super layoutSubviews]; 38 | 39 | self.statusLabel.frame = self.bounds; 40 | } 41 | 42 | - (void)willMoveToSuperview:(UIView *)newSuperview 43 | { 44 | [super willMoveToSuperview:newSuperview]; 45 | 46 | // 旧的父控件 47 | [self.superview removeObserver:self forKeyPath:MJRefreshContentSize context:nil]; 48 | 49 | if (newSuperview) { // 新的父控件 50 | // 监听 51 | [newSuperview addObserver:self forKeyPath:MJRefreshContentSize options:NSKeyValueObservingOptionNew context:nil]; 52 | 53 | // 重新调整frame 54 | [self adjustFrameWithContentSize]; 55 | } 56 | } 57 | 58 | #pragma mark 重写调整frame 59 | - (void)adjustFrameWithContentSize 60 | { 61 | // 内容的高度 62 | CGFloat contentHeight = self.scrollView.contentSizeHeight; 63 | // 表格的高度 64 | CGFloat scrollHeight = self.scrollView.height - self.scrollViewOriginalInset.top - self.scrollViewOriginalInset.bottom; 65 | // 设置位置和尺寸 66 | self.y = MAX(contentHeight, scrollHeight); 67 | } 68 | 69 | #pragma mark 监听UIScrollView的属性 70 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 71 | { 72 | // 不能跟用户交互,直接返回 73 | if (!self.userInteractionEnabled || self.alpha <= 0.01 || self.hidden) return; 74 | 75 | if ([MJRefreshContentSize isEqualToString:keyPath]) { 76 | // 调整frame 77 | [self adjustFrameWithContentSize]; 78 | } else if ([MJRefreshContentOffset isEqualToString:keyPath]) { 79 | #warning 这个返回一定要放这个位置 80 | // 如果正在刷新,直接返回 81 | if (self.state == MJRefreshStateRefreshing) return; 82 | 83 | // 调整状态 84 | [self adjustStateWithContentOffset]; 85 | } 86 | } 87 | 88 | /** 89 | * 调整状态 90 | */ 91 | - (void)adjustStateWithContentOffset 92 | { 93 | // 当前的contentOffset 94 | CGFloat currentOffsetY = self.scrollView.contentOffsetY; 95 | // 尾部控件刚好出现的offsetY 96 | CGFloat happenOffsetY = [self happenOffsetY]; 97 | 98 | // 如果是向下滚动到看不见尾部控件,直接返回 99 | if (currentOffsetY <= happenOffsetY) return; 100 | 101 | if (self.scrollView.isDragging) { 102 | // 普通 和 即将刷新 的临界点 103 | CGFloat normal2pullingOffsetY = happenOffsetY + self.height; 104 | 105 | if (self.state == MJRefreshStateNormal && currentOffsetY > normal2pullingOffsetY) { 106 | // 转为即将刷新状态 107 | self.state = MJRefreshStatePulling; 108 | } else if (self.state == MJRefreshStatePulling && currentOffsetY <= normal2pullingOffsetY) { 109 | // 转为普通状态 110 | self.state = MJRefreshStateNormal; 111 | } 112 | } else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开 113 | // 开始刷新 114 | self.state = MJRefreshStateRefreshing; 115 | } 116 | } 117 | 118 | #pragma mark - 状态相关 119 | #pragma mark 设置状态 120 | - (void)setState:(MJRefreshState)state 121 | { 122 | // 1.一样的就直接返回 123 | if (self.state == state) return; 124 | 125 | // 2.保存旧状态 126 | MJRefreshState oldState = self.state; 127 | 128 | // 3.调用父类方法 129 | [super setState:state]; 130 | 131 | // 4.根据状态来设置属性 132 | switch (state) 133 | { 134 | case MJRefreshStateNormal: 135 | { 136 | // 刷新完毕 137 | if (MJRefreshStateRefreshing == oldState) { 138 | self.arrowImage.transform = CGAffineTransformMakeRotation(M_PI); 139 | [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ 140 | self.scrollView.contentInsetBottom = self.scrollViewOriginalInset.bottom; 141 | }]; 142 | } else { 143 | // 执行动画 144 | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ 145 | self.arrowImage.transform = CGAffineTransformMakeRotation(M_PI); 146 | }]; 147 | } 148 | 149 | CGFloat deltaH = [self heightForContentBreakView]; 150 | int currentCount = [self totalDataCountInScrollView]; 151 | // 刚刷新完毕 152 | if (MJRefreshStateRefreshing == oldState && deltaH > 0 && currentCount != self.lastRefreshCount) { 153 | self.scrollView.contentOffsetY = self.scrollView.contentOffsetY; 154 | } 155 | break; 156 | } 157 | 158 | case MJRefreshStatePulling: 159 | { 160 | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ 161 | self.arrowImage.transform = CGAffineTransformIdentity; 162 | }]; 163 | break; 164 | } 165 | 166 | case MJRefreshStateRefreshing: 167 | { 168 | // 记录刷新前的数量 169 | self.lastRefreshCount = [self totalDataCountInScrollView]; 170 | 171 | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ 172 | CGFloat bottom = self.height + self.scrollViewOriginalInset.bottom; 173 | CGFloat deltaH = [self heightForContentBreakView]; 174 | if (deltaH < 0) { // 如果内容高度小于view的高度 175 | bottom -= deltaH; 176 | } 177 | self.scrollView.contentInsetBottom = bottom; 178 | }]; 179 | break; 180 | } 181 | 182 | default: 183 | break; 184 | } 185 | } 186 | 187 | - (int)totalDataCountInScrollView 188 | { 189 | int totalCount = 0; 190 | if ([self.scrollView isKindOfClass:[UITableView class]]) { 191 | UITableView *tableView = (UITableView *)self.scrollView; 192 | 193 | for (int section = 0; section 0) { 221 | return deltaH - self.scrollViewOriginalInset.top; 222 | } else { 223 | return - self.scrollViewOriginalInset.top; 224 | } 225 | } 226 | @end -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/MJRefreshHeaderView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshHeaderView.h 3 | // MJRefresh 4 | // 5 | // Created by mj on 13-2-26. 6 | // Copyright (c) 2013年 itcast. All rights reserved. 7 | // 下拉刷新 8 | 9 | #import "MJRefreshBaseView.h" 10 | 11 | @interface MJRefreshHeaderView : MJRefreshBaseView 12 | 13 | + (instancetype)header; 14 | - (void)setHeight:(CGFloat)height; 15 | 16 | @end -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/MJRefreshHeaderView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJRefreshHeaderView.m 3 | // MJRefresh 4 | // 5 | // Created by mj on 13-2-26. 6 | // Copyright (c) 2013年 itcast. All rights reserved. 7 | // 下拉刷新 8 | 9 | #import "MJRefreshConst.h" 10 | #import "MJRefreshHeaderView.h" 11 | #import "UIView+Extension.h" 12 | #import "UIScrollView+Extension.h" 13 | 14 | @interface MJRefreshHeaderView() 15 | // 最后的更新时间 16 | @property (nonatomic, strong) NSDate *lastUpdateTime; 17 | @property (nonatomic, weak) UILabel *lastUpdateTimeLabel; 18 | @end 19 | 20 | @implementation MJRefreshHeaderView 21 | #pragma mark - 控件初始化 22 | /** 23 | * 时间标签 24 | */ 25 | - (UILabel *)lastUpdateTimeLabel 26 | { 27 | if (!_lastUpdateTimeLabel) { 28 | // 1.创建控件 29 | UILabel *lastUpdateTimeLabel = [[UILabel alloc] init]; 30 | lastUpdateTimeLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth; 31 | lastUpdateTimeLabel.font = [UIFont boldSystemFontOfSize:12]; 32 | lastUpdateTimeLabel.textColor = MJRefreshLabelTextColor; 33 | lastUpdateTimeLabel.backgroundColor = [UIColor clearColor]; 34 | lastUpdateTimeLabel.textAlignment = NSTextAlignmentCenter; 35 | [self addSubview:_lastUpdateTimeLabel = lastUpdateTimeLabel]; 36 | 37 | // 2.加载时间 38 | self.lastUpdateTime = [[NSUserDefaults standardUserDefaults] objectForKey:MJRefreshHeaderTimeKey]; 39 | } 40 | return _lastUpdateTimeLabel; 41 | } 42 | 43 | + (instancetype)header 44 | { 45 | return [[MJRefreshHeaderView alloc] init]; 46 | } 47 | 48 | - (id)initWithFrame:(CGRect)frame 49 | { 50 | if (self = [super initWithFrame:frame]) { 51 | self.pullToRefreshText = MJRefreshHeaderPullToRefresh; 52 | self.releaseToRefreshText = MJRefreshHeaderReleaseToRefresh; 53 | self.refreshingText = MJRefreshHeaderRefreshing; 54 | } 55 | return self; 56 | } 57 | 58 | - (void)layoutSubviews 59 | { 60 | [super layoutSubviews]; 61 | 62 | CGFloat statusX = 0; 63 | CGFloat statusY = 0; 64 | CGFloat statusHeight = self.height * 0.5; 65 | CGFloat statusWidth = self.width; 66 | // 1.状态标签 67 | self.statusLabel.frame = CGRectMake(statusX, statusY, statusWidth, statusHeight); 68 | 69 | // 2.时间标签 70 | CGFloat lastUpdateY = statusHeight; 71 | CGFloat lastUpdateX = 0; 72 | CGFloat lastUpdateHeight = statusHeight; 73 | CGFloat lastUpdateWidth = statusWidth; 74 | self.lastUpdateTimeLabel.frame = CGRectMake(lastUpdateX, lastUpdateY, lastUpdateWidth, lastUpdateHeight); 75 | } 76 | 77 | - (void)willMoveToSuperview:(UIView *)newSuperview 78 | { 79 | [super willMoveToSuperview:newSuperview]; 80 | 81 | // 设置自己的位置和尺寸 82 | self.y = - self.height; 83 | } 84 | 85 | - (void)setHeight:(CGFloat)height { 86 | self.y = height; 87 | } 88 | 89 | #pragma mark - 状态相关 90 | #pragma mark 设置最后的更新时间 91 | - (void)setLastUpdateTime:(NSDate *)lastUpdateTime 92 | { 93 | _lastUpdateTime = lastUpdateTime; 94 | 95 | // 1.归档 96 | [[NSUserDefaults standardUserDefaults] setObject:lastUpdateTime forKey:MJRefreshHeaderTimeKey]; 97 | [[NSUserDefaults standardUserDefaults] synchronize]; 98 | 99 | // 2.更新时间 100 | [self updateTimeLabel]; 101 | } 102 | 103 | #pragma mark 更新时间字符串 104 | - (void)updateTimeLabel 105 | { 106 | if (!self.lastUpdateTime) return; 107 | 108 | // 1.获得年月日 109 | NSCalendar *calendar = [NSCalendar currentCalendar]; 110 | NSUInteger unitFlags = NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit |NSHourCalendarUnit |NSMinuteCalendarUnit; 111 | NSDateComponents *cmp1 = [calendar components:unitFlags fromDate:_lastUpdateTime]; 112 | NSDateComponents *cmp2 = [calendar components:unitFlags fromDate:[NSDate date]]; 113 | 114 | // 2.格式化日期 115 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 116 | if ([cmp1 day] == [cmp2 day]) { // 今天 117 | formatter.dateFormat = @"今天 HH:mm"; 118 | } else if ([cmp1 year] == [cmp2 year]) { // 今年 119 | formatter.dateFormat = @"MM-dd HH:mm"; 120 | } else { 121 | formatter.dateFormat = @"yyyy-MM-dd HH:mm"; 122 | } 123 | NSString *time = [formatter stringFromDate:self.lastUpdateTime]; 124 | 125 | // 3.显示日期 126 | self.lastUpdateTimeLabel.text = [NSString stringWithFormat:@"最后更新:%@", time]; 127 | } 128 | 129 | #pragma mark - 监听UIScrollView的contentOffset属性 130 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 131 | { 132 | // 不能跟用户交互就直接返回 133 | if (!self.userInteractionEnabled || self.alpha <= 0.01 || self.hidden) return; 134 | 135 | // 如果正在刷新,直接返回 136 | if (self.state == MJRefreshStateRefreshing) return; 137 | 138 | if ([MJRefreshContentOffset isEqualToString:keyPath]) { 139 | [self adjustStateWithContentOffset]; 140 | } 141 | } 142 | 143 | /** 144 | * 调整状态 145 | */ 146 | - (void)adjustStateWithContentOffset 147 | { 148 | // 当前的contentOffset 149 | CGFloat currentOffsetY = self.scrollView.contentOffsetY; 150 | // 头部控件刚好出现的offsetY 151 | CGFloat happenOffsetY = - self.scrollViewOriginalInset.top; 152 | 153 | // 如果是向上滚动到看不见头部控件,直接返回 154 | if (currentOffsetY >= happenOffsetY) return; 155 | 156 | if (self.scrollView.isDragging) { 157 | // 普通 和 即将刷新 的临界点 158 | CGFloat normal2pullingOffsetY = happenOffsetY - self.height; 159 | 160 | if (self.state == MJRefreshStateNormal && currentOffsetY < normal2pullingOffsetY) { 161 | // 转为即将刷新状态 162 | self.state = MJRefreshStatePulling; 163 | } else if (self.state == MJRefreshStatePulling && currentOffsetY >= normal2pullingOffsetY) { 164 | // 转为普通状态 165 | self.state = MJRefreshStateNormal; 166 | } 167 | } else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开 168 | // 开始刷新 169 | self.state = MJRefreshStateRefreshing; 170 | } 171 | } 172 | 173 | #pragma mark 设置状态 174 | - (void)setState:(MJRefreshState)state 175 | { 176 | // 1.一样的就直接返回 177 | if (self.state == state) return; 178 | 179 | // 2.保存旧状态 180 | MJRefreshState oldState = self.state; 181 | 182 | // 3.调用父类方法 183 | [super setState:state]; 184 | 185 | // 4.根据状态执行不同的操作 186 | switch (state) { 187 | case MJRefreshStateNormal: // 下拉可以刷新 188 | { 189 | // 刷新完毕 190 | if (MJRefreshStateRefreshing == oldState) { 191 | self.arrowImage.transform = CGAffineTransformIdentity; 192 | // 保存刷新时间 193 | self.lastUpdateTime = [NSDate date]; 194 | 195 | [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ 196 | self.scrollView.contentInsetTop = self.scrollViewOriginalInset.top; 197 | }]; 198 | } else { 199 | // 执行动画 200 | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ 201 | self.arrowImage.transform = CGAffineTransformIdentity; 202 | }]; 203 | } 204 | break; 205 | } 206 | 207 | case MJRefreshStatePulling: // 松开可立即刷新 208 | { 209 | // 执行动画 210 | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ 211 | self.arrowImage.transform = CGAffineTransformMakeRotation(M_PI); 212 | }]; 213 | break; 214 | } 215 | 216 | case MJRefreshStateRefreshing: // 正在刷新中 217 | { 218 | // 执行动画 219 | [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ 220 | // 1.增加滚动区域 221 | CGFloat top = self.scrollViewOriginalInset.top + self.height; 222 | self.scrollView.contentInsetTop = top; 223 | 224 | // 2.设置滚动位置 225 | self.scrollView.contentOffsetY = - top; 226 | }]; 227 | break; 228 | } 229 | 230 | default: 231 | break; 232 | } 233 | } 234 | @end -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/UIScrollView+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+Extension.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 14-5-28. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIScrollView (Extension) 12 | @property (assign, nonatomic) CGFloat contentInsetTop; 13 | @property (assign, nonatomic) CGFloat contentInsetBottom; 14 | @property (assign, nonatomic) CGFloat contentInsetLeft; 15 | @property (assign, nonatomic) CGFloat contentInsetRight; 16 | 17 | @property (assign, nonatomic) CGFloat contentOffsetX; 18 | @property (assign, nonatomic) CGFloat contentOffsetY; 19 | 20 | @property (assign, nonatomic) CGFloat contentSizeWidth; 21 | @property (assign, nonatomic) CGFloat contentSizeHeight; 22 | @end 23 | -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/UIScrollView+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+Extension.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 14-5-28. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import "UIScrollView+Extension.h" 10 | 11 | @implementation UIScrollView (Extension) 12 | - (void)setContentInsetTop:(CGFloat)contentInsetTop 13 | { 14 | UIEdgeInsets inset = self.contentInset; 15 | inset.top = contentInsetTop; 16 | self.contentInset = inset; 17 | } 18 | 19 | - (CGFloat)contentInsetTop 20 | { 21 | return self.contentInset.top; 22 | } 23 | 24 | - (void)setContentInsetBottom:(CGFloat)contentInsetBottom 25 | { 26 | UIEdgeInsets inset = self.contentInset; 27 | inset.bottom = contentInsetBottom; 28 | self.contentInset = inset; 29 | } 30 | 31 | - (CGFloat)contentInsetBottom 32 | { 33 | return self.contentInset.bottom; 34 | } 35 | 36 | - (void)setContentInsetLeft:(CGFloat)contentInsetLeft 37 | { 38 | UIEdgeInsets inset = self.contentInset; 39 | inset.left = contentInsetLeft; 40 | self.contentInset = inset; 41 | } 42 | 43 | - (CGFloat)contentInsetLeft 44 | { 45 | return self.contentInset.left; 46 | } 47 | 48 | - (void)setContentInsetRight:(CGFloat)contentInsetRight 49 | { 50 | UIEdgeInsets inset = self.contentInset; 51 | inset.right = contentInsetRight; 52 | self.contentInset = inset; 53 | } 54 | 55 | - (CGFloat)contentInsetRight 56 | { 57 | return self.contentInset.right; 58 | } 59 | 60 | - (void)setContentOffsetX:(CGFloat)contentOffsetX 61 | { 62 | CGPoint offset = self.contentOffset; 63 | offset.x = contentOffsetX; 64 | self.contentOffset = offset; 65 | } 66 | 67 | - (CGFloat)contentOffsetX 68 | { 69 | return self.contentOffset.x; 70 | } 71 | 72 | - (void)setContentOffsetY:(CGFloat)contentOffsetY 73 | { 74 | CGPoint offset = self.contentOffset; 75 | offset.y = contentOffsetY; 76 | self.contentOffset = offset; 77 | } 78 | 79 | - (CGFloat)contentOffsetY 80 | { 81 | return self.contentOffset.y; 82 | } 83 | 84 | - (void)setContentSizeWidth:(CGFloat)contentSizeWidth 85 | { 86 | CGSize size = self.contentSize; 87 | size.width = contentSizeWidth; 88 | self.contentSize = size; 89 | } 90 | 91 | - (CGFloat)contentSizeWidth 92 | { 93 | return self.contentSize.width; 94 | } 95 | 96 | - (void)setContentSizeHeight:(CGFloat)contentSizeHeight 97 | { 98 | CGSize size = self.contentSize; 99 | size.height = contentSizeHeight; 100 | self.contentSize = size; 101 | } 102 | 103 | - (CGFloat)contentSizeHeight 104 | { 105 | return self.contentSize.height; 106 | } 107 | @end 108 | -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/UIScrollView+MJRefresh.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+MJRefresh.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 14-5-28. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIScrollView (MJRefresh) 12 | #pragma mark - 下拉刷新 13 | /** 14 | * 添加一个下拉刷新头部控件 15 | * 16 | * @param callback 回调 17 | */ 18 | - (void)addHeaderWithCallback:(void (^)())callback; 19 | 20 | /** 21 | * 添加一个下拉刷新头部控件 22 | * 23 | * @param target 目标 24 | * @param action 回调方法 25 | */ 26 | - (void)addHeaderWithTarget:(id)target action:(SEL)action; 27 | /** 28 | * 重新设置header的Height 29 | */ 30 | - (void)setHeaderHeight:(CGFloat)height; 31 | /** 32 | * 移除下拉刷新头部控件 33 | */ 34 | - (void)removeHeader; 35 | 36 | /** 37 | * 主动让下拉刷新头部控件进入刷新状态 38 | */ 39 | - (void)headerBeginRefreshing; 40 | 41 | /** 42 | * 让下拉刷新头部控件停止刷新状态 43 | */ 44 | - (void)headerEndRefreshing; 45 | 46 | /** 47 | * 下拉刷新头部控件的可见性 48 | */ 49 | @property (nonatomic, assign, getter = isHeaderHidden) BOOL headerHidden; 50 | 51 | #pragma mark - 上拉刷新 52 | /** 53 | * 添加一个上拉刷新尾部控件 54 | * 55 | * @param callback 回调 56 | */ 57 | - (void)addFooterWithCallback:(void (^)())callback; 58 | 59 | /** 60 | * 添加一个上拉刷新尾部控件 61 | * 62 | * @param target 目标 63 | * @param action 回调方法 64 | */ 65 | - (void)addFooterWithTarget:(id)target action:(SEL)action; 66 | 67 | /** 68 | * 移除上拉刷新尾部控件 69 | */ 70 | - (void)removeFooter; 71 | 72 | /** 73 | * 主动让上拉刷新尾部控件进入刷新状态 74 | */ 75 | - (void)footerBeginRefreshing; 76 | 77 | /** 78 | * 让上拉刷新尾部控件停止刷新状态 79 | */ 80 | - (void)footerEndRefreshing; 81 | 82 | /** 83 | * 下拉刷新头部控件的可见性 84 | */ 85 | @property (nonatomic, assign, getter = isFooterHidden) BOOL footerHidden; 86 | 87 | /** 88 | * 设置尾部控件的文字 89 | */ 90 | @property (copy, nonatomic) NSString *footerPullToRefreshText; // 默认:@"上拉可以加载更多数据" 91 | @property (copy, nonatomic) NSString *footerReleaseToRefreshText; // 默认:@"松开立即加载更多数据" 92 | @property (copy, nonatomic) NSString *footerRefreshingText; // 默认:@"MJ哥正在帮你加载数据..." 93 | 94 | /** 95 | * 设置头部控件的文字 96 | */ 97 | @property (copy, nonatomic) NSString *headerPullToRefreshText; // 默认:@"下拉可以刷新" 98 | @property (copy, nonatomic) NSString *headerReleaseToRefreshText; // 默认:@"松开立即刷新" 99 | @property (copy, nonatomic) NSString *headerRefreshingText; // 默认:@"MJ哥正在帮你刷新..." 100 | @end 101 | -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/UIScrollView+MJRefresh.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+MJRefresh.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 14-5-28. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import "UIScrollView+MJRefresh.h" 10 | #import "MJRefreshHeaderView.h" 11 | #import "MJRefreshFooterView.h" 12 | #import 13 | 14 | @interface UIScrollView() 15 | @property (weak, nonatomic) MJRefreshHeaderView *header; 16 | @property (weak, nonatomic) MJRefreshFooterView *footer; 17 | @end 18 | 19 | 20 | @implementation UIScrollView (MJRefresh) 21 | 22 | #pragma mark - 运行时相关 23 | static char MJRefreshHeaderViewKey; 24 | static char MJRefreshFooterViewKey; 25 | 26 | - (void)setHeader:(MJRefreshHeaderView *)header { 27 | [self willChangeValueForKey:@"MJRefreshHeaderViewKey"]; 28 | objc_setAssociatedObject(self, &MJRefreshHeaderViewKey, 29 | header, 30 | OBJC_ASSOCIATION_ASSIGN); 31 | [self didChangeValueForKey:@"MJRefreshHeaderViewKey"]; 32 | } 33 | 34 | - (MJRefreshHeaderView *)header { 35 | return objc_getAssociatedObject(self, &MJRefreshHeaderViewKey); 36 | } 37 | 38 | - (void)setFooter:(MJRefreshFooterView *)footer { 39 | [self willChangeValueForKey:@"MJRefreshFooterViewKey"]; 40 | objc_setAssociatedObject(self, &MJRefreshFooterViewKey, 41 | footer, 42 | OBJC_ASSOCIATION_ASSIGN); 43 | [self didChangeValueForKey:@"MJRefreshFooterViewKey"]; 44 | } 45 | 46 | - (MJRefreshFooterView *)footer { 47 | return objc_getAssociatedObject(self, &MJRefreshFooterViewKey); 48 | } 49 | 50 | #pragma mark - 下拉刷新 51 | /** 52 | * 添加一个下拉刷新头部控件 53 | * 54 | * @param callback 回调 55 | */ 56 | - (void)addHeaderWithCallback:(void (^)())callback 57 | { 58 | // 1.创建新的header 59 | if (!self.header) { 60 | MJRefreshHeaderView *header = [MJRefreshHeaderView header]; 61 | [self addSubview:header]; 62 | self.header = header; 63 | } 64 | 65 | // 2.设置block回调 66 | self.header.beginRefreshingCallback = callback; 67 | } 68 | 69 | /** 70 | * 添加一个下拉刷新头部控件 71 | * 72 | * @param target 目标 73 | * @param action 回调方法 74 | */ 75 | - (void)addHeaderWithTarget:(id)target action:(SEL)action 76 | { 77 | // 1.创建新的header 78 | if (!self.header) { 79 | MJRefreshHeaderView *header = [MJRefreshHeaderView header]; 80 | [self addSubview:header]; 81 | self.header = header; 82 | } 83 | 84 | // 2.设置目标和回调方法 85 | self.header.beginRefreshingTaget = target; 86 | self.header.beginRefreshingAction = action; 87 | } 88 | 89 | /** 90 | * 重新设置header的Height 91 | */ 92 | - (void)setHeaderHeight:(CGFloat)height { 93 | if (!self.header) { 94 | return; 95 | } 96 | [self.header setHeight:height]; 97 | } 98 | 99 | /** 100 | * 移除下拉刷新头部控件 101 | */ 102 | - (void)removeHeader 103 | { 104 | [self.header removeFromSuperview]; 105 | self.header = nil; 106 | } 107 | 108 | /** 109 | * 主动让下拉刷新头部控件进入刷新状态 110 | */ 111 | - (void)headerBeginRefreshing 112 | { 113 | [self.header beginRefreshing]; 114 | } 115 | 116 | /** 117 | * 让下拉刷新头部控件停止刷新状态 118 | */ 119 | - (void)headerEndRefreshing 120 | { 121 | [self.header endRefreshing]; 122 | } 123 | 124 | /** 125 | * 下拉刷新头部控件的可见性 126 | */ 127 | - (void)setHeaderHidden:(BOOL)hidden 128 | { 129 | self.header.hidden = hidden; 130 | } 131 | 132 | - (BOOL)isHeaderHidden 133 | { 134 | return self.header.isHidden; 135 | } 136 | 137 | #pragma mark - 上拉刷新 138 | /** 139 | * 添加一个上拉刷新尾部控件 140 | * 141 | * @param callback 回调 142 | */ 143 | - (void)addFooterWithCallback:(void (^)())callback 144 | { 145 | // 1.创建新的footer 146 | if (!self.footer) { 147 | MJRefreshFooterView *footer = [MJRefreshFooterView footer]; 148 | [self addSubview:footer]; 149 | self.footer = footer; 150 | } 151 | 152 | // 2.设置block回调 153 | self.footer.beginRefreshingCallback = callback; 154 | } 155 | 156 | /** 157 | * 添加一个上拉刷新尾部控件 158 | * 159 | * @param target 目标 160 | * @param action 回调方法 161 | */ 162 | - (void)addFooterWithTarget:(id)target action:(SEL)action 163 | { 164 | // 1.创建新的footer 165 | if (!self.footer) { 166 | MJRefreshFooterView *footer = [MJRefreshFooterView footer]; 167 | [self addSubview:footer]; 168 | self.footer = footer; 169 | } 170 | 171 | // 2.设置目标和回调方法 172 | self.footer.beginRefreshingTaget = target; 173 | self.footer.beginRefreshingAction = action; 174 | } 175 | 176 | /** 177 | * 移除上拉刷新尾部控件 178 | */ 179 | - (void)removeFooter 180 | { 181 | [self.footer removeFromSuperview]; 182 | self.footer = nil; 183 | } 184 | 185 | /** 186 | * 主动让上拉刷新尾部控件进入刷新状态 187 | */ 188 | - (void)footerBeginRefreshing 189 | { 190 | [self.footer beginRefreshing]; 191 | } 192 | 193 | /** 194 | * 让上拉刷新尾部控件停止刷新状态 195 | */ 196 | - (void)footerEndRefreshing 197 | { 198 | [self.footer endRefreshing]; 199 | } 200 | 201 | /** 202 | * 下拉刷新头部控件的可见性 203 | */ 204 | - (void)setFooterHidden:(BOOL)hidden 205 | { 206 | self.footer.hidden = hidden; 207 | } 208 | 209 | - (BOOL)isFooterHidden 210 | { 211 | return self.footer.isHidden; 212 | } 213 | 214 | /** 215 | * 文字 216 | */ 217 | - (void)setFooterPullToRefreshText:(NSString *)footerPullToRefreshText 218 | { 219 | self.footer.pullToRefreshText = footerPullToRefreshText; 220 | } 221 | 222 | - (NSString *)footerPullToRefreshText 223 | { 224 | return self.footer.pullToRefreshText; 225 | } 226 | 227 | - (void)setFooterReleaseToRefreshText:(NSString *)footerReleaseToRefreshText 228 | { 229 | self.footer.releaseToRefreshText = footerReleaseToRefreshText; 230 | } 231 | 232 | - (NSString *)footerReleaseToRefreshText 233 | { 234 | return self.footer.releaseToRefreshText; 235 | } 236 | 237 | - (void)setFooterRefreshingText:(NSString *)footerRefreshingText 238 | { 239 | self.footer.refreshingText = footerRefreshingText; 240 | } 241 | 242 | - (NSString *)footerRefreshingText 243 | { 244 | return self.footer.refreshingText; 245 | } 246 | 247 | - (void)setHeaderPullToRefreshText:(NSString *)headerPullToRefreshText 248 | { 249 | self.header.pullToRefreshText = headerPullToRefreshText; 250 | } 251 | 252 | - (NSString *)headerPullToRefreshText 253 | { 254 | return self.header.pullToRefreshText; 255 | } 256 | 257 | - (void)setHeaderReleaseToRefreshText:(NSString *)headerReleaseToRefreshText 258 | { 259 | self.header.releaseToRefreshText = headerReleaseToRefreshText; 260 | } 261 | 262 | - (NSString *)headerReleaseToRefreshText 263 | { 264 | return self.header.releaseToRefreshText; 265 | } 266 | 267 | - (void)setHeaderRefreshingText:(NSString *)headerRefreshingText 268 | { 269 | self.header.refreshingText = headerRefreshingText; 270 | } 271 | 272 | - (NSString *)headerRefreshingText 273 | { 274 | return self.header.refreshingText; 275 | } 276 | @end 277 | -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/UIView+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Extension.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 14-5-28. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (Extension) 12 | @property (assign, nonatomic) CGFloat x; 13 | @property (assign, nonatomic) CGFloat y; 14 | @property (assign, nonatomic) CGFloat width; 15 | @property (assign, nonatomic) CGFloat height; 16 | @property (assign, nonatomic) CGSize size; 17 | @property (assign, nonatomic) CGPoint origin; 18 | @end 19 | -------------------------------------------------------------------------------- /WFReader/ThirdPart/MJRefresh/UIView+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Extension.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 14-5-28. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import "UIView+Extension.h" 10 | 11 | @implementation UIView (Extension) 12 | - (void)setX:(CGFloat)x 13 | { 14 | CGRect frame = self.frame; 15 | frame.origin.x = x; 16 | self.frame = frame; 17 | } 18 | 19 | - (CGFloat)x 20 | { 21 | return self.frame.origin.x; 22 | } 23 | 24 | - (void)setY:(CGFloat)y 25 | { 26 | CGRect frame = self.frame; 27 | frame.origin.y = y; 28 | self.frame = frame; 29 | } 30 | 31 | - (CGFloat)y 32 | { 33 | return self.frame.origin.y; 34 | } 35 | 36 | - (void)setWidth:(CGFloat)width 37 | { 38 | CGRect frame = self.frame; 39 | frame.size.width = width; 40 | self.frame = frame; 41 | } 42 | 43 | - (CGFloat)width 44 | { 45 | return self.frame.size.width; 46 | } 47 | 48 | - (void)setHeight:(CGFloat)height 49 | { 50 | CGRect frame = self.frame; 51 | frame.size.height = height; 52 | self.frame = frame; 53 | } 54 | 55 | - (CGFloat)height 56 | { 57 | return self.frame.size.height; 58 | } 59 | 60 | - (void)setSize:(CGSize)size 61 | { 62 | CGRect frame = self.frame; 63 | frame.size = size; 64 | self.frame = frame; 65 | } 66 | 67 | - (CGSize)size 68 | { 69 | return self.frame.size; 70 | } 71 | 72 | - (void)setOrigin:(CGPoint)origin 73 | { 74 | CGRect frame = self.frame; 75 | frame.origin = origin; 76 | self.frame = frame; 77 | } 78 | 79 | - (CGPoint)origin 80 | { 81 | return self.frame.origin; 82 | } 83 | @end 84 | -------------------------------------------------------------------------------- /WFReader/ThirdPart/NJKWebViewProgress/NJKWebViewProgress.h: -------------------------------------------------------------------------------- 1 | // 2 | // NJKWebViewProgress.h 3 | // 4 | // Created by Satoshi Aasano on 4/20/13. 5 | // Copyright (c) 2013 Satoshi Asano. All rights reserved. 6 | // 7 | 8 | #import 9 | #import 10 | #undef njk_weak 11 | #if __has_feature(objc_arc_weak) 12 | #define njk_weak weak 13 | #else 14 | #define njk_weak unsafe_unretained 15 | #endif 16 | 17 | extern const float NJKInitialProgressValue; 18 | extern const float NJKInteractiveProgressValue; 19 | extern const float NJKFinalProgressValue; 20 | 21 | typedef void (^NJKWebViewProgressBlock)(float progress); 22 | @protocol NJKWebViewProgressDelegate; 23 | @interface NJKWebViewProgress : NSObject 24 | @property (nonatomic, njk_weak) idprogressDelegate; 25 | @property (nonatomic, njk_weak) idwebViewProxyDelegate; 26 | @property (nonatomic, copy) NJKWebViewProgressBlock progressBlock; 27 | @property (nonatomic, readonly) float progress; // 0.0..1.0 28 | 29 | - (void)reset; 30 | @end 31 | 32 | @protocol NJKWebViewProgressDelegate 33 | - (void)webViewProgress:(NJKWebViewProgress *)webViewProgress updateProgress:(float)progress; 34 | @end 35 | 36 | -------------------------------------------------------------------------------- /WFReader/ThirdPart/NJKWebViewProgress/NJKWebViewProgress.m: -------------------------------------------------------------------------------- 1 | // 2 | // NJKWebViewProgress.m 3 | // 4 | // Created by Satoshi Aasano on 4/20/13. 5 | // Copyright (c) 2013 Satoshi Asano. All rights reserved. 6 | // 7 | 8 | #import "NJKWebViewProgress.h" 9 | 10 | NSString *completeRPCURLPath = @"/njkwebviewprogressproxy/complete"; 11 | 12 | const float NJKInitialProgressValue = 0.1f; 13 | const float NJKInteractiveProgressValue = 0.5f; 14 | const float NJKFinalProgressValue = 0.9f; 15 | 16 | @implementation NJKWebViewProgress 17 | { 18 | NSUInteger _loadingCount; 19 | NSUInteger _maxLoadCount; 20 | NSURL *_currentURL; 21 | BOOL _interactive; 22 | } 23 | 24 | - (id)init 25 | { 26 | self = [super init]; 27 | if (self) { 28 | _maxLoadCount = _loadingCount = 0; 29 | _interactive = NO; 30 | } 31 | return self; 32 | } 33 | 34 | - (void)startProgress 35 | { 36 | if (_progress < NJKInitialProgressValue) { 37 | [self setProgress:NJKInitialProgressValue]; 38 | } 39 | } 40 | 41 | - (void)incrementProgress 42 | { 43 | float progress = self.progress; 44 | float maxProgress = _interactive ? NJKFinalProgressValue : NJKInteractiveProgressValue; 45 | float remainPercent = (float)_loadingCount / (float)_maxLoadCount; 46 | float increment = (maxProgress - progress) * remainPercent; 47 | progress += increment; 48 | progress = fmin(progress, maxProgress); 49 | [self setProgress:progress]; 50 | } 51 | 52 | - (void)completeProgress 53 | { 54 | [self setProgress:1.0]; 55 | } 56 | 57 | - (void)setProgress:(float)progress 58 | { 59 | // progress should be incremental only 60 | if (progress > _progress || progress == 0) { 61 | _progress = progress; 62 | if ([_progressDelegate respondsToSelector:@selector(webViewProgress:updateProgress:)]) { 63 | [_progressDelegate webViewProgress:self updateProgress:progress]; 64 | } 65 | if (_progressBlock) { 66 | _progressBlock(progress); 67 | } 68 | } 69 | } 70 | 71 | - (void)reset 72 | { 73 | _maxLoadCount = _loadingCount = 0; 74 | _interactive = NO; 75 | [self setProgress:0.0]; 76 | } 77 | 78 | #pragma mark - 79 | #pragma mark UIWebViewDelegate 80 | 81 | - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 82 | { 83 | if ([request.URL.path isEqualToString:completeRPCURLPath]) { 84 | [self completeProgress]; 85 | return NO; 86 | } 87 | 88 | BOOL ret = YES; 89 | if ([_webViewProxyDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) { 90 | ret = [_webViewProxyDelegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType]; 91 | } 92 | 93 | BOOL isFragmentJump = NO; 94 | if (request.URL.fragment) { 95 | NSString *nonFragmentURL = [request.URL.absoluteString stringByReplacingOccurrencesOfString:[@"#" stringByAppendingString:request.URL.fragment] withString:@""]; 96 | isFragmentJump = [nonFragmentURL isEqualToString:webView.request.URL.absoluteString]; 97 | } 98 | 99 | BOOL isTopLevelNavigation = [request.mainDocumentURL isEqual:request.URL]; 100 | 101 | BOOL isHTTP = [request.URL.scheme isEqualToString:@"http"] || [request.URL.scheme isEqualToString:@"https"]; 102 | if (ret && !isFragmentJump && isHTTP && isTopLevelNavigation) { 103 | _currentURL = request.URL; 104 | [self reset]; 105 | } 106 | return ret; 107 | } 108 | 109 | - (void)webViewDidStartLoad:(UIWebView *)webView 110 | { 111 | if ([_webViewProxyDelegate respondsToSelector:@selector(webViewDidStartLoad:)]) { 112 | [_webViewProxyDelegate webViewDidStartLoad:webView]; 113 | } 114 | 115 | _loadingCount++; 116 | _maxLoadCount = fmax(_maxLoadCount, _loadingCount); 117 | 118 | [self startProgress]; 119 | } 120 | 121 | - (void)webViewDidFinishLoad:(UIWebView *)webView 122 | { 123 | if ([_webViewProxyDelegate respondsToSelector:@selector(webViewDidFinishLoad:)]) { 124 | [_webViewProxyDelegate webViewDidFinishLoad:webView]; 125 | } 126 | 127 | _loadingCount--; 128 | [self incrementProgress]; 129 | 130 | NSString *readyState = [webView stringByEvaluatingJavaScriptFromString:@"document.readyState"]; 131 | 132 | BOOL interactive = [readyState isEqualToString:@"interactive"]; 133 | if (interactive) { 134 | _interactive = YES; 135 | NSString *waitForCompleteJS = [NSString stringWithFormat:@"window.addEventListener('load',function() { var iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = '%@://%@%@'; document.body.appendChild(iframe); }, false);", webView.request.mainDocumentURL.scheme, webView.request.mainDocumentURL.host, completeRPCURLPath]; 136 | [webView stringByEvaluatingJavaScriptFromString:waitForCompleteJS]; 137 | } 138 | 139 | BOOL isNotRedirect = _currentURL && [_currentURL isEqual:webView.request.mainDocumentURL]; 140 | BOOL complete = [readyState isEqualToString:@"complete"]; 141 | if (complete && isNotRedirect) { 142 | [self completeProgress]; 143 | } 144 | } 145 | 146 | - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error 147 | { 148 | if ([_webViewProxyDelegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) { 149 | [_webViewProxyDelegate webView:webView didFailLoadWithError:error]; 150 | } 151 | 152 | _loadingCount--; 153 | [self incrementProgress]; 154 | 155 | NSString *readyState = [webView stringByEvaluatingJavaScriptFromString:@"document.readyState"]; 156 | 157 | BOOL interactive = [readyState isEqualToString:@"interactive"]; 158 | if (interactive) { 159 | _interactive = YES; 160 | NSString *waitForCompleteJS = [NSString stringWithFormat:@"window.addEventListener('load',function() { var iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = '%@://%@%@'; document.body.appendChild(iframe); }, false);", webView.request.mainDocumentURL.scheme, webView.request.mainDocumentURL.host, completeRPCURLPath]; 161 | [webView stringByEvaluatingJavaScriptFromString:waitForCompleteJS]; 162 | } 163 | 164 | BOOL isNotRedirect = _currentURL && [_currentURL isEqual:webView.request.mainDocumentURL]; 165 | BOOL complete = [readyState isEqualToString:@"complete"]; 166 | if ((complete && isNotRedirect) || error) { 167 | [self completeProgress]; 168 | } 169 | } 170 | 171 | #pragma mark - 172 | #pragma mark Method Forwarding 173 | // for future UIWebViewDelegate impl 174 | 175 | - (BOOL)respondsToSelector:(SEL)aSelector 176 | { 177 | if ( [super respondsToSelector:aSelector] ) 178 | return YES; 179 | 180 | if ([self.webViewProxyDelegate respondsToSelector:aSelector]) 181 | return YES; 182 | 183 | return NO; 184 | } 185 | 186 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector 187 | { 188 | NSMethodSignature *signature = [super methodSignatureForSelector:selector]; 189 | if(!signature) { 190 | if([_webViewProxyDelegate respondsToSelector:selector]) { 191 | return [(NSObject *)_webViewProxyDelegate methodSignatureForSelector:selector]; 192 | } 193 | } 194 | return signature; 195 | } 196 | 197 | - (void)forwardInvocation:(NSInvocation*)invocation 198 | { 199 | if ([_webViewProxyDelegate respondsToSelector:[invocation selector]]) { 200 | [invocation invokeWithTarget:_webViewProxyDelegate]; 201 | } 202 | } 203 | 204 | @end 205 | -------------------------------------------------------------------------------- /WFReader/ThirdPart/NJKWebViewProgress/NJKWebViewProgressView.h: -------------------------------------------------------------------------------- 1 | // 2 | // NJKWebViewProgressView.h 3 | // iOS 7 Style WebView Progress Bar 4 | // 5 | // Created by Satoshi Aasano on 11/16/13. 6 | // Copyright (c) 2013 Satoshi Asano. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NJKWebViewProgressView : UIView 12 | @property (nonatomic) float progress; 13 | 14 | @property (nonatomic) UIView *progressBarView; 15 | @property (nonatomic) NSTimeInterval barAnimationDuration; // default 0.1 16 | @property (nonatomic) NSTimeInterval fadeAnimationDuration; // default 0.27 17 | @property (nonatomic) NSTimeInterval fadeOutDelay; // default 0.1 18 | 19 | - (void)setProgress:(float)progress animated:(BOOL)animated; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /WFReader/ThirdPart/NJKWebViewProgress/NJKWebViewProgressView.m: -------------------------------------------------------------------------------- 1 | // 2 | // NJKWebViewProgressView.m 3 | // 4 | // Created by Satoshi Aasanoon 11/16/13. 5 | // Copyright (c) 2013 Satoshi Asano. All rights reserved. 6 | // 7 | 8 | #import "NJKWebViewProgressView.h" 9 | 10 | @implementation NJKWebViewProgressView 11 | 12 | - (id)initWithFrame:(CGRect)frame 13 | { 14 | self = [super initWithFrame:frame]; 15 | if (self) { 16 | [self configureViews]; 17 | } 18 | return self; 19 | } 20 | 21 | - (void)awakeFromNib 22 | { 23 | [super awakeFromNib]; 24 | [self configureViews]; 25 | } 26 | 27 | -(void)configureViews 28 | { 29 | self.userInteractionEnabled = NO; 30 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth; 31 | _progressBarView = [[UIView alloc] initWithFrame:self.bounds]; 32 | _progressBarView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; 33 | UIColor *tintColor = [UIColor colorWithRed:22.f / 255.f green:126.f / 255.f blue:251.f / 255.f alpha:1.0]; // iOS7 Safari bar color 34 | if ([UIApplication.sharedApplication.delegate.window respondsToSelector:@selector(setTintColor:)] && UIApplication.sharedApplication.delegate.window.tintColor) { 35 | tintColor = UIApplication.sharedApplication.delegate.window.tintColor; 36 | } 37 | _progressBarView.backgroundColor = tintColor; 38 | [self addSubview:_progressBarView]; 39 | 40 | _barAnimationDuration = 0.27f; 41 | _fadeAnimationDuration = 0.27f; 42 | _fadeOutDelay = 0.1f; 43 | } 44 | 45 | -(void)setProgress:(float)progress 46 | { 47 | [self setProgress:progress animated:NO]; 48 | } 49 | 50 | - (void)setProgress:(float)progress animated:(BOOL)animated 51 | { 52 | BOOL isGrowing = progress > 0.0; 53 | [UIView animateWithDuration:(isGrowing && animated) ? _barAnimationDuration : 0.0 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 54 | CGRect frame = _progressBarView.frame; 55 | frame.size.width = progress * self.bounds.size.width; 56 | _progressBarView.frame = frame; 57 | } completion:nil]; 58 | 59 | if (progress >= 1.0) { 60 | [UIView animateWithDuration:animated ? _fadeAnimationDuration : 0.0 delay:_fadeOutDelay options:UIViewAnimationOptionCurveEaseInOut animations:^{ 61 | _progressBarView.alpha = 0.0; 62 | } completion:^(BOOL completed){ 63 | CGRect frame = _progressBarView.frame; 64 | frame.size.width = 0; 65 | _progressBarView.frame = frame; 66 | }]; 67 | } 68 | else { 69 | [UIView animateWithDuration:animated ? _fadeAnimationDuration : 0.0 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 70 | _progressBarView.alpha = 1.0; 71 | } completion:nil]; 72 | } 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /WFReader/ThirdPart/UIImage+ImageEffects.h: -------------------------------------------------------------------------------- 1 | /* 2 | File: UIImage+ImageEffects.h 3 | Abstract: This is a category of UIImage that adds methods to apply blur and tint effects to an image. This is the code you’ll want to look out to find out how to use vImage to efficiently calculate a blur. 4 | Version: 1.0 5 | 6 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 7 | Inc. ("Apple") in consideration of your agreement to the following 8 | terms, and your use, installation, modification or redistribution of 9 | this Apple software constitutes acceptance of these terms. If you do 10 | not agree with these terms, please do not use, install, modify or 11 | redistribute this Apple software. 12 | 13 | In consideration of your agreement to abide by the following terms, and 14 | subject to these terms, Apple grants you a personal, non-exclusive 15 | license, under Apple's copyrights in this original Apple software (the 16 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 17 | Software, with or without modifications, in source and/or binary forms; 18 | provided that if you redistribute the Apple Software in its entirety and 19 | without modifications, you must retain this notice and the following 20 | text and disclaimers in all such redistributions of the Apple Software. 21 | Neither the name, trademarks, service marks or logos of Apple Inc. may 22 | be used to endorse or promote products derived from the Apple Software 23 | without specific prior written permission from Apple. Except as 24 | expressly stated in this notice, no other rights or licenses, express or 25 | implied, are granted by Apple herein, including but not limited to any 26 | patent rights that may be infringed by your derivative works or by other 27 | works in which the Apple Software may be incorporated. 28 | 29 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 30 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 31 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 32 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 33 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 34 | 35 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 36 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 39 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 40 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 41 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | Copyright (C) 2013 Apple Inc. All Rights Reserved. 45 | 46 | 47 | Copyright © 2013 Apple Inc. All rights reserved. 48 | WWDC 2013 License 49 | 50 | NOTE: This Apple Software was supplied by Apple as part of a WWDC 2013 51 | Session. Please refer to the applicable WWDC 2013 Session for further 52 | information. 53 | 54 | IMPORTANT: This Apple software is supplied to you by Apple Inc. 55 | ("Apple") in consideration of your agreement to the following terms, and 56 | your use, installation, modification or redistribution of this Apple 57 | software constitutes acceptance of these terms. If you do not agree with 58 | these terms, please do not use, install, modify or redistribute this 59 | Apple software. 60 | 61 | In consideration of your agreement to abide by the following terms, and 62 | subject to these terms, Apple grants you a non-exclusive license, under 63 | Apple's copyrights in this original Apple software (the "Apple 64 | Software"), to use, reproduce, modify and redistribute the Apple 65 | Software, with or without modifications, in source and/or binary forms; 66 | provided that if you redistribute the Apple Software in its entirety and 67 | without modifications, you must retain this notice and the following 68 | text and disclaimers in all such redistributions of the Apple Software. 69 | Neither the name, trademarks, service marks or logos of Apple Inc. may 70 | be used to endorse or promote products derived from the Apple Software 71 | without specific prior written permission from Apple. Except as 72 | expressly stated in this notice, no other rights or licenses, express or 73 | implied, are granted by Apple herein, including but not limited to any 74 | patent rights that may be infringed by your derivative works or by other 75 | works in which the Apple Software may be incorporated. 76 | 77 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES 78 | NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE 79 | IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR 80 | A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 81 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 82 | 83 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 84 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 85 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 86 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 87 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 88 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 89 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 90 | POSSIBILITY OF SUCH DAMAGE. 91 | 92 | EA1002 93 | 5/3/2013 94 | */ 95 | 96 | @import UIKit; 97 | 98 | @interface UIImage (ImageEffects) 99 | 100 | - (UIImage *)applyLightEffect; 101 | - (UIImage *)applyExtraLightEffect; 102 | - (UIImage *)applyDarkEffect; 103 | - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor; 104 | 105 | - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage; 106 | 107 | @end 108 | -------------------------------------------------------------------------------- /WFReader/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // WFReader 4 | // 5 | // Created by 阿虎 on 14/12/25. 6 | // Copyright (c) 2014年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /WFReader/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // WFReader 4 | // 5 | // Created by 阿虎 on 14/12/25. 6 | // Copyright (c) 2014年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "E_ScrollViewController.h" 11 | //#import "S_ScrollViewController.h" 12 | 13 | 14 | 15 | @interface ViewController () 16 | 17 | @end 18 | 19 | @implementation ViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | UIButton *pushBtn = [UIButton buttonWithType:0]; 24 | pushBtn.frame = CGRectMake(40, 50, self.view.frame.size.width - 80, 100); 25 | [pushBtn setTitle:@"go to Reader" forState:0]; 26 | pushBtn.backgroundColor = [UIColor cyanColor]; 27 | [pushBtn addTarget:self action:@selector(push) forControlEvents:UIControlEventTouchUpInside]; 28 | [self.view addSubview:pushBtn]; 29 | 30 | // Do any additional setup after loading the view, typically from a nib. 31 | } 32 | 33 | - (void)didReceiveMemoryWarning { 34 | [super didReceiveMemoryWarning]; 35 | // Dispose of any resources that can be recreated. 36 | } 37 | 38 | 39 | - (void)push{ 40 | E_ScrollViewController *loginvctrl = [[E_ScrollViewController alloc] init]; 41 | [self presentViewController:loginvctrl animated:NO completion:nil]; 42 | 43 | } 44 | @end 45 | -------------------------------------------------------------------------------- /WFReader/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WFReader 4 | // 5 | // Created by 阿虎 on 14/12/25. 6 | // Copyright (c) 2014年 tigerwf. 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 | -------------------------------------------------------------------------------- /WFReaderTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /WFReaderTests/WFReaderTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WFReaderTests.m 3 | // WFReaderTests 4 | // 5 | // Created by 阿虎 on 14/12/25. 6 | // Copyright (c) 2014年 tigerwf. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface WFReaderTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation WFReaderTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | //- (void)testPerformanceExample { 34 | // // This is an example of a performance test case. 35 | // [self measureBlock:^{ 36 | // // Put the code you want to measure the time of here. 37 | // }]; 38 | //} 39 | 40 | @end 41 | --------------------------------------------------------------------------------