diff --git a/.gitignore b/.gitignore index 09dfede4..1b576db8 100644 --- a/.gitignore +++ b/.gitignore @@ -34,7 +34,8 @@ xcuserdata/ # you should judge for yourself, the pros and cons are mentioned at: # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control # -# Pods/ +Pods/ +Podfile.lock # Carthage # diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e26515e..95054837 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,29 @@ +## [1.1.0](https://github.com/HDB-Li/LLDebugTool/releases/tag/1.1.0) (06/07/2018) + +### Add screenshot function. + +Increases the need to the permissions of the album, but it is not necessary, if the project has the authority, save will be synchronized to photo album, if the project doesn't have the permission, is saved into the sandbox alone, LLDebugTool will not actively apply for album permissions. + +
+ +
+ +#### Add + +* Add `LLScreenshotHelper` in `Helper` folder, used to control screenshot. +* Add `LLScreenshotView` folder in `UserInterface/Others` folder, used to show and draw screenshot. +* Add `LLDebugToolMacros.h`, used to manage public macros. + +#### Update + +* Update `LLBaseNavigationController` and `LLBaseViewController` to repair toolbar's frame is wrong when hiding tabbar. +* Update `LLAppHelper` to fix iPhone X getting network status error. +* Remove `LLog` macros in `LLDebugTool.h` and moved to `LLDebugToolMacros.h` + +#### Additional Changes + +* Update demo for saving screenshots to photo albums when screenshots are taken. + ## [1.0.3](https://github.com/HDB-Li/LLDebugTool/releases/tag/1.0.3) (05/31/2018) Fix some leaks. diff --git a/LLDebugTool.podspec b/LLDebugTool.podspec index 1363e2a3..030c67fa 100644 --- a/LLDebugTool.podspec +++ b/LLDebugTool.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LLDebugTool" - s.version = "1.0.3" + s.version = "1.1.0" s.summary = "LLDebugTool is a debugging tool for developers and testers that can help you analyze and manipulate data in non-xcode situations." s.homepage = "https://github.com/HDB-Li/LLDebugTool" s.license = "MIT" diff --git a/LLDebugTool/DebugTool/LLDebugTool.h b/LLDebugTool/DebugTool/LLDebugTool.h index c83c70b2..2e0e49ec 100644 --- a/LLDebugTool/DebugTool/LLDebugTool.h +++ b/LLDebugTool/DebugTool/LLDebugTool.h @@ -26,14 +26,6 @@ #ifndef LLSharedDebugTool #define LLSharedDebugTool [LLDebugTool sharedTool] -#define LLog(fmt, ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelDefault onEvent:nil message:(fmt, ##__VA_ARGS__)] -#define LLog_Event(event , fmt , ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelDefault onEvent:event message:(fmt, ##__VA_ARGS__)] -#define LLog_Alert(fmt, ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelAlert onEvent:nil message:(fmt, ##__VA_ARGS__)] -#define LLog_Alert_Event(event, fmt , ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelAlert onEvent:event message:(fmt, ##__VA_ARGS__)] -#define LLog_Warning(fmt, ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelWarning onEvent:nil message:(fmt, ##__VA_ARGS__)] -#define LLog_Warning_Event(event, fmt , ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelWarning onEvent:event message:(fmt, ##__VA_ARGS__)] -#define LLog_Error(fmt, ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelError onEvent:nil message:(fmt, ##__VA_ARGS__)] -#define LLog_Error_Event(event, fmt , ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelError onEvent:event message:(fmt, ##__VA_ARGS__)] #endif @class LLWindow; diff --git a/LLDebugTool/DebugTool/LLDebugTool.m b/LLDebugTool/DebugTool/LLDebugTool.m index 4ea44cf4..00aa851e 100644 --- a/LLDebugTool/DebugTool/LLDebugTool.m +++ b/LLDebugTool/DebugTool/LLDebugTool.m @@ -22,14 +22,13 @@ // SOFTWARE. #import "LLDebugTool.h" +#import "LLScreenshotHelper.h" #import "LLStorageManager.h" #import "LLNetworkHelper.h" #import "LLCrashHelper.h" +#import "LLLogHelper.h" #import "LLAppHelper.h" #import "LLWindow.h" -#import "LLLogHelper.h" - - static LLDebugTool *_instance = nil; @@ -65,6 +64,8 @@ - (void)startWorking{ [[LLNetworkHelper sharedHelper] setEnable:YES]; // Open app monitoring [[LLAppHelper sharedHelper] startMonitoring]; + // Open screenshot + [[LLScreenshotHelper sharedHelper] setEnable:YES]; // show window [self.window showWindow]; } @@ -75,6 +76,8 @@ - (void)stopWorking { _isWorking = NO; // Close app monitoring [[LLAppHelper sharedHelper] stopMonitoring]; + // Close screenshot + [[LLScreenshotHelper sharedHelper] setEnable:NO]; // Close network monitoring [[LLNetworkHelper sharedHelper] setEnable:NO]; // Close log helper @@ -87,7 +90,7 @@ - (void)stopWorking { } - (NSString *)version { - return @"1.0.3"; + return @"1.1.0"; } - (void)showDebugViewControllerWithIndex:(NSInteger)index { diff --git a/LLDebugTool/DebugTool/LLDebugToolMacros.h b/LLDebugTool/DebugTool/LLDebugToolMacros.h new file mode 100644 index 00000000..dd7dcbdf --- /dev/null +++ b/LLDebugTool/DebugTool/LLDebugToolMacros.h @@ -0,0 +1,52 @@ +// +// LLDebugToolMacros.h +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#ifndef LLDebugToolMacros_h +#define LLDebugToolMacros_h + +#define LLog(fmt, ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelDefault onEvent:nil message:(fmt, ##__VA_ARGS__)] +#define LLog_Event(event , fmt , ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelDefault onEvent:event message:(fmt, ##__VA_ARGS__)] +#define LLog_Alert(fmt, ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelAlert onEvent:nil message:(fmt, ##__VA_ARGS__)] +#define LLog_Alert_Event(event, fmt , ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelAlert onEvent:event message:(fmt, ##__VA_ARGS__)] +#define LLog_Warning(fmt, ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelWarning onEvent:nil message:(fmt, ##__VA_ARGS__)] +#define LLog_Warning_Event(event, fmt , ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelWarning onEvent:event message:(fmt, ##__VA_ARGS__)] +#define LLog_Error(fmt, ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelError onEvent:nil message:(fmt, ##__VA_ARGS__)] +#define LLog_Error_Event(event, fmt , ...) [LLSharedDebugTool logInFile:[[NSString stringWithUTF8String:__FILE__] lastPathComponent] function:NSStringFromSelector(_cmd) lineNo:__LINE__ level:LLConfigLogLevelError onEvent:event message:(fmt, ##__VA_ARGS__)] + +/* + // If you only use LLDebugTool in Debug environment, you can copy the following part to your PCH file to resolve most Release environment errors. + + #ifndef DEBUG + #define LLog(fmt, ...) NSLog(fmt) + #define LLog_Event(event , fmt , ...) NSLog(fmt) + #define LLog_Alert(fmt, ...) NSLog(fmt) + #define LLog_Alert_Event(event, fmt , ...) NSLog(fmt) + #define LLog_Warning(fmt, ...) NSLog(fmt) + #define LLog_Warning_Event(event, fmt , ...) NSLog(fmt) + #define LLog_Error(fmt, ...) NSLog(fmt) + #define LLog_Error_Event(event, fmt , ...) NSLog(fmt) + #endif + + */ + +#endif /* LLDebugToolMacros_h */ diff --git a/LLDebugTool/Helper/AppHelper/LLAppHelper.m b/LLDebugTool/Helper/AppHelper/LLAppHelper.m index 9fa61f94..5feb7894 100644 --- a/LLDebugTool/Helper/AppHelper/LLAppHelper.m +++ b/LLDebugTool/Helper/AppHelper/LLAppHelper.m @@ -332,54 +332,59 @@ - (NSString *)currentWifiSSID } - (NSString *)networkingStatesFromStatebar { + NSString *stateString = @"Unknown"; UIApplication *app = [UIApplication sharedApplication]; - NSArray *children; if ([[app valueForKeyPath:@"_statusBar"] isKindOfClass:NSClassFromString(@"UIStatusBar_Modern")]) { - children = [[[[app valueForKeyPath:@"_statusBar"] valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews]; + // For iPhoneX + NSArray *children = [[[[app valueForKeyPath:@"_statusBar"] valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews]; + for (UIView *view in children) { + for (id child in view.subviews) { + if ([child isKindOfClass:NSClassFromString(@"_UIStatusBarWifiSignalView")]) { + stateString = @"WIFI"; + break; + } + if ([child isKindOfClass:NSClassFromString(@"_UIStatusBarStringView")]) { + if ([[child valueForKey:@"_originalText"] containsString:@"G"]) { + stateString = [child valueForKey:@"_originalText"]; + break; + } + } + } + } } else { - children = [[[app valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews]; - } - - int type = 0; - for (id child in children) { - if ([child isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) { - type = [[child valueForKeyPath:@"dataNetworkType"] intValue]; + // For others iPhone + NSArray *children = [[[app valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews]; + int type = -1; + for (id child in children) { + if ([child isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) { + type = [[child valueForKeyPath:@"dataNetworkType"] intValue]; + } + } + switch (type) { + case 0: + stateString = @"Not Reachable"; + break; + case 1: + stateString = @"2G"; + break; + case 2: + stateString = @"3G"; + break; + case 3: + stateString = @"4G"; + break; + case 4: + stateString = @"LTE"; + break; + case 5: + stateString = @"WIFI"; + break; + default: + stateString = @"Unknown"; + break; } } - - NSString *stateString = @"wifi"; - - switch (type) { - case 0: - stateString = @"notReachable"; - break; - - case 1: - stateString = @"2G"; - break; - - case 2: - stateString = @"3G"; - break; - - case 3: - stateString = @"4G"; - break; - - case 4: - stateString = @"LTE"; - break; - - case 5: - stateString = @"wifi"; - break; - - default: - stateString = @"unknown"; - break; - } - return stateString; } diff --git a/LLDebugTool/Helper/ScreenShotHelper/LLScreenshotHelper.h b/LLDebugTool/Helper/ScreenShotHelper/LLScreenshotHelper.h new file mode 100644 index 00000000..2c7adf71 --- /dev/null +++ b/LLDebugTool/Helper/ScreenShotHelper/LLScreenshotHelper.h @@ -0,0 +1,45 @@ +// +// LLScreenshotHelper.h +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import + +@interface LLScreenshotHelper : NSObject + +/** + Singleton to control screenshot. + + @return Singleton + */ ++ (instancetype)sharedHelper; + +/** + Set enable to screenshot. + */ +@property (nonatomic , assign) BOOL enable; + +/** + Simulate user screenshot. + */ +- (void)simulateTakeScreenshot; + +@end diff --git a/LLDebugTool/Helper/ScreenShotHelper/LLScreenshotHelper.m b/LLDebugTool/Helper/ScreenShotHelper/LLScreenshotHelper.m new file mode 100644 index 00000000..213828bc --- /dev/null +++ b/LLDebugTool/Helper/ScreenShotHelper/LLScreenshotHelper.m @@ -0,0 +1,138 @@ +// +// LLScreenshotHelper.m +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import "LLScreenshotHelper.h" +#import +#import "LLScreenshotView.h" +#import "LLDebugTool.h" +#import "LLWindow.h" + +static LLScreenshotHelper *_instance = nil; + +@implementation LLScreenshotHelper + ++ (instancetype)sharedHelper { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _instance = [[LLScreenshotHelper alloc] init]; + }); + return _instance; +} + +- (void)setEnable:(BOOL)enable { + if (_enable != enable) { + _enable = enable; + if (enable) { + [self registerScreenshot]; + } else { + [self unregisterScreenshot]; + } + } +} + +- (void)simulateTakeScreenshot { + if (self.enable) { + [[LLDebugTool sharedTool].window hideWindow]; + UIImage *image = [self imageFromScreen]; + if (image) { + LLScreenshotView *screenshot = [[LLScreenshotView alloc] initWithImage:image]; + [screenshot show]; + } + } +} + +#pragma mark - UIApplicationUserDidTakeScreenshotNotification +- (void)receiveUserDidTakeScreenshotNotification:(NSNotification *)notification { + [self simulateTakeScreenshot]; +} + +#pragma mark - Primary +- (void)registerScreenshot { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveUserDidTakeScreenshotNotification:) name:UIApplicationUserDidTakeScreenshotNotification object:nil]; +} + +- (void)unregisterScreenshot { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationUserDidTakeScreenshotNotification object:nil]; +} + +- (nullable UIImage *)imageFromScreen { + NSData *data = [self dataWithScreenshotInPNGFormat]; + return [UIImage imageWithData:data]; +} + +- (nullable NSData *)dataWithScreenshotInPNGFormat +{ + CGSize imageSize = CGSizeZero; + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + if (UIInterfaceOrientationIsPortrait(orientation)) + imageSize = [UIScreen mainScreen].bounds.size; + else + imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width); + + UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0); + CGContextRef context = UIGraphicsGetCurrentContext(); + + NSMutableArray *windows = [[NSMutableArray alloc] initWithArray:[[UIApplication sharedApplication] windows]]; + UIView *statusBar = [[UIApplication sharedApplication] valueForKey:@"_statusBar"]; + if ([statusBar isKindOfClass:[UIView class]]) { + [windows addObject:statusBar]; + } + for (UIView *window in windows) + { + if (!window.isHidden) { + CGContextSaveGState(context); + CGContextTranslateCTM(context, window.center.x, window.center.y); + CGContextConcatCTM(context, window.transform); + CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y); + if (orientation == UIInterfaceOrientationLandscapeLeft) + { + CGContextRotateCTM(context, M_PI_2); + CGContextTranslateCTM(context, 0, -imageSize.width); + } + else if (orientation == UIInterfaceOrientationLandscapeRight) + { + CGContextRotateCTM(context, -M_PI_2); + CGContextTranslateCTM(context, -imageSize.height, 0); + } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) { + CGContextRotateCTM(context, M_PI); + CGContextTranslateCTM(context, -imageSize.width, -imageSize.height); + } + if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) + { + [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES]; + } + else + { + [window.layer renderInContext:context]; + } + CGContextRestoreGState(context); + } + } + + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return UIImagePNGRepresentation(image); +} + +@end diff --git a/LLDebugTool/Helper/StorageManager/LLStorageManager.h b/LLDebugTool/Helper/StorageManager/LLStorageManager.h index eb49d8ea..c6dd35a8 100644 --- a/LLDebugTool/Helper/StorageManager/LLStorageManager.h +++ b/LLDebugTool/Helper/StorageManager/LLStorageManager.h @@ -22,6 +22,7 @@ // SOFTWARE. #import +#import @class LLLogModel; @class LLCrashModel; @@ -104,4 +105,11 @@ */ - (BOOL)removeLogModels:(NSArray *)models; +#pragma mark - Screenshot + +/** + Save screenShots to sandbox. + */ +- (BOOL)saveScreenshot:(UIImage *)image name:(NSString *)name; + @end diff --git a/LLDebugTool/Helper/StorageManager/LLStorageManager.m b/LLDebugTool/Helper/StorageManager/LLStorageManager.m index c7993da9..2a97acaf 100644 --- a/LLDebugTool/Helper/StorageManager/LLStorageManager.m +++ b/LLDebugTool/Helper/StorageManager/LLStorageManager.m @@ -28,8 +28,7 @@ #import "LLCrashModel.h" #import "LLAppHelper.h" #import "LLLogModel.h" - - +#import "LLTool.h" static LLStorageManager *_instance = nil; @@ -57,6 +56,10 @@ @interface LLStorageManager () */ @property (strong , nonatomic) NSArray *cacheCrashModels; +@property (copy , nonatomic) NSString *folderPath; + +@property (copy , nonatomic) NSString *screenshotFolderPath; + @end @implementation LLStorageManager @@ -274,8 +277,17 @@ - (BOOL)_removeLogModel:(LLLogModel *)model { return ret; } -#pragma mark - Primary +#pragma mark - Screenshot +- (BOOL)saveScreenshot:(UIImage *)image name:(NSString *)name { + if (name.length == 0) { + name = [[LLTool sharedTool] staticStringFromDate:[NSDate date]]; + } + name = [name stringByAppendingPathExtension:@"png"]; + NSString *path = [self.screenshotFolderPath stringByAppendingPathComponent:name]; + return [UIImagePNGRepresentation(image) writeToFile:path atomically:YES]; +} +#pragma mark - Primary /** Initialize something */ @@ -290,16 +302,13 @@ - (void)initial { */ - (BOOL)initDatabase { NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; - doc = [doc stringByAppendingPathComponent:@"LLDebugTool"]; - if (![[NSFileManager defaultManager] fileExistsAtPath:doc]) { - NSError *error; - [[NSFileManager defaultManager] createDirectoryAtPath:doc withIntermediateDirectories:YES attributes:nil error:&error]; - if (error) { - NSLog(@"LLStorageManager create folder fail, error = %@",error.description); - } - NSAssert(!error, error.description); - } - NSString *filePath = [doc stringByAppendingPathComponent:@"LLDebugTool.db"]; + self.folderPath = [doc stringByAppendingPathComponent:@"LLDebugTool"]; + [self createDirectoryAtPath:self.folderPath]; + + self.screenshotFolderPath = [self.folderPath stringByAppendingPathComponent:@"Screenshot"]; + [self createDirectoryAtPath:self.screenshotFolderPath]; + + NSString *filePath = [self.folderPath stringByAppendingPathComponent:@"LLDebugTool.db"]; _dbQueue = [FMDatabaseQueue databaseQueueWithPath:filePath]; @@ -328,6 +337,19 @@ - (BOOL)initDatabase { return ret1 && ret2 && ret3; } +- (BOOL)createDirectoryAtPath:(NSString *)path { + if (![[NSFileManager defaultManager] fileExistsAtPath:path]) { + NSError *error; + [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]; + if (error) { + NSLog(@"LLStorageManager create folder fail, path = %@, error = %@",path,error.description); + NSAssert(!error, error.description); + return NO; + } + return YES; + } + return YES; +} /** * Remove unused log models and networks models. diff --git a/LLDebugTool/LLDebug.h b/LLDebugTool/LLDebug.h index 84ef0c6d..35d663b5 100644 --- a/LLDebugTool/LLDebug.h +++ b/LLDebugTool/LLDebug.h @@ -26,5 +26,6 @@ #import "LLDebugTool.h" #import "LLConfig.h" +#import "LLDebugToolMacros.h" #endif /* LLDebug_h */ diff --git a/LLDebugTool/UserInterface/Base/LLBaseNavigationController.m b/LLDebugTool/UserInterface/Base/LLBaseNavigationController.m index 883cb246..452010e2 100644 --- a/LLDebugTool/UserInterface/Base/LLBaseNavigationController.m +++ b/LLDebugTool/UserInterface/Base/LLBaseNavigationController.m @@ -30,6 +30,13 @@ @interface LLBaseNavigationController () @implementation LLBaseNavigationController +- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { + if (self.viewControllers.count > 0) { + viewController.hidesBottomBarWhenPushed = YES; + } + [super pushViewController:viewController animated:animated]; +} + - (UIStatusBarStyle)preferredStatusBarStyle { return [LLConfig sharedConfig].statusBarStyle; } diff --git a/LLDebugTool/UserInterface/Base/LLBaseViewController.m b/LLDebugTool/UserInterface/Base/LLBaseViewController.m index ee83e3bc..251efc7e 100644 --- a/LLDebugTool/UserInterface/Base/LLBaseViewController.m +++ b/LLDebugTool/UserInterface/Base/LLBaseViewController.m @@ -22,10 +22,11 @@ // SOFTWARE. #import "LLBaseViewController.h" +#import "LLImageNameConfig.h" #import "LLDebugTool.h" #import "LLMacros.h" -#import "LLImageNameConfig.h" #import "LLWindow.h" +#import "LLTool.h" static NSString *const kEmptyCellID = @"emptyCellID"; @@ -33,8 +34,6 @@ @interface LLBaseViewController () @property (nonatomic , assign) UITableViewStyle style; -@property (nonatomic , strong) UILabel *toastLabel; - @end @implementation LLBaseViewController @@ -59,52 +58,9 @@ - (void)viewDidLoad { } } -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - if (self.navigationController.viewControllers.count > 1) { - self.tabBarController.tabBar.hidden = YES; - } else { - self.tabBarController.tabBar.hidden = NO; - } -} - #pragma mark - Public - (void)toastMessage:(NSString *)message { - if (self.toastLabel) { - [self.toastLabel removeFromSuperview]; - self.toastLabel = nil; - } - - __block UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 0, LL_SCREEN_WIDTH - 40, 100)]; - label.text = message; - label.textAlignment = NSTextAlignmentCenter; - label.numberOfLines = 0; - label.lineBreakMode = NSLineBreakByCharWrapping; - [label sizeToFit]; - label.frame = CGRectMake(0, 0, label.frame.size.width + 20, label.frame.size.height + 10); - label.layer.cornerRadius = label.font.lineHeight / 2.0; - label.layer.masksToBounds = YES; - label.center = CGPointMake(LL_SCREEN_WIDTH / 2.0, LL_SCREEN_HEIGHT / 2.0); - label.alpha = 0; - label.backgroundColor = [UIColor blackColor]; - label.textColor = [UIColor whiteColor]; - [self.view addSubview:label]; - self.toastLabel = label; - [UIView animateWithDuration:0.25 animations:^{ - label.alpha = 1; - } completion:^(BOOL finished) { - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [UIView animateWithDuration:0.1 animations:^{ - label.alpha = 0; - } completion:^(BOOL finished) { - [label removeFromSuperview]; - }]; - }); - }]; + [[LLTool sharedTool] toastMessage:message]; } - (void)showAlertControllerWithMessage:(NSString *)message handler:(void (^)(NSInteger action))handler { diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenShotView.m b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenShotView.m new file mode 100644 index 00000000..f5d22501 --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenShotView.m @@ -0,0 +1,194 @@ +// +// LLScreenshotView.m +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import "LLScreenshotView.h" +#import +#import "LLScreenshotBaseOperation.h" +#import "LLScreenshotImageView.h" +#import "LLScreenshotToolbar.h" +#import "LLStorageManager.h" +#import "LLDebugTool.h" +#import "LLWindow.h" +#import "LLMacros.h" +#import "LLTool.h" + +@interface LLScreenshotView () + +@property (nonatomic , strong , nonnull) LLScreenshotImageView *imageView; + +@property (nonatomic , strong , nonnull) LLScreenshotToolbar *toolBar; + +@property (nonatomic , assign) CGRect originalImageFrame; + +@property (nonatomic , copy , nonnull) NSString *name; + +@end + +@implementation LLScreenshotView + +- (instancetype)initWithImage:(UIImage *)image { + if (self = [super initWithFrame:[UIScreen mainScreen].bounds]) { + [self initialWithImage:image]; + } + return self; +} + +- (void)show { + UIWindow *window = [UIApplication sharedApplication].delegate.window; + self.frame = CGRectMake(0, LL_SCREEN_HEIGHT, LL_SCREEN_WIDTH, LL_SCREEN_HEIGHT); + [window addSubview:self]; + [[LLDebugTool sharedTool].window hideWindow]; + [UIView animateWithDuration:0.25 delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:5.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ + self.frame = CGRectMake(0, 0, LL_SCREEN_WIDTH, LL_SCREEN_HEIGHT); + } completion:^(BOOL finished) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShowNotification:) name:UIKeyboardWillShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideNotification:) name:UIKeyboardWillHideNotification object:nil]; + }]; +} + +- (void)hide { + [UIView animateWithDuration:0.25 delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:5.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ + self.frame = CGRectMake(0, LL_SCREEN_HEIGHT, LL_SCREEN_WIDTH, LL_SCREEN_HEIGHT); + } completion:^(BOOL finished) { + [self removeFromSuperview]; + [[LLDebugTool sharedTool].window showWindow]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + }]; +} + +- (void)cancelAction { + [self hide]; +} + +- (void)confirmAction { + self.hidden = YES; + __weak __block typeof(self) weakSelf = self; + __block UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Note" message:@"Enter the image name" preferredStyle:UIAlertControllerStyleAlert]; + [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { + textField.text = weakSelf.name; + }]; + UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { + weakSelf.hidden = NO; + }]; + UIAlertAction *confirm = [UIAlertAction actionWithTitle:@"Confirm" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + weakSelf.hidden = NO; + [weakSelf doConfirmAction:alert.textFields.firstObject.text]; + }]; + [alert addAction:cancel]; + [alert addAction:confirm]; + + [[UIApplication sharedApplication].delegate.window.rootViewController presentViewController:alert animated:YES completion:nil]; +} + +- (void)doConfirmAction:(NSString *)name { + self.toolBar.hidden = YES; + UIImage *image = [self convertViewToImage:self.imageView]; + if (image) { + [[LLStorageManager sharedManager] saveScreenshot:image name:name]; + if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { + UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); + [[LLTool sharedTool] toastMessage:@"Save image in sandbox and album."]; + } else { + [[LLTool sharedTool] toastMessage:@"Save image in sandbox."]; + } + [self hide]; + } else { + self.toolBar.hidden = NO; + [[LLTool sharedTool] toastMessage:@"Save image failed."]; + } +} + +#pragma mark - NSNotification +- (void)keyboardWillShowNotification:(NSNotification *)notifi { + NSDictionary *userInfo = notifi.userInfo; + CGFloat duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + CGRect endFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; + if ([self.imageView.currentOperation isKindOfClass:[LLScreenshotTextOperation class]]) { + LLScreenshotTextOperation *operation = (LLScreenshotTextOperation *)self.imageView.currentOperation; + CGFloat y = operation.textView.frame.origin.y + self.originalImageFrame.origin.y; + CGFloat gap = y - endFrame.origin.y + 100; + if (gap > 0) { + [UIView animateWithDuration:duration animations:^{ + CGRect oriRect = self.imageView.frame; + self.imageView.frame = CGRectMake(oriRect.origin.x, self.originalImageFrame.origin.y - gap, oriRect.size.width, oriRect.size.height); + }]; + } + } +} + +- (void)keyboardWillHideNotification:(NSNotification *)notifi { + NSDictionary *userInfo = notifi.userInfo; + CGFloat duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + if (!CGRectEqualToRect(self.imageView.frame, self.originalImageFrame)) { + [UIView animateWithDuration:duration animations:^{ + self.imageView.frame = self.originalImageFrame; + }]; + } +} + +#pragma mark - Primary +- (void)initialWithImage:(UIImage *)image { + self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; + self.name = [[LLTool sharedTool] staticStringFromDate:[NSDate date]]; + + CGFloat rate = 0.1; + CGFloat toolBarHeight = 80; + CGFloat imgViewWidth = (1 - rate * 2) * LL_SCREEN_WIDTH; + CGFloat imgViewHeight = (1 - rate * 2) * LL_SCREEN_HEIGHT; + CGFloat imgViewTop = (rate * 2 * LL_SCREEN_HEIGHT - toolBarHeight) / 2.0; + // Init ImageView + self.imageView = [[LLScreenshotImageView alloc] initWithFrame:CGRectMake(rate * LL_SCREEN_WIDTH, imgViewTop, imgViewWidth, imgViewHeight)]; + self.originalImageFrame = self.imageView.frame; + self.imageView.image = image; + [self addSubview:self.imageView]; + + // Init Controls + self.toolBar = [[LLScreenshotToolbar alloc] initWithFrame:CGRectMake(self.imageView.frame.origin.x, self.imageView.frame.origin.y + self.imageView.frame.size.height + 10, self.imageView.frame.size.width, toolBarHeight)]; + self.toolBar.delegate = self; + [self addSubview:self.toolBar]; +} + +- (UIImage *)convertViewToImage:(UIView *)view{ + CGSize size = view.bounds.size; + UIGraphicsBeginImageContextWithOptions(size, YES, [UIScreen mainScreen].scale); + [view.layer renderInContext:UIGraphicsGetCurrentContext()]; + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return image; +} + +#pragma mark - LLScreenshotToolbarDelegate +- (void)LLScreenshotToolbar:(LLScreenshotToolbar *)toolBar didSelectedAction:(LLScreenshotAction)action selectorModel:(LLScreenshotSelectorModel *)selectorModel { + if (action <= LLScreenshotActionText) { + self.imageView.currentAction = action; + self.imageView.currentSelectorModel = selectorModel; + } else if (action == LLScreenshotActionBack) { + [self.imageView removeLastOperation]; + } else if (action == LLScreenshotActionCancel) { + [self cancelAction]; + } else if (action == LLScreenshotActionConfirm) { + [self confirmAction]; + } +} + +@end diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotActionView.h b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotActionView.h new file mode 100644 index 00000000..8290e66e --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotActionView.h @@ -0,0 +1,51 @@ +// +// LLScreenshotActionView.h +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import +#import "LLScreenshotDefine.h" + +@class LLScreenshotActionView; + +@protocol LLScreenshotActionViewDelegate + +@optional +/** + Call when action button clicked. + */ +- (void)LLScreenshotActionView:(LLScreenshotActionView *_Nonnull)actionView didSelectedAction:(LLScreenshotAction)action isSelected:(BOOL)isSelected position:(CGFloat)position; + +@end + +@interface LLScreenshotActionView : UIView + +/** + Delegate to accept click events. + */ +@property (nonatomic , weak , nullable) id delegate; + +/** + Specifies the initialization method. + */ +- (instancetype _Nonnull)initWithFrame:(CGRect)frame; + +@end diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotActionView.m b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotActionView.m new file mode 100644 index 00000000..b022dd1f --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotActionView.m @@ -0,0 +1,139 @@ +// +// LLScreenshotActionView.m +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import "LLScreenshotActionView.h" +#import "LLImageNameConfig.h" + +@interface LLScreenshotActionView () + +@property (nonatomic , strong , nullable) UIButton *lastSelectButton; + +@end + +@implementation LLScreenshotActionView + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + [self initial]; + } + return self; +} + +- (void)buttonClicked:(UIButton *)sender { + switch (sender.tag) { + case LLScreenshotActionRect: + case LLScreenshotActionRound: + case LLScreenshotActionLine: + case LLScreenshotActionPen: + case LLScreenshotActionText:{ + if (self.lastSelectButton != sender) { + self.lastSelectButton.selected = NO; + sender.selected = YES; + self.lastSelectButton = sender; + } else { + sender.selected = NO; + self.lastSelectButton = nil; + } + } + break; + default: + break; + } + if ([_delegate respondsToSelector:@selector(LLScreenshotActionView:didSelectedAction:isSelected:position:)]) { + CGFloat position = sender.frame.origin.x + sender.frame.size.width / 2.0; + [_delegate LLScreenshotActionView:self didSelectedAction:sender.tag isSelected:sender.isSelected position:position]; + } +} + +#pragma mark - Primary +- (void)initial { + self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.8]; + self.layer.cornerRadius = 5; + self.layer.masksToBounds = YES; + + int count = 8; + CGFloat gap = 10; + CGFloat itemWidth = (self.frame.size.width - gap * 2) / count; + CGFloat itemHeight = self.frame.size.height; + CGFloat top = (self.frame.size.height - itemHeight) / 2.0; + + for (int i = 1; i <= count; i++) { + UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; + button.frame = CGRectMake(gap + (i - 1) * itemWidth, top, itemWidth, itemHeight); + NSString *imageName = @""; + NSString *selectImageName = @""; + switch (i) { + case LLScreenshotActionRect:{ + imageName = kRectImageName; + selectImageName = kRectSelectImageName; + break; + } + case LLScreenshotActionRound:{ + imageName = kRoundImageName; + selectImageName = kRoundSelectImageName; + break; + } + case LLScreenshotActionLine:{ + imageName = kLineImageName; + selectImageName = kLineSelectImageName; + break; + } + case LLScreenshotActionPen:{ + imageName = kPenImageName; + selectImageName = kPenSelectImageName; + break; + } + case LLScreenshotActionText:{ + imageName = kTextImageName; + selectImageName = kTextSelectImageName; + break; + } + case LLScreenshotActionBack:{ + imageName = kUndoImageName; + selectImageName = kUndoDisableImageName; + break; + } + case LLScreenshotActionCancel:{ + imageName = kCancelImageName; + selectImageName = kCancelImageName; + break; + } + case LLScreenshotActionConfirm:{ + imageName = kSureImageName; + selectImageName = kSureImageName; + break; + } + default: + break; + } + [button setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal]; + [button setImage:[UIImage imageNamed:selectImageName] forState:UIControlStateSelected]; + button.tag = i; + button.showsTouchWhenHighlighted = NO; + button.adjustsImageWhenHighlighted = NO; + [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; + [self addSubview:button]; + } +} + +@end diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotBaseOperation.h b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotBaseOperation.h new file mode 100644 index 00000000..d93d33a8 --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotBaseOperation.h @@ -0,0 +1,95 @@ +// +// LLScreenshotBaseOperation.h +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import +#import +#import "LLScreenshotSelectorModel.h" +#import "LLScreenshotDefine.h" + +@interface LLScreenshotBaseOperation : NSObject + +@property (nonatomic , assign , readonly) LLScreenshotAction action; + +@property (nonatomic , assign , readonly) LLScreenshotSelectorAction size; + +@property (nonatomic , assign , readonly) LLScreenshotSelectorAction color; + +@property (nonatomic , strong , readonly , nonnull) CAShapeLayer *layer; + +/** + Specifies the initialization method. + */ +- (instancetype)initWithSelector:(LLScreenshotSelectorModel *)selector action:(LLScreenshotAction)action; + +/** + Subclasses need to be rewritten. + */ +- (void)drawImageView:(CGRect)rect; + +@end + +@interface LLScreenshotTwoValueOperation : LLScreenshotBaseOperation + +// CGPoint + +/** + CGPoint value. Mark start point. + */ +@property (nonatomic , strong , nullable) NSValue *startValue; + +/** + CGPoint value. Mark end point. + */ +@property (nonatomic , strong , nullable) NSValue *endValue; + +@end + +@interface LLScreenshotRectOperation : LLScreenshotTwoValueOperation + +@end + +@interface LLScreenshotRoundOperation : LLScreenshotTwoValueOperation + +@end + +@interface LLScreenshotLineOperation : LLScreenshotTwoValueOperation + +@end + +@interface LLScreenshotPenOperation : LLScreenshotBaseOperation + +/** + CGPoint value. add operation point. + */ +- (void)addValue:(NSValue *)value; + +@end + +@interface LLScreenshotTextOperation : LLScreenshotBaseOperation + +/** + Use to input text. + */ +@property (nonatomic , strong , readonly , nonnull) UITextView *textView; + +@end diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotBaseOperation.m b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotBaseOperation.m new file mode 100644 index 00000000..baabd589 --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotBaseOperation.m @@ -0,0 +1,337 @@ +// +// LLScreenshotBaseOperation.m +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import "LLScreenshotBaseOperation.h" +#import "LLImageNameConfig.h" +#import "LLMacros.h" +#import "LLTool.h" + +@interface LLScreenshotBaseOperation () + +@property (nonatomic , strong , nonnull) LLScreenshotSelectorModel *selector; + +@property (nonatomic , strong , nonnull) UIBezierPath *path; + +@property (nonatomic , strong , nonnull) UIColor *redColor; + +@property (nonatomic , strong , nonnull) UIColor *blueColor; + +@property (nonatomic , strong , nonnull) UIColor *greenColor; + +@property (nonatomic , strong , nonnull) UIColor *yellowColor; + +@property (nonatomic , strong , nonnull) UIColor *grayColor; + +@property (nonatomic , strong , nonnull) UIColor *whiteColor; + +@property (nonatomic , strong , nonnull) UIFont *smallFont; + +@property (nonatomic , strong , nonnull) UIFont *mediumFont; + +@property (nonatomic , strong , nonnull) UIFont *bigFont; + +@end + +@implementation LLScreenshotBaseOperation + +- (instancetype)init +{ + self = [super init]; + if (self) { + _selector = [[LLScreenshotSelectorModel alloc] initWithSize:LLScreenshotSelectorActionSmall color:LLScreenshotSelectorActionRed]; + _action = LLScreenshotActionRect; + _path = [UIBezierPath bezierPath]; + _layer = [CAShapeLayer layer]; + } + return self; +} + +- (instancetype)initWithSelector:(LLScreenshotSelectorModel *)selector action:(LLScreenshotAction)action { + if (self = [super init]) { + _selector = selector; + _action = action; + _path = [UIBezierPath bezierPath]; + _layer = [CAShapeLayer layer]; + } + return self; +} + +- (void)drawImageView:(CGRect)rect { + NSLog(@"%@ : Subclasses need to be rewritten.", NSStringFromSelector(_cmd)); +} + +- (LLScreenshotSelectorAction)size { + return _selector.size; +} + +- (LLScreenshotSelectorAction)color { + return _selector.color; +} + +- (UIColor *)redColor { + if (!_redColor) { + _redColor = [UIColor colorWithRed:0xd8/255.0 green:0x1e/255.0 blue:0x06/255.0 alpha:1]; + } + return _redColor; +} + +- (UIColor *)blueColor { + if (!_blueColor) { + _blueColor = [UIColor colorWithRed:0x12/255.0 green:0x96/255.0 blue:0xdb/255.0 alpha:1]; + } + return _blueColor; +} + +- (UIColor *)greenColor { + if (!_greenColor) { + _greenColor = [UIColor colorWithRed:0x1a/255.0 green:0xfa/255.0 blue:0x29/255.0 alpha:1]; + } + return _greenColor; +} + +- (UIColor *)yellowColor { + if (!_yellowColor) { + _yellowColor = [UIColor colorWithRed:0xf4/255.0 green:0xea/255.0 blue:0x2a/255.0 alpha:1]; + } + return _yellowColor; +} + +- (UIColor *)grayColor { + if (!_grayColor) { + _grayColor = [UIColor colorWithRed:0x2c/255.0 green:0x2c/255.0 blue:0x2c/255.0 alpha:1]; + } + return _grayColor; +} + +- (UIColor *)whiteColor { + if (!_whiteColor) { + _whiteColor = [UIColor whiteColor]; + } + return _whiteColor; +} + +- (UIFont *)smallFont { + if (!_smallFont) { + _smallFont = [UIFont systemFontOfSize:12]; + } + return _smallFont; +} + +- (UIFont *)mediumFont { + if (!_mediumFont) { + _mediumFont = [UIFont systemFontOfSize:14]; + } + return _mediumFont; +} + +- (UIFont *)bigFont { + if (!_bigFont) { + _bigFont = [UIFont systemFontOfSize:17]; + } + return _bigFont; +} + +#pragma mark - Primary +- (CGRect)rectWithPoint:(CGPoint)point { + CGFloat size = [self sizeBySelector] / 2.0; + return CGRectMake(point.x - size, point.y - size, size, size); +} + +- (CGFloat)sizeBySelector { + switch (self.size) { + case LLScreenshotSelectorActionSmall: + return 3; + case LLScreenshotSelectorActionMedium: + return 6; + case LLScreenshotSelectorActionBig: + return 9; + default: + break; + } + return 3; +} + +- (UIColor *)colorBySelector { + switch (self.color) { + case LLScreenshotSelectorActionRed: + return self.redColor; + case LLScreenshotSelectorActionBlue: + return self.blueColor; + case LLScreenshotSelectorActionGreen: + return self.greenColor; + case LLScreenshotSelectorActionYellow: + return self.yellowColor; + case LLScreenshotSelectorActionGray: + return self.grayColor; + case LLScreenshotSelectorActionWhite: + return self.whiteColor; + default: + break; + } + return self.whiteColor; +} + +- (UIFont *)fontBySelector { + switch (self.size) { + case LLScreenshotSelectorActionSmall: + return self.smallFont; + case LLScreenshotSelectorActionMedium: + return self.mediumFont; + case LLScreenshotSelectorActionBig: + return self.bigFont; + default: + break; + } + return self.smallFont; +} + +@end + +@implementation LLScreenshotTwoValueOperation + +@end + +@implementation LLScreenshotRectOperation + +- (void)drawImageView:(CGRect)rect { + CGRect rectPath = CGRectZero; + if (self.startValue && self.endValue) { + rectPath = [LLTool rectWithPoint:self.startValue.CGPointValue otherPoint:self.endValue.CGPointValue]; + } + [self configPathWithRect:rectPath]; +} + +- (void)configPathWithRect:(CGRect)rect { + self.path = [UIBezierPath bezierPathWithRect:rect]; + self.layer.lineWidth = [self sizeBySelector]; + self.layer.strokeColor = [self colorBySelector].CGColor; + self.layer.fillColor = nil; + self.layer.path = self.path.CGPath; +} + +@end + +@implementation LLScreenshotRoundOperation + +- (void)drawImageView:(CGRect)rect { + CGRect rectPath = CGRectZero; + if (self.startValue && self.endValue) { + rectPath = [LLTool rectWithPoint:self.startValue.CGPointValue otherPoint:self.endValue.CGPointValue]; + } + [self configPathWithRect:rectPath]; +} + +- (void)configPathWithRect:(CGRect)rect { + self.path = [UIBezierPath bezierPathWithOvalInRect:rect]; + self.layer.lineWidth = [self sizeBySelector]; + self.layer.strokeColor = [self colorBySelector].CGColor; + self.layer.fillColor = nil; + self.layer.path = self.path.CGPath; +} + +@end + +@implementation LLScreenshotLineOperation + +- (void)drawImageView:(CGRect)rect { + if (self.startValue && self.endValue) { + self.path = [UIBezierPath bezierPath]; + [self.path moveToPoint:self.startValue.CGPointValue]; + [self.path addLineToPoint:self.endValue.CGPointValue]; + self.layer.lineWidth = [self sizeBySelector]; + self.layer.strokeColor = [self colorBySelector].CGColor; + self.layer.fillColor = nil; + self.layer.path = self.path.CGPath; + } +} + +@end + +@interface LLScreenshotPenOperation () + +// CGPoint +@property (nonatomic , strong , nonnull) NSMutableArray *values; + +@end + +@implementation LLScreenshotPenOperation + +- (instancetype)initWithSelector:(LLScreenshotSelectorModel *)selector action:(LLScreenshotAction)action { + if (self = [super initWithSelector:selector action:action]) { + self.values = [[NSMutableArray alloc] init]; + } + return self; +} + +- (void)addValue:(NSValue *)value { + [self.values addObject:value]; + if (self.values.count == 1) { + [self.path moveToPoint:value.CGPointValue]; + } else { + [self.path addLineToPoint:value.CGPointValue]; + } +} + +- (void)drawImageView:(CGRect)rect { + self.layer.lineWidth = [self sizeBySelector]; + self.layer.strokeColor = [self colorBySelector].CGColor; + self.layer.fillColor = nil; + self.layer.path = self.path.CGPath; +} + +@end + +@implementation LLScreenshotTextOperation + +- (instancetype)initWithSelector:(LLScreenshotSelectorModel *)selector action:(LLScreenshotAction)action { + if (self = [super initWithSelector:selector action:action]) { + _textView = [[UITextView alloc] init]; + _textView.backgroundColor = [UIColor clearColor]; + _textView.delegate = self; + _textView.showsHorizontalScrollIndicator = NO; + _textView.showsVerticalScrollIndicator = NO; + } + return self; +} + +#pragma mark - UITextViewDelegate +- (void)textViewDidBeginEditing:(UITextView *)textView { + textView.textColor = [self colorBySelector]; + textView.font = [self fontBySelector]; +} + +- (void)textViewDidEndEditing:(UITextView *)textView { + if (textView.text.length == 0) { + [textView removeFromSuperview]; + } else { + textView.editable = NO; + textView.selectable = NO; + } +} + +- (void)textViewDidChange:(UITextView *)textView { + CGSize size = [textView sizeThatFits:CGSizeMake(textView.frame.size.width, MAXFLOAT)]; + textView.frame = CGRectMake(textView.frame.origin.x, textView.frame.origin.y, textView.frame.size.width, size.height); +} + +@end diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotDefine.h b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotDefine.h new file mode 100644 index 00000000..46009678 --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotDefine.h @@ -0,0 +1,51 @@ +// +// LLScreenshotDefine.h +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#ifndef LLScreenshotDefine_h +#define LLScreenshotDefine_h + +typedef NS_ENUM(NSUInteger, LLScreenshotAction) { + LLScreenshotActionNone = 0, + LLScreenshotActionRect = 1, + LLScreenshotActionRound = 2, + LLScreenshotActionLine = 3, + LLScreenshotActionPen = 4, + LLScreenshotActionText = 5, + LLScreenshotActionBack = 6, + LLScreenshotActionCancel = 7, + LLScreenshotActionConfirm = 8 +}; + +typedef NS_ENUM(NSUInteger, LLScreenshotSelectorAction) { + LLScreenshotSelectorActionSmall = 0, + LLScreenshotSelectorActionMedium = 1, + LLScreenshotSelectorActionBig = 2, + LLScreenshotSelectorActionRed = 3, // d81e06 + LLScreenshotSelectorActionBlue = 4, // 1296db + LLScreenshotSelectorActionGreen = 5, // 1afa29 + LLScreenshotSelectorActionYellow = 6, // f4ea2a + LLScreenshotSelectorActionGray = 7, // 2c2c2c + LLScreenshotSelectorActionWhite = 8, // ffffff +}; + +#endif /* LLScreenshotDefine_h */ diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotImageView.h b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotImageView.h new file mode 100644 index 00000000..99f24b53 --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotImageView.h @@ -0,0 +1,59 @@ +// +// LLScreenshotImageView.h +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import +#import "LLScreenshotBaseOperation.h" + +@interface LLScreenshotImageView : UIView + +/** + Image to show. + */ +@property (nonatomic , strong , nullable) UIImage *image; + +/** + Current operation. + */ +@property (nonatomic , strong , readonly , nullable) LLScreenshotBaseOperation *currentOperation; + +/** + Current action. + */ +@property (nonatomic , assign) LLScreenshotAction currentAction; + +/** + Current selector model. + */ +@property (nonatomic , strong , nullable) LLScreenshotSelectorModel *currentSelectorModel; + +/** + Specifies the initialization method. + */ +- (instancetype)initWithFrame:(CGRect)frame; + +/** + Remove last operation in operations. + */ +- (void)removeLastOperation; + +@end diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotImageView.m b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotImageView.m new file mode 100644 index 00000000..b1f262a3 --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotImageView.m @@ -0,0 +1,258 @@ +// +// LLScreenshotImageView.m +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import "LLScreenshotImageView.h" +#import "LLScreenshotBaseOperation.h" + +@interface LLScreenshotImageView () + +@property (nonatomic , strong , nonnull) UIImageView *imageView; + +@property (nonatomic , strong , nullable) LLScreenshotBaseOperation *currentOperation; + +@property (nonatomic , strong , nonnull) NSMutableArray *operations; + +@end + +@implementation LLScreenshotImageView + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + [self initial]; + } + return self; +} + +- (void)removeLastOperation { + LLScreenshotBaseOperation *operation = self.operations.lastObject; + switch (operation.action) { + case LLScreenshotActionRect: + case LLScreenshotActionRound: + case LLScreenshotActionLine: + case LLScreenshotActionPen:{ + LLScreenshotTwoValueOperation *oper = (LLScreenshotTwoValueOperation *)operation; + [oper.layer removeFromSuperlayer]; + [self.operations removeObject:oper]; + } + break; + case LLScreenshotActionText:{ + LLScreenshotTextOperation *oper = (LLScreenshotTextOperation *)operation; + [oper.textView removeFromSuperview]; + [self.operations removeObject:oper]; + } + break; + default: + break; + } +} + +#pragma mark - Touches +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + if ([self.currentOperation isKindOfClass:[LLScreenshotTextOperation class]]) { + LLScreenshotTextOperation *operation = (LLScreenshotTextOperation *)self.currentOperation; + [operation.textView resignFirstResponder]; + if (self.currentAction == LLScreenshotActionText) { + self.currentOperation = nil; + return; + } + } + + UITouch *touch = touches.anyObject; + CGPoint point = [touch locationInView:self]; + if (!CGRectContainsPoint(self.bounds, point)) { + return; + } + NSValue *pointValue = [NSValue valueWithCGPoint:point]; + switch (self.currentAction) { + case LLScreenshotActionRect:{ + LLScreenshotRectOperation *operation = [[LLScreenshotRectOperation alloc] initWithSelector:self.currentSelectorModel action:self.currentAction]; + self.currentOperation = operation; + [self.operations addObject:operation]; + [self.layer addSublayer:operation.layer]; + operation.startValue = pointValue; + [self setNeedsDisplay]; + } + break; + case LLScreenshotActionRound:{ + LLScreenshotRoundOperation *operation = [[LLScreenshotRoundOperation alloc] initWithSelector:self.currentSelectorModel action:self.currentAction]; + self.currentOperation = operation; + [self.operations addObject:operation]; + [self.layer addSublayer:operation.layer]; + operation.startValue = pointValue; + [self setNeedsDisplay]; + } + break; + case LLScreenshotActionLine:{ + LLScreenshotLineOperation *operation = [[LLScreenshotLineOperation alloc] initWithSelector:self.currentSelectorModel action:self.currentAction]; + self.currentOperation = operation; + [self.operations addObject:operation]; + [self.layer addSublayer:operation.layer]; + operation.startValue = pointValue; + [self setNeedsDisplay]; + } + break; + case LLScreenshotActionPen:{ + LLScreenshotPenOperation *operation = [[LLScreenshotPenOperation alloc] initWithSelector:self.currentSelectorModel action:self.currentAction]; + self.currentOperation = operation; + [self.operations addObject:operation]; + [self.layer addSublayer:operation.layer]; + [operation addValue:pointValue]; + [self setNeedsDisplay]; + } + break; + case LLScreenshotActionText:{ + if (self.frame.size.height - 30 < point.y) { + return; + } + LLScreenshotTextOperation *operation = [[LLScreenshotTextOperation alloc] initWithSelector:self.currentSelectorModel action:self.currentAction]; + self.currentOperation = operation; + [self.operations addObject:operation]; + [self addSubview:operation.textView]; + operation.textView.frame = CGRectMake(point.x, point.y, self.frame.size.width - point.x - 10, 30); + [operation.textView becomeFirstResponder]; + } + break; + default: + break; + } +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { + UITouch *touch = touches.anyObject; + CGPoint point = [touch locationInView:self]; + if (!CGRectContainsPoint(self.bounds, point)) { + return; + } + NSValue *pointValue = [NSValue valueWithCGPoint:point]; + switch (self.currentAction) { + case LLScreenshotActionRect:{ + LLScreenshotRectOperation *operation = (LLScreenshotRectOperation *)self.currentOperation; + operation.endValue = pointValue; + [self setNeedsDisplay]; + } + break; + case LLScreenshotActionRound:{ + LLScreenshotRoundOperation *operation = (LLScreenshotRoundOperation *)self.currentOperation; + operation.endValue = pointValue; + [self setNeedsDisplay]; + } + break; + case LLScreenshotActionLine:{ + LLScreenshotLineOperation *operation = (LLScreenshotLineOperation *)self.currentOperation; + operation.endValue = pointValue; + [self setNeedsDisplay]; + } + break; + case LLScreenshotActionPen:{ + LLScreenshotPenOperation *operation = (LLScreenshotPenOperation *)self.currentOperation; + [operation addValue:pointValue]; + [self setNeedsDisplay]; + } + break; + default: + break; + } +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { + // Call end if cancelled. + [self touchesEnded:touches withEvent:event]; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + UITouch *touch = touches.anyObject; + CGPoint point = [touch locationInView:self]; + if (!CGRectContainsPoint(self.bounds, point)) { + return; + } + NSValue *pointValue = [NSValue valueWithCGPoint:point]; + switch (self.currentAction) { + case LLScreenshotActionRect:{ + LLScreenshotRectOperation *operation = (LLScreenshotRectOperation *)self.currentOperation; + operation.endValue = pointValue; + [self setNeedsDisplay]; + } + break; + case LLScreenshotActionRound:{ + LLScreenshotRoundOperation *operation = (LLScreenshotRoundOperation *)self.currentOperation; + operation.endValue = pointValue; + [self setNeedsDisplay]; + } + break; + case LLScreenshotActionLine:{ + LLScreenshotLineOperation *operation = (LLScreenshotLineOperation *)self.currentOperation; + operation.endValue = pointValue; + [self setNeedsDisplay]; + } + break; + case LLScreenshotActionPen:{ + LLScreenshotPenOperation *operation = (LLScreenshotPenOperation *)self.currentOperation; + [operation addValue:pointValue]; + [self setNeedsDisplay]; + } + break; + default: + break; + } +} + +- (void)drawRect:(CGRect)rect { + [super drawRect:rect]; + [self.currentOperation drawImageView:rect]; +} + +#pragma mark - Primary +- (void)initial { + self.backgroundColor = [UIColor whiteColor]; + self.layer.masksToBounds = YES; + self.userInteractionEnabled = NO; + self.operations = [[NSMutableArray alloc] init]; + + self.imageView = [[UIImageView alloc] initWithFrame:self.bounds]; + self.imageView.layer.borderColor = [UIColor whiteColor].CGColor; + self.imageView.layer.borderWidth = 2; + self.imageView.layer.shadowColor = [UIColor blackColor].CGColor; + self.imageView.layer.shadowOffset = CGSizeZero; + self.imageView.layer.shadowOpacity = 0.5; + [self addSubview:self.imageView]; +} + +- (void)setImage:(UIImage *)image { + if (_image != image) { + _image = image; + self.imageView.image = image; + } +} + +- (void)setCurrentAction:(LLScreenshotAction)currentAction { + if (_currentAction != currentAction) { + _currentAction = currentAction; + if (currentAction > LLScreenshotActionNone && currentAction < LLScreenshotActionBack) { + self.userInteractionEnabled = YES; + } else { + self.userInteractionEnabled = NO; + } + } +} + +@end diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotSelectorModel.h b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotSelectorModel.h new file mode 100644 index 00000000..71e4f86b --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotSelectorModel.h @@ -0,0 +1,35 @@ +// +// LLScreenshotSelectorModel.h +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import "LLBaseModel.h" +#import "LLScreenshotDefine.h" + +@interface LLScreenshotSelectorModel : LLBaseModel + +@property (nonatomic , assign) LLScreenshotSelectorAction size; + +@property (nonatomic , assign) LLScreenshotSelectorAction color; + +- (instancetype)initWithSize:(LLScreenshotSelectorAction)size color:(LLScreenshotSelectorAction)color; + +@end diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotSelectorModel.m b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotSelectorModel.m new file mode 100644 index 00000000..fb004215 --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotSelectorModel.m @@ -0,0 +1,48 @@ +// +// LLScreenshotSelectorModel.m +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import "LLScreenshotSelectorModel.h" + +@implementation LLScreenshotSelectorModel + +- (instancetype)init { + if (self = [super init]) { + _size = LLScreenshotSelectorActionSmall; + _color = LLScreenshotSelectorActionRed; + } + return self; +} + +- (instancetype)initWithSize:(LLScreenshotSelectorAction)size color:(LLScreenshotSelectorAction)color { + if (self = [super init]) { + if (size >= LLScreenshotSelectorActionSmall && size <= LLScreenshotSelectorActionBig) { + _size = size; + } + if (color >= LLScreenshotSelectorActionRed && color <= LLScreenshotSelectorActionWhite) { + _color = color; + } + } + return self; +} + +@end diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotSelectorView.h b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotSelectorView.h new file mode 100644 index 00000000..32a22339 --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotSelectorView.h @@ -0,0 +1,41 @@ +// +// LLScreenshotSelectorView.h +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import +#import "LLScreenshotDefine.h" + +@class LLScreenshotSelectorModel; + +@interface LLScreenshotSelectorView : UIView + +/** + Specifies the initialization method. + */ +- (instancetype)initWithFrame:(CGRect)frame; + +/** + Return current selector model. + */ +- (LLScreenshotSelectorModel *)currentSelectorModel; + +@end diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotSelectorView.m b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotSelectorView.m new file mode 100644 index 00000000..1984ddbf --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotSelectorView.m @@ -0,0 +1,157 @@ +// +// LLScreenshotSelectorView.m +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import "LLScreenshotSelectorView.h" +#import "LLScreenshotSelectorModel.h" +#import "LLImageNameConfig.h" + +@interface LLScreenshotSelectorView () + +@property (nonatomic , strong) UIButton *lastSizeButton; + +@property (nonatomic , strong) UIButton *lastColorButton; + +@property (nonatomic , strong) LLScreenshotSelectorModel *model; + +@end + +@implementation LLScreenshotSelectorView + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + [self initial]; + } + return self; +} + +- (LLScreenshotSelectorModel *)currentSelectorModel { + return _model; +} + +- (void)actionButtonClicked:(UIButton *)sender { + if (sender.tag <= LLScreenshotSelectorActionBig) { + // Size button + if (self.lastSizeButton != sender) { + self.lastSizeButton.selected = NO; + sender.selected = YES; + self.lastSizeButton = sender; + self.model.size = sender.tag; + } + } else { + // Color button + if (self.lastColorButton != sender) { + self.lastColorButton.selected = NO; + self.lastColorButton.layer.borderWidth = 0; + sender.selected = YES; + sender.layer.borderWidth = 2; + self.lastColorButton = sender; + self.model.color = sender.tag; + } + } +} + +#pragma mark - Primary +- (void)initial { + self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.8]; + self.layer.cornerRadius = 5; + self.layer.masksToBounds = YES; + self.model = [[LLScreenshotSelectorModel alloc] init]; + + NSInteger count = 9; + CGFloat gap = 10; + CGFloat itemWidth = 19; + CGFloat itemHeight = 19; + CGFloat itemGap = (self.frame.size.width - gap * 2 - itemWidth * count) / (count - 1); + CGFloat top = (self.frame.size.height - itemHeight) / 2.0; + + for (int i = 0; i < count; i++) { + UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; + button.frame = CGRectMake(gap + i * (itemWidth + itemGap), top, itemWidth, itemHeight); + NSString *imageName = @""; + NSString *selectImageName = @""; + switch (i) { + case LLScreenshotSelectorActionSmall:{ + imageName = kSelectorSmallImageName; + selectImageName = kSelectorSmallSelectImageName; + button.selected = YES; + self.lastSizeButton = button; + } + break; + case LLScreenshotSelectorActionMedium:{ + imageName = kSelectorMediumImageName; + selectImageName = kSelectorMediumSelectImageName; + } + break; + case LLScreenshotSelectorActionBig:{ + imageName = kSelectorBigImageName; + selectImageName = kSelectorBigSelectImageName; + } + break; + case LLScreenshotSelectorActionRed:{ + imageName = kSelectorRedImageName; + selectImageName = kSelectorRedImageName; + button.selected = YES; + button.layer.borderWidth = 2; + self.lastColorButton = button; + } + break; + case LLScreenshotSelectorActionBlue:{ + imageName = kSelectorBlueImageName; + selectImageName = kSelectorBlueImageName; + } + break; + case LLScreenshotSelectorActionGreen:{ + imageName = kSelectorGreenImageName; + selectImageName = kSelectorGreenImageName; + } + break; + case LLScreenshotSelectorActionYellow:{ + imageName = kSelectorYellowImageName; + selectImageName = kSelectorYellowImageName; + } + break; + case LLScreenshotSelectorActionGray:{ + imageName = kSelectorGrayImageName; + selectImageName = kSelectorGrayImageName; + } + break; + case LLScreenshotSelectorActionWhite:{ + imageName = kSelectorWhiteImageName; + selectImageName = kSelectorWhiteImageName; + } + break; + default: + break; + } + [button setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal]; + [button setImage:[UIImage imageNamed:selectImageName] forState:UIControlStateSelected]; + button.tag = i; + button.showsTouchWhenHighlighted = NO; + button.adjustsImageWhenHighlighted = NO; + button.layer.borderColor = [UIColor whiteColor].CGColor; + [button addTarget:self action:@selector(actionButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; + [self addSubview:button]; + } +} + +@end diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotToolbar.h b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotToolbar.h new file mode 100644 index 00000000..dc8a3192 --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotToolbar.h @@ -0,0 +1,45 @@ +// +// LLScreenshotToolbar.h +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import +#import "LLScreenshotDefine.h" + +@class LLScreenshotToolbar; +@class LLScreenshotSelectorModel; + +@protocol LLScreenshotToolbarDelegate + +- (void)LLScreenshotToolbar:(LLScreenshotToolbar *)toolBar didSelectedAction:(LLScreenshotAction)action selectorModel:(LLScreenshotSelectorModel *)selectorModel; + +@end + +@interface LLScreenshotToolbar : UIView + +@property (nonatomic , weak , nullable) id delegate; + +/** + Specifies the initialization method. + */ +- (instancetype _Nonnull)initWithFrame:(CGRect)frame; + +@end diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotToolbar.m b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotToolbar.m new file mode 100644 index 00000000..52593e0b --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotToolbar.m @@ -0,0 +1,162 @@ +// +// LLScreenshotToolbar.m +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import "LLScreenshotToolbar.h" +#import "LLScreenshotSelectorView.h" +#import "LLScreenshotActionView.h" +#import "LLImageNameConfig.h" + +@interface LLScreenshotToolbar () + +@property (nonatomic , strong , nonnull) LLScreenshotActionView *actionView; + +@property (nonatomic , strong , nonnull) UIView *selectorBackgroundView; + +@property (nonatomic , strong , nonnull) NSMutableArray *selectorViews; + +@property (nonatomic , strong , nonnull) LLScreenshotSelectorView *lastSelectorView; + +@property (nonatomic , strong , nonnull) UIImageView *triangleView; + +@property (nonatomic , assign) BOOL selectorViewShowed; + +@end + +@implementation LLScreenshotToolbar + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + [self initial]; + } + return self; +} + +#pragma mark - Primary +- (void)initial { + self.clipsToBounds = YES; + self.selectorViews = [[NSMutableArray alloc] init]; + + CGFloat gap = 10; + CGFloat itemHeight = (self.frame.size.height - gap) /2.0; + self.actionView = [[LLScreenshotActionView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, itemHeight)]; + self.actionView.delegate = self; + [self addSubview:self.actionView]; + + self.selectorBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, self.frame.size.height, self.frame.size.width, self.frame.size.height - itemHeight)]; + self.selectorBackgroundView.backgroundColor = [UIColor clearColor]; + [self addSubview:self.selectorBackgroundView]; + + CGFloat triangleHeight = 10; + self.triangleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:kSelectorTriangleImageName]]; + self.triangleView.frame = CGRectMake(0, 0, triangleHeight * 2, triangleHeight); + [self.selectorBackgroundView addSubview:self.triangleView]; + + for (int i = 0; i < 5; i++) { + LLScreenshotSelectorView *selectorView = [[LLScreenshotSelectorView alloc] initWithFrame:CGRectMake(0, triangleHeight, self.selectorBackgroundView.frame.size.width, self.selectorBackgroundView.frame.size.height - triangleHeight)]; + [self.selectorViews addObject:selectorView]; + [self.selectorBackgroundView addSubview:selectorView]; + } + + self.lastSelectorView = [self.selectorViews firstObject]; + [self.selectorBackgroundView bringSubviewToFront:[self.selectorViews firstObject]]; +} + +- (void)showSelectorView:(NSInteger)index position:(CGFloat)position { + LLScreenshotSelectorView *selectedView = self.selectorViews[index - 1]; + if (selectedView != self.lastSelectorView) { + self.lastSelectorView = selectedView; + [self.selectorBackgroundView bringSubviewToFront:selectedView]; + } + + if (self.selectorViewShowed) { + [UIView animateWithDuration:0.25 animations:^{ + CGRect oriFrame = self.triangleView.frame; + self.triangleView.frame = CGRectMake(position - oriFrame.size.width / 2.0, oriFrame.origin.y, oriFrame.size.width, oriFrame.size.height); + }]; + } else { + [UIView animateWithDuration:0.25 animations:^{ + CGRect oriFrame = self.triangleView.frame; + CGFloat actionViewBottom = self.actionView.frame.size.height + self.actionView.frame.origin.y; + self.triangleView.frame = CGRectMake(position - oriFrame.size.width / 2.0, oriFrame.origin.y, oriFrame.size.width, oriFrame.size.height); + self.selectorBackgroundView.frame = CGRectMake(0, actionViewBottom, self.selectorBackgroundView.frame.size.width, self.selectorBackgroundView.frame.size.height); + } completion:^(BOOL finished) { + self.selectorViewShowed = YES; + }]; + } +} + +- (void)hideSelectorView { + if (self.selectorViewShowed) { + [UIView animateWithDuration:0.25 animations:^{ + self.selectorBackgroundView.frame = CGRectMake(0, self.frame.size.height, self.selectorBackgroundView.frame.size.width, self.selectorBackgroundView.frame.size.height); + } completion:^(BOOL finished) { + self.selectorViewShowed = NO; + }]; + } +} + +#pragma mark - LLScreenshotActionViewDelegate +- (void)LLScreenshotActionView:(LLScreenshotActionView *)actionView didSelectedAction:(LLScreenshotAction)action isSelected:(BOOL)isSelected position:(CGFloat)position { + switch (action) { + case LLScreenshotActionRect: + case LLScreenshotActionRound: + case LLScreenshotActionLine: + case LLScreenshotActionPen: + case LLScreenshotActionText:{ + if (isSelected) { + [self showSelectorView:action position:position]; + } else { + [self hideSelectorView]; + } + } + break; + case LLScreenshotActionBack:{ + + } + break; + case LLScreenshotActionCancel:{ + + } + break; + case LLScreenshotActionConfirm:{ + + } + break; + default: + break; + } + + if ([_delegate respondsToSelector:@selector(LLScreenshotToolbar:didSelectedAction:selectorModel:)]) { + LLScreenshotSelectorModel *model = nil; + if (action < LLScreenshotActionBack) { + if (isSelected) { + model = [self.selectorViews[action - 1] currentSelectorModel]; + } else { + action = LLScreenshotActionNone; + } + } + [_delegate LLScreenshotToolbar:self didSelectedAction:action selectorModel:model]; + } +} + +@end diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotView.h b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotView.h new file mode 100644 index 00000000..d0741de4 --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotView.h @@ -0,0 +1,43 @@ +// +// LLScreenshotView.h +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import + +@interface LLScreenshotView : UIView + +/** + Init with image. + */ +- (instancetype)initWithImage:(UIImage *)image; + +/** + Show on window. + */ +- (void)show; + +/** + Hide from window. + */ +- (void)hide; + +@end diff --git a/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotView.m b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotView.m new file mode 100644 index 00000000..f5d22501 --- /dev/null +++ b/LLDebugTool/UserInterface/Others/ScreenShotView/LLScreenshotView.m @@ -0,0 +1,194 @@ +// +// LLScreenshotView.m +// +// Copyright (c) 2018 LLDebugTool Software Foundation (https://github.com/HDB-Li/LLDebugTool) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import "LLScreenshotView.h" +#import +#import "LLScreenshotBaseOperation.h" +#import "LLScreenshotImageView.h" +#import "LLScreenshotToolbar.h" +#import "LLStorageManager.h" +#import "LLDebugTool.h" +#import "LLWindow.h" +#import "LLMacros.h" +#import "LLTool.h" + +@interface LLScreenshotView () + +@property (nonatomic , strong , nonnull) LLScreenshotImageView *imageView; + +@property (nonatomic , strong , nonnull) LLScreenshotToolbar *toolBar; + +@property (nonatomic , assign) CGRect originalImageFrame; + +@property (nonatomic , copy , nonnull) NSString *name; + +@end + +@implementation LLScreenshotView + +- (instancetype)initWithImage:(UIImage *)image { + if (self = [super initWithFrame:[UIScreen mainScreen].bounds]) { + [self initialWithImage:image]; + } + return self; +} + +- (void)show { + UIWindow *window = [UIApplication sharedApplication].delegate.window; + self.frame = CGRectMake(0, LL_SCREEN_HEIGHT, LL_SCREEN_WIDTH, LL_SCREEN_HEIGHT); + [window addSubview:self]; + [[LLDebugTool sharedTool].window hideWindow]; + [UIView animateWithDuration:0.25 delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:5.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ + self.frame = CGRectMake(0, 0, LL_SCREEN_WIDTH, LL_SCREEN_HEIGHT); + } completion:^(BOOL finished) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShowNotification:) name:UIKeyboardWillShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideNotification:) name:UIKeyboardWillHideNotification object:nil]; + }]; +} + +- (void)hide { + [UIView animateWithDuration:0.25 delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:5.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ + self.frame = CGRectMake(0, LL_SCREEN_HEIGHT, LL_SCREEN_WIDTH, LL_SCREEN_HEIGHT); + } completion:^(BOOL finished) { + [self removeFromSuperview]; + [[LLDebugTool sharedTool].window showWindow]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + }]; +} + +- (void)cancelAction { + [self hide]; +} + +- (void)confirmAction { + self.hidden = YES; + __weak __block typeof(self) weakSelf = self; + __block UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Note" message:@"Enter the image name" preferredStyle:UIAlertControllerStyleAlert]; + [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { + textField.text = weakSelf.name; + }]; + UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { + weakSelf.hidden = NO; + }]; + UIAlertAction *confirm = [UIAlertAction actionWithTitle:@"Confirm" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + weakSelf.hidden = NO; + [weakSelf doConfirmAction:alert.textFields.firstObject.text]; + }]; + [alert addAction:cancel]; + [alert addAction:confirm]; + + [[UIApplication sharedApplication].delegate.window.rootViewController presentViewController:alert animated:YES completion:nil]; +} + +- (void)doConfirmAction:(NSString *)name { + self.toolBar.hidden = YES; + UIImage *image = [self convertViewToImage:self.imageView]; + if (image) { + [[LLStorageManager sharedManager] saveScreenshot:image name:name]; + if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { + UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); + [[LLTool sharedTool] toastMessage:@"Save image in sandbox and album."]; + } else { + [[LLTool sharedTool] toastMessage:@"Save image in sandbox."]; + } + [self hide]; + } else { + self.toolBar.hidden = NO; + [[LLTool sharedTool] toastMessage:@"Save image failed."]; + } +} + +#pragma mark - NSNotification +- (void)keyboardWillShowNotification:(NSNotification *)notifi { + NSDictionary *userInfo = notifi.userInfo; + CGFloat duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + CGRect endFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; + if ([self.imageView.currentOperation isKindOfClass:[LLScreenshotTextOperation class]]) { + LLScreenshotTextOperation *operation = (LLScreenshotTextOperation *)self.imageView.currentOperation; + CGFloat y = operation.textView.frame.origin.y + self.originalImageFrame.origin.y; + CGFloat gap = y - endFrame.origin.y + 100; + if (gap > 0) { + [UIView animateWithDuration:duration animations:^{ + CGRect oriRect = self.imageView.frame; + self.imageView.frame = CGRectMake(oriRect.origin.x, self.originalImageFrame.origin.y - gap, oriRect.size.width, oriRect.size.height); + }]; + } + } +} + +- (void)keyboardWillHideNotification:(NSNotification *)notifi { + NSDictionary *userInfo = notifi.userInfo; + CGFloat duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + if (!CGRectEqualToRect(self.imageView.frame, self.originalImageFrame)) { + [UIView animateWithDuration:duration animations:^{ + self.imageView.frame = self.originalImageFrame; + }]; + } +} + +#pragma mark - Primary +- (void)initialWithImage:(UIImage *)image { + self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; + self.name = [[LLTool sharedTool] staticStringFromDate:[NSDate date]]; + + CGFloat rate = 0.1; + CGFloat toolBarHeight = 80; + CGFloat imgViewWidth = (1 - rate * 2) * LL_SCREEN_WIDTH; + CGFloat imgViewHeight = (1 - rate * 2) * LL_SCREEN_HEIGHT; + CGFloat imgViewTop = (rate * 2 * LL_SCREEN_HEIGHT - toolBarHeight) / 2.0; + // Init ImageView + self.imageView = [[LLScreenshotImageView alloc] initWithFrame:CGRectMake(rate * LL_SCREEN_WIDTH, imgViewTop, imgViewWidth, imgViewHeight)]; + self.originalImageFrame = self.imageView.frame; + self.imageView.image = image; + [self addSubview:self.imageView]; + + // Init Controls + self.toolBar = [[LLScreenshotToolbar alloc] initWithFrame:CGRectMake(self.imageView.frame.origin.x, self.imageView.frame.origin.y + self.imageView.frame.size.height + 10, self.imageView.frame.size.width, toolBarHeight)]; + self.toolBar.delegate = self; + [self addSubview:self.toolBar]; +} + +- (UIImage *)convertViewToImage:(UIView *)view{ + CGSize size = view.bounds.size; + UIGraphicsBeginImageContextWithOptions(size, YES, [UIScreen mainScreen].scale); + [view.layer renderInContext:UIGraphicsGetCurrentContext()]; + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return image; +} + +#pragma mark - LLScreenshotToolbarDelegate +- (void)LLScreenshotToolbar:(LLScreenshotToolbar *)toolBar didSelectedAction:(LLScreenshotAction)action selectorModel:(LLScreenshotSelectorModel *)selectorModel { + if (action <= LLScreenshotActionText) { + self.imageView.currentAction = action; + self.imageView.currentSelectorModel = selectorModel; + } else if (action == LLScreenshotActionBack) { + [self.imageView removeLastOperation]; + } else if (action == LLScreenshotActionCancel) { + [self cancelAction]; + } else if (action == LLScreenshotActionConfirm) { + [self confirmAction]; + } +} + +@end diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-cancel@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-cancel@2x.png new file mode 100644 index 00000000..3db315c9 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-cancel@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-cancel@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-cancel@3x.png new file mode 100644 index 00000000..d91e207e Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-cancel@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-line-select@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-line-select@2x.png new file mode 100644 index 00000000..5b9d003b Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-line-select@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-line-select@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-line-select@3x.png new file mode 100644 index 00000000..33751a72 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-line-select@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-line@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-line@2x.png new file mode 100644 index 00000000..57370f2d Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-line@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-line@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-line@3x.png new file mode 100644 index 00000000..1e40ae5b Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-line@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-pen-select@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-pen-select@2x.png new file mode 100644 index 00000000..b8e0e81f Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-pen-select@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-pen-select@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-pen-select@3x.png new file mode 100644 index 00000000..db619ba2 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-pen-select@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-pen@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-pen@2x.png new file mode 100644 index 00000000..7a6afe8d Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-pen@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-pen@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-pen@3x.png new file mode 100644 index 00000000..bb79063b Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-pen@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-rect-select@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-rect-select@2x.png new file mode 100644 index 00000000..4c07debf Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-rect-select@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-rect-select@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-rect-select@3x.png new file mode 100644 index 00000000..0f18c7ff Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-rect-select@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-rect@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-rect@2x.png new file mode 100644 index 00000000..2bf28810 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-rect@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-rect@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-rect@3x.png new file mode 100644 index 00000000..6331675d Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-rect@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-round-select@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-round-select@2x.png new file mode 100644 index 00000000..b35469e0 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-round-select@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-round-select@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-round-select@3x.png new file mode 100644 index 00000000..d19b8433 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-round-select@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-round@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-round@2x.png new file mode 100644 index 00000000..1280bc20 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-round@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-round@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-round@3x.png new file mode 100644 index 00000000..aff235b4 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-round@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-arrow@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-arrow@3x.png new file mode 100644 index 00000000..af39d542 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-arrow@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-big-select@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-big-select@2x.png new file mode 100644 index 00000000..972e0a35 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-big-select@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-big-select@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-big-select@3x.png new file mode 100644 index 00000000..de05d1a2 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-big-select@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-big@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-big@2x.png new file mode 100644 index 00000000..48fd898a Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-big@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-big@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-big@3x.png new file mode 100644 index 00000000..8c36ad31 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-big@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-blue@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-blue@2x.png new file mode 100644 index 00000000..f95d9cdd Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-blue@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-blue@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-blue@3x.png new file mode 100644 index 00000000..e78757ba Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-blue@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-gray@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-gray@2x.png new file mode 100644 index 00000000..7ece36ab Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-gray@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-gray@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-gray@3x.png new file mode 100644 index 00000000..de47efc0 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-gray@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-green@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-green@2x.png new file mode 100644 index 00000000..e9e7dc31 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-green@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-green@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-green@3x.png new file mode 100644 index 00000000..1018e8e5 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-green@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-medium-select@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-medium-select@2x.png new file mode 100644 index 00000000..0a84e5b9 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-medium-select@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-medium-select@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-medium-select@3x.png new file mode 100644 index 00000000..88103eb3 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-medium-select@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-medium@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-medium@2x.png new file mode 100644 index 00000000..af9e8021 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-medium@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-medium@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-medium@3x.png new file mode 100644 index 00000000..717a7c1a Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-medium@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-red@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-red@2x.png new file mode 100644 index 00000000..507600fa Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-red@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-red@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-red@3x.png new file mode 100644 index 00000000..258023cb Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-red@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-small-select@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-small-select@2x.png new file mode 100644 index 00000000..0d20f2ee Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-small-select@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-small-select@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-small-select@3x.png new file mode 100644 index 00000000..4c60829e Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-small-select@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-small@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-small@2x.png new file mode 100644 index 00000000..3bb1e0ee Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-small@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-small@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-small@3x.png new file mode 100644 index 00000000..04fecb86 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-small@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-triangle@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-triangle@2x.png new file mode 100644 index 00000000..9eb6eae9 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-triangle@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-triangle@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-triangle@3x.png new file mode 100644 index 00000000..28063b85 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-triangle@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-white@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-white@2x.png new file mode 100644 index 00000000..7868b837 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-white@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-white@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-white@3x.png new file mode 100644 index 00000000..7a407274 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-white@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-yellow@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-yellow@2x.png new file mode 100644 index 00000000..51984f0f Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-yellow@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-yellow@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-yellow@3x.png new file mode 100644 index 00000000..916ed418 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-selector-yellow@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-sure@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-sure@2x.png new file mode 100644 index 00000000..34c32bd3 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-sure@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-sure@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-sure@3x.png new file mode 100644 index 00000000..8859ca60 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-sure@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-text-select@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-text-select@2x.png new file mode 100644 index 00000000..c0b46a78 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-text-select@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-text-select@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-text-select@3x.png new file mode 100644 index 00000000..08a3e69e Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-text-select@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-text@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-text@2x.png new file mode 100644 index 00000000..291e9d08 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-text@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-text@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-text@3x.png new file mode 100644 index 00000000..71776b6b Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-text@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-undo-disable@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-undo-disable@2x.png new file mode 100644 index 00000000..232a4f36 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-undo-disable@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-undo-disable@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-undo-disable@3x.png new file mode 100644 index 00000000..2e75967e Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-undo-disable@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-undo@2x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-undo@2x.png new file mode 100644 index 00000000..beeab4e2 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-undo@2x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-undo@3x.png b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-undo@3x.png new file mode 100644 index 00000000..9833b5c1 Binary files /dev/null and b/LLDebugTool/UserInterface/Resources/LLDebugTool.bundle/LL-undo@3x.png differ diff --git a/LLDebugTool/UserInterface/Resources/LLImageNameConfig.h b/LLDebugTool/UserInterface/Resources/LLImageNameConfig.h index e13aedab..3c494f33 100644 --- a/LLDebugTool/UserInterface/Resources/LLImageNameConfig.h +++ b/LLDebugTool/UserInterface/Resources/LLImageNameConfig.h @@ -26,4 +26,36 @@ static NSString *const kDoneImageName = @"LLDebugTool.bundle/LL-done"; static NSString *const kFolderImageName = @"LLDebugTool.bundle/LL-folder"; static NSString *const kEmptyFolderImageName = @"LLDebugTool.bundle/LL-folder-empty"; +// Draw 0x148816 +static NSString *const kCancelImageName = @"LLDebugTool.bundle/LL-cancel"; +static NSString *const kLineImageName = @"LLDebugTool.bundle/LL-line"; +static NSString *const kLineSelectImageName = @"LLDebugTool.bundle/LL-line-select"; +static NSString *const kPenImageName = @"LLDebugTool.bundle/LL-pen"; +static NSString *const kPenSelectImageName = @"LLDebugTool.bundle/LL-pen-select"; +static NSString *const kRectImageName = @"LLDebugTool.bundle/LL-rect"; +static NSString *const kRectSelectImageName = @"LLDebugTool.bundle/LL-rect-select"; +static NSString *const kRoundImageName = @"LLDebugTool.bundle/LL-round"; +static NSString *const kRoundSelectImageName = @"LLDebugTool.bundle/LL-round-select"; +static NSString *const kSureImageName = @"LLDebugTool.bundle/LL-sure"; +static NSString *const kTextImageName = @"LLDebugTool.bundle/LL-text"; +static NSString *const kTextSelectImageName = @"LLDebugTool.bundle/LL-text-select"; +static NSString *const kUndoImageName = @"LLDebugTool.bundle/LL-undo"; +static NSString *const kUndoDisableImageName = @"LLDebugTool.bundle/LL-undo-disable"; + +// Selector +static NSString *const kSelectorTriangleImageName = @"LLDebugTool.bundle/LL-selector-triangle"; +static NSString *const kSelectorSmallImageName = @"LLDebugTool.bundle/LL-selector-small"; +static NSString *const kSelectorSmallSelectImageName = @"LLDebugTool.bundle/LL-selector-small-select"; +static NSString *const kSelectorMediumImageName = @"LLDebugTool.bundle/LL-selector-medium"; +static NSString *const kSelectorMediumSelectImageName = @"LLDebugTool.bundle/LL-selector-medium-select"; +static NSString *const kSelectorBigImageName = @"LLDebugTool.bundle/LL-selector-big"; +static NSString *const kSelectorBigSelectImageName = @"LLDebugTool.bundle/LL-selector-big-select"; +static NSString *const kSelectorRedImageName = @"LLDebugTool.bundle/LL-selector-red"; +static NSString *const kSelectorBlueImageName = @"LLDebugTool.bundle/LL-selector-blue"; +static NSString *const kSelectorGreenImageName = @"LLDebugTool.bundle/LL-selector-green"; +static NSString *const kSelectorYellowImageName = @"LLDebugTool.bundle/LL-selector-yellow"; +static NSString *const kSelectorGrayImageName = @"LLDebugTool.bundle/LL-selector-gray"; +static NSString *const kSelectorWhiteImageName = @"LLDebugTool.bundle/LL-selector-white"; +static NSString *const kSelectorArrowImageName = @"LLDebugTool.bundle/LL-selector-arrow"; + #endif /* LLImageNameConfig_h */ diff --git a/LLDebugTool/UserInterface/Sections/Sandbox/LLSandboxVC.m b/LLDebugTool/UserInterface/Sections/Sandbox/LLSandboxVC.m index f0e0f62c..36d0552c 100644 --- a/LLDebugTool/UserInterface/Sections/Sandbox/LLSandboxVC.m +++ b/LLDebugTool/UserInterface/Sections/Sandbox/LLSandboxVC.m @@ -68,6 +68,7 @@ - (void)rightItemClick { } } else { btn.selected = !btn.selected; + self.selectAllItem.title = @"Select All"; [self.tableView setEditing:NO animated:YES]; [self.navigationController setToolbarHidden:YES animated:YES]; } diff --git a/LLDebugTool/UserInterface/Sections/Window/LLWindowViewController.m b/LLDebugTool/UserInterface/Sections/Window/LLWindowViewController.m index cc0c053b..07e14cbc 100644 --- a/LLDebugTool/UserInterface/Sections/Window/LLWindowViewController.m +++ b/LLDebugTool/UserInterface/Sections/Window/LLWindowViewController.m @@ -22,17 +22,18 @@ // SOFTWARE. #import "LLWindowViewController.h" -#import "LLMacros.h" -#import "LLWindow.h" -#import "LLCrashVC.h" +#import "LLBaseNavigationController.h" +#import "LLScreenshotHelper.h" +#import "LLImageNameConfig.h" #import "LLNetworkVC.h" -#import "LLLogVC.h" #import "LLAppInfoVC.h" #import "LLSandboxVC.h" #import "LLAppHelper.h" +#import "LLCrashVC.h" +#import "LLMacros.h" +#import "LLWindow.h" #import "LLConfig.h" -#import "LLImageNameConfig.h" -#import "LLBaseNavigationController.h" +#import "LLLogVC.h" @interface LLWindowViewController () @@ -184,6 +185,12 @@ - (void)createGestureRecognizer { UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapGR:)]; [self.sBallView addGestureRecognizer:tap]; + + UITapGestureRecognizer *tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapGR:)]; + tap2.numberOfTapsRequired = 2; + [self.sBallView addGestureRecognizer:tap2]; + + [tap requireGestureRecognizerToFail:tap2]; } - (void)becomeActive { @@ -269,6 +276,10 @@ - (void)tapGR:(UITapGestureRecognizer *)gr { [self showDebugViewControllerWithIndex:0]; } +- (void)doubleTapGR:(UITapGestureRecognizer *)gr { + [[LLScreenshotHelper sharedHelper] simulateTakeScreenshot]; +} + #pragma mark - Lazy load - (UITabBarController *)tabVC { if (_tabVC == nil) { diff --git a/LLDebugTool/UserInterface/Tool/LLTool.h b/LLDebugTool/UserInterface/Tool/LLTool.h index 9c1f27f3..8ead6500 100644 --- a/LLDebugTool/UserInterface/Tool/LLTool.h +++ b/LLDebugTool/UserInterface/Tool/LLTool.h @@ -68,4 +68,14 @@ Convert data to JSONString. */ + (NSString *)prettyJSONStringFromData:(NSData *)data; + +/** + Get rect from two point + */ ++ (CGRect)rectWithPoint:(CGPoint)point otherPoint:(CGPoint)otherPoint; + +/** + Show toast. + */ +- (void)toastMessage:(NSString *)message; @end diff --git a/LLDebugTool/UserInterface/Tool/LLTool.m b/LLDebugTool/UserInterface/Tool/LLTool.m index 5ee9d1b7..27ccf0ea 100644 --- a/LLDebugTool/UserInterface/Tool/LLTool.m +++ b/LLDebugTool/UserInterface/Tool/LLTool.m @@ -23,6 +23,7 @@ #import "LLTool.h" #import "LLConfig.h" +#import "LLMacros.h" static LLTool *_instance = nil; @@ -34,6 +35,8 @@ @interface LLTool () @property (nonatomic , strong) NSDateFormatter *staticDateFormatter; +@property (nonatomic , strong) UILabel *toastLabel; + @end @implementation LLTool @@ -107,6 +110,59 @@ + (NSString *)prettyJSONStringFromData:(NSData *)data return prettyString; } ++ (CGRect)rectWithPoint:(CGPoint)point otherPoint:(CGPoint)otherPoint { + + CGFloat x = MIN(point.x, otherPoint.x); + CGFloat y = MIN(point.y, otherPoint.y); + CGFloat maxX = MAX(point.x, otherPoint.x); + CGFloat maxY = MAX(point.y, otherPoint.y); + CGFloat width = maxX - x; + CGFloat height = maxY - y; + // Return rect nearby + CGFloat gap = 1 / 2.0; + if (width == 0) { + width = gap; + } + if (height == 0) { + height = gap; + } + return CGRectMake(x, y, width, height); +} + +- (void)toastMessage:(NSString *)message { + if (self.toastLabel) { + [self.toastLabel removeFromSuperview]; + self.toastLabel = nil; + } + + __block UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 0, LL_SCREEN_WIDTH - 40, 100)]; + label.text = message; + label.textAlignment = NSTextAlignmentCenter; + label.numberOfLines = 0; + label.lineBreakMode = NSLineBreakByCharWrapping; + [label sizeToFit]; + label.frame = CGRectMake(0, 0, label.frame.size.width + 20, label.frame.size.height + 10); + label.layer.cornerRadius = label.font.lineHeight / 2.0; + label.layer.masksToBounds = YES; + label.center = CGPointMake(LL_SCREEN_WIDTH / 2.0, LL_SCREEN_HEIGHT / 2.0); + label.alpha = 0; + label.backgroundColor = [UIColor blackColor]; + label.textColor = [UIColor whiteColor]; + [[UIApplication sharedApplication].keyWindow addSubview:label]; + self.toastLabel = label; + [UIView animateWithDuration:0.25 animations:^{ + label.alpha = 1; + } completion:^(BOOL finished) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [UIView animateWithDuration:0.1 animations:^{ + label.alpha = 0; + } completion:^(BOOL finished) { + [label removeFromSuperview]; + }]; + }); + }]; +} + #pragma mark - Lazy load - (NSDateFormatter *)dateFormatter { if (!_dateFormatter) { diff --git a/LLDebugToolDemo.xcodeproj/project.pbxproj b/LLDebugToolDemo.xcodeproj/project.pbxproj index 9ddbaf32..22aeddd8 100644 --- a/LLDebugToolDemo.xcodeproj/project.pbxproj +++ b/LLDebugToolDemo.xcodeproj/project.pbxproj @@ -9,11 +9,20 @@ /* Begin PBXBuildFile section */ 208678B3E17E2AAB3B0E945F /* libPods-LLDebugToolDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 533ECC0E7675B1A81455CB56 /* libPods-LLDebugToolDemo.a */; }; 3602DC532099C4AF00F8CE50 /* LLBaseTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3602DC522099C4AF00F8CE50 /* LLBaseTableViewCell.m */; }; - 3603254D20BFC69800987B80 /* NetTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 3603254C20BFC69800987B80 /* NetTool.m */; }; 367E27A120A1A8480032EF0D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 367E27A320A1A8480032EF0D /* Localizable.strings */; }; 367E855720A68EC100E5B472 /* LLSubTitleTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 367E855520A68EC100E5B472 /* LLSubTitleTableViewCell.m */; }; 367E855820A68EC100E5B472 /* LLSubTitleTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 367E855620A68EC100E5B472 /* LLSubTitleTableViewCell.xib */; }; 367F94C7209AF38300CA1821 /* LLBaseNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 367F94C6209AF38300CA1821 /* LLBaseNavigationController.m */; }; + 3687521F20C69B22002C6AD9 /* LLScreenshotView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3687521120C69B21002C6AD9 /* LLScreenshotView.m */; }; + 3687522020C69B22002C6AD9 /* LLScreenshotActionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3687521220C69B21002C6AD9 /* LLScreenshotActionView.m */; }; + 3687522120C69B22002C6AD9 /* LLScreenshotBaseOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 3687521620C69B21002C6AD9 /* LLScreenshotBaseOperation.m */; }; + 3687522220C69B22002C6AD9 /* LLScreenshotSelectorModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3687521920C69B22002C6AD9 /* LLScreenshotSelectorModel.m */; }; + 3687522320C69B22002C6AD9 /* LLScreenshotToolbar.m in Sources */ = {isa = PBXBuildFile; fileRef = 3687521B20C69B22002C6AD9 /* LLScreenshotToolbar.m */; }; + 3687522420C69B22002C6AD9 /* LLScreenshotSelectorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3687521C20C69B22002C6AD9 /* LLScreenshotSelectorView.m */; }; + 3687522520C69B22002C6AD9 /* LLScreenshotImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3687521D20C69B22002C6AD9 /* LLScreenshotImageView.m */; }; + 3691A61B20C7E63B00E22192 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3691A61D20C7E63B00E22192 /* InfoPlist.strings */; }; + 36A0007720BE863700AE8810 /* NetTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 36A0007620BE863700AE8810 /* NetTool.m */; }; + 36AE43DB20C788E90066EA41 /* LLScreenshotHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 36AE43DA20C788E90066EA41 /* LLScreenshotHelper.m */; }; 36C5BF782099897F007A3188 /* LLConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 36C5BEEE2099897F007A3188 /* LLConfig.m */; }; 36C5BF792099897F007A3188 /* LLCrashHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 36C5BEF22099897F007A3188 /* LLCrashHelper.m */; }; 36C5BF7A2099897F007A3188 /* LLStorageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 36C5BEF52099897F007A3188 /* LLStorageManager.m */; }; @@ -84,8 +93,7 @@ 0857CAF55E62609DE772D43C /* Pods-LLDebugToolDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LLDebugToolDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-LLDebugToolDemo/Pods-LLDebugToolDemo.release.xcconfig"; sourceTree = ""; }; 3602DC512099C4AF00F8CE50 /* LLBaseTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LLBaseTableViewCell.h; sourceTree = ""; }; 3602DC522099C4AF00F8CE50 /* LLBaseTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LLBaseTableViewCell.m; sourceTree = ""; }; - 3603254B20BFC69800987B80 /* NetTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetTool.h; sourceTree = ""; }; - 3603254C20BFC69800987B80 /* NetTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NetTool.m; sourceTree = ""; }; + 365D4D7020C91B3900A5D59E /* LLDebugToolMacros.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LLDebugToolMacros.h; sourceTree = ""; }; 367E279720A1A7880032EF0D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = ""; }; 367E279820A1A7880032EF0D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LaunchScreen.strings"; sourceTree = ""; }; 367E27A220A1A8480032EF0D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; @@ -95,6 +103,27 @@ 367E855620A68EC100E5B472 /* LLSubTitleTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LLSubTitleTableViewCell.xib; sourceTree = ""; }; 367F94C5209AF38300CA1821 /* LLBaseNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LLBaseNavigationController.h; sourceTree = ""; }; 367F94C6209AF38300CA1821 /* LLBaseNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LLBaseNavigationController.m; sourceTree = ""; }; + 3687521020C69B21002C6AD9 /* LLScreenshotView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLScreenshotView.h; sourceTree = ""; }; + 3687521120C69B21002C6AD9 /* LLScreenshotView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLScreenshotView.m; sourceTree = ""; }; + 3687521220C69B21002C6AD9 /* LLScreenshotActionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLScreenshotActionView.m; sourceTree = ""; }; + 3687521320C69B21002C6AD9 /* LLScreenshotActionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLScreenshotActionView.h; sourceTree = ""; }; + 3687521420C69B21002C6AD9 /* LLScreenshotImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLScreenshotImageView.h; sourceTree = ""; }; + 3687521520C69B21002C6AD9 /* LLScreenshotSelectorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLScreenshotSelectorView.h; sourceTree = ""; }; + 3687521620C69B21002C6AD9 /* LLScreenshotBaseOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLScreenshotBaseOperation.m; sourceTree = ""; }; + 3687521720C69B21002C6AD9 /* LLScreenshotDefine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLScreenshotDefine.h; sourceTree = ""; }; + 3687521820C69B21002C6AD9 /* LLScreenshotSelectorModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLScreenshotSelectorModel.h; sourceTree = ""; }; + 3687521920C69B22002C6AD9 /* LLScreenshotSelectorModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLScreenshotSelectorModel.m; sourceTree = ""; }; + 3687521A20C69B22002C6AD9 /* LLScreenshotBaseOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLScreenshotBaseOperation.h; sourceTree = ""; }; + 3687521B20C69B22002C6AD9 /* LLScreenshotToolbar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLScreenshotToolbar.m; sourceTree = ""; }; + 3687521C20C69B22002C6AD9 /* LLScreenshotSelectorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLScreenshotSelectorView.m; sourceTree = ""; }; + 3687521D20C69B22002C6AD9 /* LLScreenshotImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLScreenshotImageView.m; sourceTree = ""; }; + 3687521E20C69B22002C6AD9 /* LLScreenshotToolbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLScreenshotToolbar.h; sourceTree = ""; }; + 3691A61C20C7E63B00E22192 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 3691A61E20C7E63D00E22192 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 36A0007520BE863700AE8810 /* NetTool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NetTool.h; sourceTree = ""; }; + 36A0007620BE863700AE8810 /* NetTool.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NetTool.m; sourceTree = ""; }; + 36AE43D920C788E90066EA41 /* LLScreenshotHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLScreenshotHelper.h; sourceTree = ""; }; + 36AE43DA20C788E90066EA41 /* LLScreenshotHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLScreenshotHelper.m; sourceTree = ""; }; 36C5BEEE2099897F007A3188 /* LLConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLConfig.m; sourceTree = ""; }; 36C5BEEF2099897F007A3188 /* LLConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLConfig.h; sourceTree = ""; }; 36C5BEF22099897F007A3188 /* LLCrashHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLCrashHelper.m; sourceTree = ""; }; @@ -232,6 +261,37 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 3687520F20C69B12002C6AD9 /* ScreenshotView */ = { + isa = PBXGroup; + children = ( + 3687521720C69B21002C6AD9 /* LLScreenshotDefine.h */, + 3687521020C69B21002C6AD9 /* LLScreenshotView.h */, + 3687521120C69B21002C6AD9 /* LLScreenshotView.m */, + 3687521420C69B21002C6AD9 /* LLScreenshotImageView.h */, + 3687521D20C69B22002C6AD9 /* LLScreenshotImageView.m */, + 3687521E20C69B22002C6AD9 /* LLScreenshotToolbar.h */, + 3687521B20C69B22002C6AD9 /* LLScreenshotToolbar.m */, + 3687521320C69B21002C6AD9 /* LLScreenshotActionView.h */, + 3687521220C69B21002C6AD9 /* LLScreenshotActionView.m */, + 3687521520C69B21002C6AD9 /* LLScreenshotSelectorView.h */, + 3687521C20C69B22002C6AD9 /* LLScreenshotSelectorView.m */, + 3687521820C69B21002C6AD9 /* LLScreenshotSelectorModel.h */, + 3687521920C69B22002C6AD9 /* LLScreenshotSelectorModel.m */, + 3687521A20C69B22002C6AD9 /* LLScreenshotBaseOperation.h */, + 3687521620C69B21002C6AD9 /* LLScreenshotBaseOperation.m */, + ); + path = ScreenshotView; + sourceTree = ""; + }; + 36AE43D820C788E90066EA41 /* ScreenshotHelper */ = { + isa = PBXGroup; + children = ( + 36AE43D920C788E90066EA41 /* LLScreenshotHelper.h */, + 36AE43DA20C788E90066EA41 /* LLScreenshotHelper.m */, + ); + path = ScreenshotHelper; + sourceTree = ""; + }; 36C5BEED2099897F007A3188 /* Config */ = { isa = PBXGroup; children = ( @@ -244,6 +304,7 @@ 36C5BEF02099897F007A3188 /* Helper */ = { isa = PBXGroup; children = ( + 36AE43D820C788E90066EA41 /* ScreenshotHelper */, 36C5BEF12099897F007A3188 /* CrashHelper */, 36C5BEF42099897F007A3188 /* StorageManager */, 36C5BEF72099897F007A3188 /* AppHelper */, @@ -438,6 +499,7 @@ 36C5BF3E2099897F007A3188 /* Others */ = { isa = PBXGroup; children = ( + 3687520F20C69B12002C6AD9 /* ScreenshotView */, 36C5BF402099897F007A3188 /* FilterView */, 36C5BF592099897F007A3188 /* LLMacros.h */, 36C5BF3F2099897F007A3188 /* YWFilePreviewController.h */, @@ -581,6 +643,7 @@ children = ( 36C5BF772099897F007A3188 /* LLDebugTool.h */, 36C5BF762099897F007A3188 /* LLDebugTool.m */, + 365D4D7020C91B3900A5D59E /* LLDebugToolMacros.h */, ); path = DebugTool; sourceTree = ""; @@ -615,8 +678,8 @@ C43BA809205AB095006307BE /* LLDebugToolDemo */ = { isa = PBXGroup; children = ( - 3603254B20BFC69800987B80 /* NetTool.h */, - 3603254C20BFC69800987B80 /* NetTool.m */, + 36A0007520BE863700AE8810 /* NetTool.h */, + 36A0007620BE863700AE8810 /* NetTool.m */, C43BA80A205AB095006307BE /* AppDelegate.h */, C43BA80B205AB095006307BE /* AppDelegate.m */, C43BA80D205AB095006307BE /* ViewController.h */, @@ -627,6 +690,7 @@ C43BA818205AB095006307BE /* Info.plist */, C43BA819205AB095006307BE /* main.m */, 367E27A320A1A8480032EF0D /* Localizable.strings */, + 3691A61D20C7E63B00E22192 /* InfoPlist.strings */, ); path = LLDebugToolDemo; sourceTree = ""; @@ -663,8 +727,6 @@ C43BA803205AB095006307BE /* Sources */, C43BA804205AB095006307BE /* Frameworks */, C43BA805205AB095006307BE /* Resources */, - 26F08AEA5492BC3B938C7190 /* [CP] Embed Pods Frameworks */, - 97DC28EB89EC5A3F8BA895DC /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -681,7 +743,7 @@ C43BA7FF205AB095006307BE /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0900; + LastUpgradeCheck = 0930; ORGANIZATIONNAME = li; TargetAttributes = { C43BA806205AB095006307BE = { @@ -718,6 +780,7 @@ 367E855820A68EC100E5B472 /* LLSubTitleTableViewCell.xib in Resources */, 36C5BF922099897F007A3188 /* LLSandboxCell.xib in Resources */, 36C5BF862099897F007A3188 /* LLNetworkImageCell.xib in Resources */, + 3691A61B20C7E63B00E22192 /* InfoPlist.strings in Resources */, 36C5BF972099897F007A3188 /* LLLogCell.xib in Resources */, 36C5BFA32099897F007A3188 /* LLFilterLabelCell.xib in Resources */, C43BA817205AB095006307BE /* LaunchScreen.storyboard in Resources */, @@ -734,21 +797,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 26F08AEA5492BC3B938C7190 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LLDebugToolDemo/Pods-LLDebugToolDemo-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; 6E3CB1D4BAA2CB6C13E12F68 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -767,21 +815,6 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 97DC28EB89EC5A3F8BA895DC /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LLDebugToolDemo/Pods-LLDebugToolDemo-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -794,6 +827,7 @@ 36C5BFAA2099897F007A3188 /* NSString+LL_Utils.m in Sources */, 36C5BFAD2099897F007A3188 /* LLBaseViewController.m in Sources */, 36C5BF9C2099897F007A3188 /* LLFilterOtherView.m in Sources */, + 36AE43DB20C788E90066EA41 /* LLScreenshotHelper.m in Sources */, 36C5BF7D2099897F007A3188 /* LLSandboxModel.m in Sources */, 36C5BFB02099897F007A3188 /* LLDebugTool.m in Sources */, 36C5BF8E2099897F007A3188 /* LLCrashVC.m in Sources */, @@ -801,6 +835,7 @@ 36C5BF7F2099897F007A3188 /* LLLogHelper.m in Sources */, 36C5BFA62099897F007A3188 /* LLFilterEventView.m in Sources */, 36C5BF842099897F007A3188 /* LLNetworkVC.m in Sources */, + 3687522120C69B22002C6AD9 /* LLScreenshotBaseOperation.m in Sources */, 36C5BF812099897F007A3188 /* LLNetworkModel.m in Sources */, 36C5BF9F2099897F007A3188 /* LLFilterDatePickerView.m in Sources */, 36C5BFAB2099897F007A3188 /* LLSearchBar.m in Sources */, @@ -808,9 +843,11 @@ 36C5BFA22099897F007A3188 /* LLFilterView.m in Sources */, 36C5BF802099897F007A3188 /* LLURLProtocol.m in Sources */, 36C5BF932099897F007A3188 /* LLWindow.m in Sources */, + 3687521F20C69B22002C6AD9 /* LLScreenshotView.m in Sources */, 367F94C7209AF38300CA1821 /* LLBaseNavigationController.m in Sources */, C43BA81A205AB095006307BE /* main.m in Sources */, 36C5BF992099897F007A3188 /* LLAppInfoVC.m in Sources */, + 36A0007720BE863700AE8810 /* NetTool.m in Sources */, 36C5BFA72099897F007A3188 /* YWFilePreviewController.m in Sources */, 36C5BF822099897F007A3188 /* LLNetworkHelper.m in Sources */, 36C5BFAC2099897F007A3188 /* LLNoneCopyTextField.m in Sources */, @@ -820,9 +857,10 @@ 36C5BF8D2099897F007A3188 /* LLCrashCell.m in Sources */, 36C5BF7E2099897F007A3188 /* LLLogModel.m in Sources */, 36C5BF7C2099897F007A3188 /* LLSandboxHelper.m in Sources */, + 3687522320C69B22002C6AD9 /* LLScreenshotToolbar.m in Sources */, 36C5BF982099897F007A3188 /* LLLogContentVC.m in Sources */, 36C5BF962099897F007A3188 /* LLLogVC.m in Sources */, - 3603254D20BFC69800987B80 /* NetTool.m in Sources */, + 3687522520C69B22002C6AD9 /* LLScreenshotImageView.m in Sources */, C4D3B5E4209ECE76006AF138 /* NSURLSessionConfiguration+LL_Swizzling.m in Sources */, 36C5BFA82099897F007A3188 /* UIButton+LL_Utils.m in Sources */, 367E855720A68EC100E5B472 /* LLSubTitleTableViewCell.m in Sources */, @@ -838,12 +876,15 @@ 36C5BFA92099897F007A3188 /* UIDevice+LL_Swizzling.m in Sources */, 36C5BFAF2099897F007A3188 /* LLTool.m in Sources */, 36C5BF832099897F007A3188 /* LLNetworkImageCell.m in Sources */, + 3687522420C69B22002C6AD9 /* LLScreenshotSelectorView.m in Sources */, 36C5BF852099897F007A3188 /* LLNetworkCell.m in Sources */, C43BA80C205AB095006307BE /* AppDelegate.m in Sources */, + 3687522220C69B22002C6AD9 /* LLScreenshotSelectorModel.m in Sources */, 36C5BF8F2099897F007A3188 /* LLCrashContentVC.m in Sources */, 36C5BFA42099897F007A3188 /* LLFilterLabelCell.m in Sources */, 36C5BF782099897F007A3188 /* LLConfig.m in Sources */, 36C5BFA52099897F007A3188 /* LLFilterLabelModel.m in Sources */, + 3687522020C69B22002C6AD9 /* LLScreenshotActionView.m in Sources */, 36C5BF9B2099897F007A3188 /* LLFilterLevelView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -860,6 +901,15 @@ name = Localizable.strings; sourceTree = ""; }; + 3691A61D20C7E63B00E22192 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 3691A61C20C7E63B00E22192 /* en */, + 3691A61E20C7E63D00E22192 /* zh-Hans */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; C43BA810205AB095006307BE /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( @@ -896,6 +946,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -903,6 +954,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -952,6 +1004,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -959,6 +1012,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -992,6 +1046,7 @@ baseConfigurationReference = 532D187B41D9EFF04391FD36 /* Pods-LLDebugToolDemo.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = NO; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; @@ -1010,6 +1065,7 @@ baseConfigurationReference = 0857CAF55E62609DE772D43C /* Pods-LLDebugToolDemo.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = NO; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; diff --git a/LLDebugToolDemo/AppDelegate.m b/LLDebugToolDemo/AppDelegate.m index 268703dc..8d7a5e09 100644 --- a/LLDebugToolDemo/AppDelegate.m +++ b/LLDebugToolDemo/AppDelegate.m @@ -7,6 +7,8 @@ // #import "AppDelegate.h" + +// If you integrate with cocoapods, used #import . #import "LLDebug.h" @interface AppDelegate () @@ -15,17 +17,19 @@ @interface AppDelegate () @implementation AppDelegate - - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + + // Uncomment one of the following lines to change the color configuration. + // [LLConfig sharedConfig].colorStyle = LLConfigColorStyleSystem; + // [[LLConfig sharedConfig] configBackgroundColor:[UIColor orangeColor] textColor:[UIColor whiteColor] statusBarStyle:UIStatusBarStyleDefault]; + // [LLConfig sharedConfig].useSystemColor = YES; + // Use this line to tag user. More config please see "LLConfig.h". + [LLConfig sharedConfig].userIdentity = @"Miss L"; - [LLConfig sharedConfig].userIdentity = @"123456789"; -// [LLConfig sharedConfig].colorStyle = LLConfigColorStyleSystem; -// [[LLConfig sharedConfig] configBackgroundColor:[UIColor orangeColor] textColor:[UIColor whiteColor] statusBarStyle:UIStatusBarStyleDefault]; -// [LLConfig sharedConfig].useSystemColor = YES; + // Use this line to start working. [[LLDebugTool sharedTool] startWorking]; - - // Override point for customization after application launch. + return YES; } diff --git a/LLDebugToolDemo/Info.plist b/LLDebugToolDemo/Info.plist index 679529a2..d709b5fb 100644 --- a/LLDebugToolDemo/Info.plist +++ b/LLDebugToolDemo/Info.plist @@ -50,5 +50,9 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + NSPhotoLibraryUsageDescription + Only for demo display. If you apply for photo album permission in your project, screenshot will be stored in photo album at the same time. + NSPhotoLibraryAddUsageDescription + Only for demo display. If you apply for photo album permission in your project, screenshot will be stored in photo album at the same time diff --git a/LLDebugToolDemo/ViewController.m b/LLDebugToolDemo/ViewController.m index 2b9f7213..cd9d1591 100644 --- a/LLDebugToolDemo/ViewController.m +++ b/LLDebugToolDemo/ViewController.m @@ -7,10 +7,13 @@ // #import "ViewController.h" + +// If you integrate with cocoapods, used #import . #import "LLDebug.h" // Used to example. #import "NetTool.h" +#import static NSString *const kCellID = @"cellID"; @@ -26,6 +29,11 @@ @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; + // Try to get album permission, and if possible, screenshots are stored in the album at the same time. + [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { + + }]; + // LLDebugTool need time to start. sleep(0.5); __block __weak typeof(self) weakSelf = self; diff --git a/LLDebugToolDemo/en.lproj/InfoPlist.strings b/LLDebugToolDemo/en.lproj/InfoPlist.strings new file mode 100644 index 00000000..b78f63cb --- /dev/null +++ b/LLDebugToolDemo/en.lproj/InfoPlist.strings @@ -0,0 +1,10 @@ +/* + InfoPlist.strings + LLDebugToolDemo + + Created by Li on 2018/6/6. + Copyright © 2018年 li. All rights reserved. +*/ + +NSPhotoLibraryUsageDescription = "Only for demo display. If you apply for photo album permission in your project, screenshot will be stored in photo album at the same time."; +NSPhotoLibraryAddUsageDescription = "Only for demo display. If you apply for photo album permission in your project, screenshot will be stored in photo album at the same time"; diff --git a/LLDebugToolDemo/zh-Hans.lproj/InfoPlist.strings b/LLDebugToolDemo/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 00000000..14413cde --- /dev/null +++ b/LLDebugToolDemo/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,10 @@ +/* + InfoPlist.strings + LLDebugToolDemo + + Created by Li on 2018/6/6. + Copyright © 2018年 li. All rights reserved. +*/ + +NSPhotoLibraryUsageDescription = "仅用于demo展示,如果你的项目中申请了相册权限,截屏时会同时储存到相册。"; +NSPhotoLibraryAddUsageDescription = "仅用于demo展示,如果你的项目中申请了相册权限,截屏时会同时储存到相册"; diff --git a/README-cn.md b/README-cn.md index f41ab4a4..96c94795 100644 --- a/README-cn.md +++ b/README-cn.md @@ -3,7 +3,7 @@

[![Version](https://img.shields.io/badge/IOS-%3E%3D8.0-f07e48.svg)](https://img.shields.io/badge/IOS-%3E%3D8.0-f07e48.svg) -[![CocoaPods Compatible](https://img.shields.io/badge/pod-v1.0.3-blue.svg)](https://img.shields.io/badge/pod-v1.0.3-blue.svg) +[![CocoaPods Compatible](https://img.shields.io/badge/pod-v1.1.0-blue.svg)](https://img.shields.io/badge/pod-v1.1.0-blue.svg) [![Platform](https://img.shields.io/badge/platform-ios-lightgrey.svg)](https://img.shields.io/badge/platform-ios-lightgrey.svg) [![License](https://img.shields.io/badge/license-MIT-91bc2b.svg)](https://img.shields.io/badge/license-MIT-91bc2b.svg) [![Language](https://img.shields.io/badge/Language-Objective--C-yellow.svg)](https://img.shields.io/badge/Language-Objective--C-yellow.svg) @@ -16,18 +16,32 @@ LLDebugTool是一款针对开发者和测试者的调试工具,它可以帮助 为您的下一个项目选择LLDebugTool,或者迁移到您现有的项目中——您会为此感到惊喜! -
- - - - - - +#### Gif + +
+ + +
+ +#### ScreenShots + +
+ + + + +
-## 最近更新 (1.0.3) +## 最近更新 (1.1.0) -- 修复一些内存泄漏问题。 +- 添加截屏功能。 + + **你可以通过同时按住home键和power键来进行截屏,也可以双击悬浮球来进行截屏,截屏后对图画添加一些简单的标注,最终将截图保存到沙盒或者相册中。 这项功能可以在测试人员测试app时,更好的标记Bug、UI问题或者其他情况。** + +
+ +
## 我能用LLDebugTool做什么? @@ -49,7 +63,7 @@ LLDebugTool是一款针对开发者和测试者的调试工具,它可以帮助 [CocoaPods](http://cocoapods.org) 是集成`LLDebugTool`的首选方式。 -1. 添加 `pod 'LLDebugTool'` 到你的Podfile里。如果只想在Debug模式下使用,则添加`pod 'LLDebugTool' ,:configurations => ['Debug']` 到你的Podfile里。 +1. 添加 `pod 'LLDebugTool'` 到你的Podfile里。如果只想在Debug模式下使用,则添加`pod 'LLDebugTool' ,:configurations => ['Debug']` 到你的Podfile里,详细的配置方式可以查看[Wiki/如何仅在Debug环境中使用](https://github.com/HDB-Li/LLDebugTool/wiki/如何仅在Debug环境中使用)。 2. 终端输入`pod install`来进行集成。搜索不到`LLDebugTool`时,可先运行`pod repo update`,再执行`pod install`。 3. 在你需要使用LLDebugTool的文件里添加`#import "LLDebug.h"`,或者直接在pch文件中添加`#import "LLDebug.h"`。 @@ -158,7 +172,8 @@ LLDebugTool提供了一个快捷的方式来查看和操作沙盒文件,你可 ### 更多使用 -你可以下载并运行["LLDebugToolDemo"](https://github.com/HDB-Li/LLDebugTool/archive/master.zip)来发现LLDebugTool的更多使用方式。Demo是在XCode9.3,ios 11.3,cocoapods 1.5.0下运行的,如果有任何版本兼容问题,请告诉我。 +* 你可以通过查看[Wiki](https://github.com/HDB-Li/LLDebugTool/wiki),获得更多帮助。 +* 你可以下载并运行[LLDebugToolDemo](https://github.com/HDB-Li/LLDebugTool/archive/master.zip)来发现LLDebugTool的更多使用方式。Demo是在XCode9.3,ios 11.3,cocoapods 1.5.0下运行的,如果有任何版本兼容问题,请告诉我。 ## 要求 @@ -170,6 +185,8 @@ LLDebugTool在支持ios8+,并且需要使用ARC模式。使用到的框架已 * `SystemConfiguration` +* `Photos` + * `malloc` * `mach-o` diff --git a/README.md b/README.md index 4df0b054..661344f9 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@

[![Version](https://img.shields.io/badge/IOS-%3E%3D8.0-f07e48.svg)](https://img.shields.io/badge/IOS-%3E%3D8.0-f07e48.svg) -[![CocoaPods Compatible](https://img.shields.io/badge/pod-v1.0.3-blue.svg)](https://img.shields.io/badge/pod-v1.0.3-blue.svg) +[![CocoaPods Compatible](https://img.shields.io/badge/pod-v1.1.0-blue.svg)](https://img.shields.io/badge/pod-v1.1.0-blue.svg) [![Platform](https://img.shields.io/badge/platform-ios-lightgrey.svg)](https://img.shields.io/badge/platform-ios-lightgrey.svg) [![License](https://img.shields.io/badge/license-MIT-91bc2b.svg)](https://img.shields.io/badge/license-MIT-91bc2b.svg) [![Language](https://img.shields.io/badge/Language-Objective--C-yellow.svg)](https://img.shields.io/badge/Language-Objective--C-yellow.svg) @@ -16,18 +16,32 @@ LLDebugTool is a debugging tool for developers and testers that can help you ana Choose LLDebugTool for your next project, or migrate over your existing projects—you'll be happy you did! -
- - - - - - +#### Gif + +
+ + +
+ +#### ScreenShots + +
+ + + + +
-## Recent updates (1.0.3) +## Recent updates (1.1.0) -- Fix some leaks. +- Add screenshot function. + + **You can by holding down the home button and power button at the same time to make screenshots, can also double-click the suspension ball to screenshots, screenshots for pictures after adding some simple annotation, eventually will save screenshots to sandbox or photo album. This feature allows testers to better mark bugs, UI issues, or other situations when testing an app.** + +
+ +
## What can you do with LLDebugTool? @@ -49,7 +63,7 @@ Choose LLDebugTool for your next project, or migrate over your existing projects [CocoaPods](http://cocoapods.org) is the recommended way to add `LLDebugTool` to your project. -1. Add a pod entry for LLDebugTool to your Podfile `pod 'LLDebugTool'`,If only you want to use it only in Debug mode, Add a pod entry for LLDebugTool to your Podfile `pod 'LLDebugTool' ,:configurations => ['Debug']`. +1. Add a pod entry for LLDebugTool to your Podfile `pod 'LLDebugTool'`,If only you want to use it only in Debug mode, Add a pod entry for LLDebugTool to your Podfile `pod 'LLDebugTool' ,:configurations => ['Debug']`, Details also see [Wiki/Use in Debug environment](https://github.com/HDB-Li/LLDebugTool/wiki/Use-in-Debug-environment). 2. Install the pod(s) by running `pod install`. If you can't search `LLDebugTool`, running `pod repo update` before `pod install`. 3. Include LLDebugTool wherever you need it with `#import "LLDebug.h"` or you can write `#import "LLDebug.h"` in your .pch in your .pch file. @@ -158,7 +172,8 @@ LLDebugTool provides a quick way to view and manipulate sandbox, you can easily ### More Usage -You can download and run the ["LLDebugToolDemo"](https://github.com/HDB-Li/LLDebugTool/archive/master.zip) to find more use with LLDebugTool. The demo is build under XCode9.3, ios 11.3 and cocoapods 1.5.0. If there is any version compatibility problem, please let me know. +* You can get more help by looking at the [Wiki](https://github.com/HDB-Li/LLDebugTool/wiki). +* You can download and run the [LLDebugToolDemo](https://github.com/HDB-Li/LLDebugTool/archive/master.zip) to find more use with LLDebugTool. The demo is build under XCode9.3, ios 11.3 and cocoapods 1.5.0. If there is any version compatibility problem, please let me know. ## Requirements @@ -170,6 +185,8 @@ LLDebugTool works on iOS 8+ and requires ARC to build. It depends on the followi * `SystemConfiguration` +* `Photos` + * `malloc` * `mach-o`