diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..198413640 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at mohamed.hamed.ibrahem@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..22823ca9f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,18 @@ +# Contributing + +love contributions from everyone. +waiting your contributions +## Contributing Code + +Fork the repo. + +Make your change. + + +Push to your fork. Write a [good commit message][commit]. Submit a pull request. + + [commit]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html + +This is a time for discussion and improvements, +and making the necessary changes will be required before we can +merge the contribution. diff --git a/Example/Podfile b/Example/Podfile old mode 100755 new mode 100644 diff --git a/Example/Podfile.lock b/Example/Podfile.lock old mode 100755 new mode 100644 index e17c04d67..088e03eb5 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -9,4 +9,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: b3b33da00e571f79c0e6db13cf8c1bf38234ee5b -COCOAPODS: 1.2.1 +COCOAPODS: 1.3.1 diff --git a/Example/Pods/Manifest.lock b/Example/Pods/Manifest.lock old mode 100755 new mode 100644 index e17c04d67..088e03eb5 --- a/Example/Pods/Manifest.lock +++ b/Example/Pods/Manifest.lock @@ -9,4 +9,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: b3b33da00e571f79c0e6db13cf8c1bf38234ee5b -COCOAPODS: 1.2.1 +COCOAPODS: 1.3.1 diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj old mode 100755 new mode 100644 index c7b0eff83..f6ccfca4b --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -449,89 +449,75 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ - 1A507E6980951C0A82AB22212E6F691C /* Release */ = { + 4DDA329CC70A1E4684D815B1091FC03D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5633199933D95A619855E0585754A483 /* iOSPhotoEditor.xcconfig */; + baseConfigurationReference = 206D698D11189FC0981ADC708603EE08 /* Pods-editorTest.release.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREFIX_HEADER = "Target Support Files/iOSPhotoEditor/iOSPhotoEditor-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/iOSPhotoEditor/Info.plist"; + INFOPLIST_FILE = "Target Support Files/Pods-editorTest/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/iOSPhotoEditor/iOSPhotoEditor.modulemap"; - MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_NAME = iOSPhotoEditor; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-editorTest/Pods-editorTest.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_editorTest; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; - 4E487F173E6C9664F4E9E26B9635D23C /* Debug */ = { + 59F416B2873AA8A8CE99374C7922BCF7 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 5F19AD2B2E058311ECC6A5223693C2FC /* Pods-editorTest.debug.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGNING_REQUIRED = NO; - COPY_PHASE_STRIP = NO; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "POD_CONFIGURATION_DEBUG=1", - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-editorTest/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - ONLY_ACTIVE_ARCH = YES; - PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; - STRIP_INSTALLED_PRODUCT = NO; - SYMROOT = "${SRCROOT}/../build"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-editorTest/Pods-editorTest.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_editorTest; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; }; name = Debug; }; - 98CA8FDCE1D3ED98FDE317BD391C83F1 /* Debug */ = { + 6F0E4336EED226F0E3E0750C676CF7B9 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 5633199933D95A619855E0585754A483 /* iOSPhotoEditor.xcconfig */; buildSettings = { @@ -540,150 +526,172 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/iOSPhotoEditor/iOSPhotoEditor-prefix.pch"; INFOPLIST_FILE = "Target Support Files/iOSPhotoEditor/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/iOSPhotoEditor/iOSPhotoEditor.modulemap"; - MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = iOSPhotoEditor; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; + name = Release; }; - BDD0139D6EB93FA375F887ABD62DAB2E /* Release */ = { + 6F9224530522DD3C735EC96CF142642E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGNING_REQUIRED = NO; - COPY_PHASE_STRIP = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "POD_CONFIGURATION_RELEASE=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; STRIP_INSTALLED_PRODUCT = NO; SYMROOT = "${SRCROOT}/../build"; - VALIDATE_PRODUCT = YES; }; name = Release; }; - C9240C5446ECFAEAD561801C5F5DAAB1 /* Release */ = { + 86115BDFCECBA3E41BB7111A29A356CD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 206D698D11189FC0981ADC708603EE08 /* Pods-editorTest.release.xcconfig */; + baseConfigurationReference = 5633199933D95A619855E0585754A483 /* iOSPhotoEditor.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "Target Support Files/Pods-editorTest/Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/iOSPhotoEditor/iOSPhotoEditor-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/iOSPhotoEditor/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-editorTest/Pods-editorTest.modulemap"; - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = Pods_editorTest; + MODULEMAP_FILE = "Target Support Files/iOSPhotoEditor/iOSPhotoEditor.modulemap"; + PRODUCT_NAME = iOSPhotoEditor; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Release; + name = Debug; }; - E5DF9E10282710764D40AA648C9D55EC /* Debug */ = { + B57951D085A1B98A97F8A1062A5E5C5B /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5F19AD2B2E058311ECC6A5223693C2FC /* Pods-editorTest.debug.xcconfig */; buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_REQUIRED = NO; + COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "Target Support Files/Pods-editorTest/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-editorTest/Pods-editorTest.modulemap"; MTL_ENABLE_DEBUG_INFO = YES; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = Pods_editorTest; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; + STRIP_INSTALLED_PRODUCT = NO; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; + SYMROOT = "${SRCROOT}/../build"; }; name = Debug; }; @@ -693,8 +701,8 @@ 0E72CA372EE7F9013E54BE4CC4AAFC42 /* Build configuration list for PBXNativeTarget "Pods-editorTest" */ = { isa = XCConfigurationList; buildConfigurations = ( - E5DF9E10282710764D40AA648C9D55EC /* Debug */, - C9240C5446ECFAEAD561801C5F5DAAB1 /* Release */, + 59F416B2873AA8A8CE99374C7922BCF7 /* Debug */, + 4DDA329CC70A1E4684D815B1091FC03D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -702,8 +710,8 @@ 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( - 4E487F173E6C9664F4E9E26B9635D23C /* Debug */, - BDD0139D6EB93FA375F887ABD62DAB2E /* Release */, + B57951D085A1B98A97F8A1062A5E5C5B /* Debug */, + 6F9224530522DD3C735EC96CF142642E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -711,8 +719,8 @@ 8DECE022BAA855D9EE6FB37D55A85D9E /* Build configuration list for PBXNativeTarget "iOSPhotoEditor" */ = { isa = XCConfigurationList; buildConfigurations = ( - 98CA8FDCE1D3ED98FDE317BD391C83F1 /* Debug */, - 1A507E6980951C0A82AB22212E6F691C /* Release */, + 86115BDFCECBA3E41BB7111A29A356CD /* Debug */, + 6F0E4336EED226F0E3E0750C676CF7B9 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Example/Pods/Pods.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/Pods-editorTest.xcscheme b/Example/Pods/Pods.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/Pods-editorTest.xcscheme index 50c1a0de1..9af41a691 100644 --- a/Example/Pods/Pods.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/Pods-editorTest.xcscheme +++ b/Example/Pods/Pods.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/Pods-editorTest.xcscheme @@ -26,6 +26,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" shouldUseLaunchSchemeArgsEnv = "YES"> @@ -36,6 +37,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Example/Pods/Pods.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/xcschememanagement.plist b/Example/Pods/Pods.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/xcschememanagement.plist index 230d56b98..3209f15c9 100644 --- a/Example/Pods/Pods.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Example/Pods/Pods.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/xcschememanagement.plist @@ -16,17 +16,6 @@ SuppressBuildableAutocreation - - 2955A52A217BA297BB7C1592135AADC2 - - primary - - - EEFA0C43D4FA150B0F6A42226C6C6F88 - - primary - - - + diff --git a/Example/Pods/Target Support Files/Pods-editorTest/Pods-editorTest-frameworks.sh b/Example/Pods/Target Support Files/Pods-editorTest/Pods-editorTest-frameworks.sh index 458bcfdd9..718ce3fa4 100755 --- a/Example/Pods/Target Support Files/Pods-editorTest/Pods-editorTest-frameworks.sh +++ b/Example/Pods/Target Support Files/Pods-editorTest/Pods-editorTest-frameworks.sh @@ -6,6 +6,10 @@ mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + install_framework() { if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then @@ -23,9 +27,9 @@ install_framework() source="$(readlink "${source}")" fi - # use filter instead of exclude so missing patterns dont' throw errors - echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" - rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" local basename basename="$(basename -s .framework "$1")" @@ -54,6 +58,15 @@ install_framework() fi } +# Copies the dSYM of a vendored framework +install_dsym() { + local source="$1" + if [ -r "$source" ]; then + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DWARF_DSYM_FOLDER_PATH}" + fi +} + # Signs a framework with the provided identity code_sign_if_enabled() { if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then @@ -76,7 +89,7 @@ strip_invalid_archs() { archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" stripped="" for arch in $archs; do - if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then + if ! [[ "${ARCHS}" == *"$arch"* ]]; then # Strip non-valid architectures in-place lipo -remove "$arch" -output "$binary" "$binary" || exit 1 stripped="$stripped $arch" @@ -89,10 +102,10 @@ strip_invalid_archs() { if [[ "$CONFIGURATION" == "Debug" ]]; then - install_framework "$BUILT_PRODUCTS_DIR/iOSPhotoEditor/iOSPhotoEditor.framework" + install_framework "${BUILT_PRODUCTS_DIR}/iOSPhotoEditor/iOSPhotoEditor.framework" fi if [[ "$CONFIGURATION" == "Release" ]]; then - install_framework "$BUILT_PRODUCTS_DIR/iOSPhotoEditor/iOSPhotoEditor.framework" + install_framework "${BUILT_PRODUCTS_DIR}/iOSPhotoEditor/iOSPhotoEditor.framework" fi if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then wait diff --git a/Example/Pods/Target Support Files/Pods-editorTest/Pods-editorTest-resources.sh b/Example/Pods/Target Support Files/Pods-editorTest/Pods-editorTest-resources.sh index aed060f04..a7df4405b 100755 --- a/Example/Pods/Target Support Files/Pods-editorTest/Pods-editorTest-resources.sh +++ b/Example/Pods/Target Support Files/Pods-editorTest/Pods-editorTest-resources.sh @@ -8,6 +8,10 @@ RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt XCASSET_FILES=() +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + case "${TARGETED_DEVICE_FAMILY}" in 1,2) TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" @@ -44,29 +48,29 @@ EOM fi case $RESOURCE_PATH in *.storyboard) - echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} ;; *.xib) - echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} ;; *.framework) - echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" - echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" - rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" ;; *.xcdatamodel) - echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" ;; *.xcdatamodeld) - echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" ;; *.xcmappingmodel) - echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" ;; *.xcassets) @@ -74,7 +78,7 @@ EOM XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") ;; *) - echo "$RESOURCE_PATH" + echo "$RESOURCE_PATH" || true echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" ;; esac diff --git a/Example/editorTest.xcodeproj/project.pbxproj b/Example/editorTest.xcodeproj/project.pbxproj old mode 100755 new mode 100644 index 3a4d147fe..3920806c8 --- a/Example/editorTest.xcodeproj/project.pbxproj +++ b/Example/editorTest.xcodeproj/project.pbxproj @@ -185,9 +185,12 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-editorTest/Pods-editorTest-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/iOSPhotoEditor/iOSPhotoEditor.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/iOSPhotoEditor.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -200,13 +203,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-editorTest-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - 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"; + 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; }; /* End PBXShellScriptBuildPhase section */ diff --git a/Example/editorTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Example/editorTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata old mode 100755 new mode 100644 diff --git a/Example/editorTest.xcodeproj/project.xcworkspace/xcuserdata/hamed.xcuserdatad/UserInterfaceState.xcuserstate b/Example/editorTest.xcodeproj/project.xcworkspace/xcuserdata/hamed.xcuserdatad/UserInterfaceState.xcuserstate old mode 100755 new mode 100644 diff --git a/Example/editorTest.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/editorTest.xcscheme b/Example/editorTest.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/editorTest.xcscheme old mode 100755 new mode 100644 diff --git a/Example/editorTest.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/xcschememanagement.plist b/Example/editorTest.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/xcschememanagement.plist old mode 100755 new mode 100644 diff --git a/Example/editorTest.xcworkspace/contents.xcworkspacedata b/Example/editorTest.xcworkspace/contents.xcworkspacedata old mode 100755 new mode 100644 diff --git a/Example/editorTest.xcworkspace/xcuserdata/hamed.xcuserdatad/UserInterfaceState.xcuserstate b/Example/editorTest.xcworkspace/xcuserdata/hamed.xcuserdatad/UserInterfaceState.xcuserstate old mode 100755 new mode 100644 index 1413d4a39..f294b67cb Binary files a/Example/editorTest.xcworkspace/xcuserdata/hamed.xcuserdatad/UserInterfaceState.xcuserstate and b/Example/editorTest.xcworkspace/xcuserdata/hamed.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Example/editorTest.xcworkspace/xcuserdata/hamed.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Example/editorTest.xcworkspace/xcuserdata/hamed.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist old mode 100755 new mode 100644 index 6ff175523..580b0c8d4 --- a/Example/editorTest.xcworkspace/xcuserdata/hamed.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/Example/editorTest.xcworkspace/xcuserdata/hamed.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -25,7 +25,7 @@ endingColumnNumber = "9223372036854775807" startingLineNumber = "66" endingLineNumber = "66" - landmarkName = "tapGesture(_:)" + landmarkName = "rotationGesture(_:)" landmarkType = "7"> @@ -93,5 +93,31 @@ landmarkType = "7"> + + + + + + + + diff --git a/Example/editorTest/AppDelegate.swift b/Example/editorTest/AppDelegate.swift old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/0.imageset/0.png b/Example/editorTest/Assets.xcassets/0.imageset/0.png old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/0.imageset/Contents.json b/Example/editorTest/Assets.xcassets/0.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/1.imageset/1.png b/Example/editorTest/Assets.xcassets/1.imageset/1.png old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/1.imageset/Contents.json b/Example/editorTest/Assets.xcassets/1.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/10.imageset/10.png b/Example/editorTest/Assets.xcassets/10.imageset/10.png old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/10.imageset/Contents.json b/Example/editorTest/Assets.xcassets/10.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/2.imageset/2.png b/Example/editorTest/Assets.xcassets/2.imageset/2.png old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/2.imageset/Contents.json b/Example/editorTest/Assets.xcassets/2.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/3.imageset/3.png b/Example/editorTest/Assets.xcassets/3.imageset/3.png old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/3.imageset/Contents.json b/Example/editorTest/Assets.xcassets/3.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/4.imageset/4.png b/Example/editorTest/Assets.xcassets/4.imageset/4.png old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/4.imageset/Contents.json b/Example/editorTest/Assets.xcassets/4.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/5.imageset/5.png b/Example/editorTest/Assets.xcassets/5.imageset/5.png old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/5.imageset/Contents.json b/Example/editorTest/Assets.xcassets/5.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/6.imageset/6.png b/Example/editorTest/Assets.xcassets/6.imageset/6.png old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/6.imageset/Contents.json b/Example/editorTest/Assets.xcassets/6.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/7.imageset/7.png b/Example/editorTest/Assets.xcassets/7.imageset/7.png old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/7.imageset/Contents.json b/Example/editorTest/Assets.xcassets/7.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/8.imageset/8.png b/Example/editorTest/Assets.xcassets/8.imageset/8.png old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/8.imageset/Contents.json b/Example/editorTest/Assets.xcassets/8.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/9.imageset/9.png b/Example/editorTest/Assets.xcassets/9.imageset/9.png old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/9.imageset/Contents.json b/Example/editorTest/Assets.xcassets/9.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/editorTest/Assets.xcassets/AppIcon.appiconset/Contents.json old mode 100755 new mode 100644 diff --git a/Example/editorTest/Assets.xcassets/Contents.json b/Example/editorTest/Assets.xcassets/Contents.json old mode 100755 new mode 100644 diff --git a/Example/editorTest/Base.lproj/LaunchScreen.storyboard b/Example/editorTest/Base.lproj/LaunchScreen.storyboard old mode 100755 new mode 100644 diff --git a/Example/editorTest/Base.lproj/Main.storyboard b/Example/editorTest/Base.lproj/Main.storyboard old mode 100755 new mode 100644 diff --git a/Example/editorTest/Info.plist b/Example/editorTest/Info.plist old mode 100755 new mode 100644 diff --git a/Example/editorTest/ViewController.swift b/Example/editorTest/ViewController.swift old mode 100755 new mode 100644 index 274de3a28..e69595029 --- a/Example/editorTest/ViewController.swift +++ b/Example/editorTest/ViewController.swift @@ -49,13 +49,10 @@ extension ViewController: UIImagePickerControllerDelegate, UINavigationControlle let photoEditor = PhotoEditorViewController(nibName:"PhotoEditorViewController",bundle: Bundle(for: PhotoEditorViewController.self)) - photoEditor.photoEditorDelegate = self - photoEditor.image = image - //Colors for drawing and Text, If not set default values will be used - // photoEditor.colors = [.red,.blue,.green] + //photoEditor.colors = [.red, .blue, .green] //Stickers that the user will choose from to add on the image for i in 0...10 { @@ -63,7 +60,7 @@ extension ViewController: UIImagePickerControllerDelegate, UINavigationControlle } //To hide controls - array of enum control - // photoEditor.hiddenControls = [.crop, .draw, .share] + //photoEditor.hiddenControls = [.crop, .draw, .share] present(photoEditor, animated: true, completion: nil) } diff --git a/Example/editorTest/img.jpg b/Example/editorTest/img.jpg old mode 100755 new mode 100644 diff --git a/LICENSE.md b/LICENSE.md old mode 100755 new mode 100644 diff --git a/Photo Editor/LICENSE.md b/Photo Editor/LICENSE.md old mode 100755 new mode 100644 diff --git a/Photo Editor/Photo Editor.xcodeproj/project.pbxproj b/Photo Editor/Photo Editor.xcodeproj/project.pbxproj old mode 100755 new mode 100644 index 38ca82269..88df0963e --- a/Photo Editor/Photo Editor.xcodeproj/project.pbxproj +++ b/Photo Editor/Photo Editor.xcodeproj/project.pbxproj @@ -7,55 +7,87 @@ objects = { /* Begin PBXBuildFile section */ - 055C05091EB6375800B32735 /* EmojiCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 055C05071EB6375800B32735 /* EmojiCollectionViewCell.swift */; }; - 055C050A1EB6375800B32735 /* EmojiCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 055C05081EB6375800B32735 /* EmojiCollectionViewCell.xib */; }; - 055C050C1EB638A500B32735 /* EmojisCollectionViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 055C050B1EB638A500B32735 /* EmojisCollectionViewDelegate.swift */; }; + 056513191EF489B4009EA38F /* PhotoEditorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513081EF489B4009EA38F /* PhotoEditorViewController.swift */; }; + 0565131A1EF489B4009EA38F /* StickersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513091EF489B4009EA38F /* StickersViewController.swift */; }; + 0565131B1EF489B4009EA38F /* ColorCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0565130A1EF489B4009EA38F /* ColorCollectionViewCell.swift */; }; + 0565131C1EF489B4009EA38F /* ColorsCollectionViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0565130B1EF489B4009EA38F /* ColorsCollectionViewDelegate.swift */; }; + 0565131D1EF489B4009EA38F /* EmojiCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0565130C1EF489B4009EA38F /* EmojiCollectionViewCell.swift */; }; + 0565131E1EF489B4009EA38F /* EmojisCollectionViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0565130D1EF489B4009EA38F /* EmojisCollectionViewDelegate.swift */; }; + 0565131F1EF489B4009EA38F /* StickerCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0565130E1EF489B4009EA38F /* StickerCollectionViewCell.swift */; }; + 056513201EF489B4009EA38F /* UIImage+Size.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0565130F1EF489B4009EA38F /* UIImage+Size.swift */; }; + 056513211EF489B4009EA38F /* UIImageView+Alpha.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513101EF489B4009EA38F /* UIImageView+Alpha.swift */; }; + 056513221EF489B4009EA38F /* UIView+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513111EF489B4009EA38F /* UIView+Image.swift */; }; + 056513231EF489B4009EA38F /* Protocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513121EF489B4009EA38F /* Protocols.swift */; }; + 056513241EF489B4009EA38F /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513131EF489B4009EA38F /* GradientView.swift */; }; + 056513251EF489B4009EA38F /* CropView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513141EF489B4009EA38F /* CropView.swift */; }; + 056513261EF489B4009EA38F /* CropRectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513151EF489B4009EA38F /* CropRectView.swift */; }; + 056513271EF489B4009EA38F /* CropViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513161EF489B4009EA38F /* CropViewController.swift */; }; + 056513281EF489B4009EA38F /* UIImage+Crop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513171EF489B4009EA38F /* UIImage+Crop.swift */; }; + 056513291EF489B4009EA38F /* ResizeControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513181EF489B4009EA38F /* ResizeControl.swift */; }; + 056513341EF489C0009EA38F /* StickersViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0565132A1EF489C0009EA38F /* StickersViewController.xib */; }; + 056513351EF489C0009EA38F /* ColorCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0565132B1EF489C0009EA38F /* ColorCollectionViewCell.xib */; }; + 056513361EF489C0009EA38F /* EmojiCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0565132C1EF489C0009EA38F /* EmojiCollectionViewCell.xib */; }; + 056513371EF489C0009EA38F /* icomoon.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0565132D1EF489C0009EA38F /* icomoon.ttf */; }; + 056513381EF489C0009EA38F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0565132E1EF489C0009EA38F /* LaunchScreen.storyboard */; }; + 056513391EF489C0009EA38F /* PhotoCropEditorBorder.png in Resources */ = {isa = PBXBuildFile; fileRef = 0565132F1EF489C0009EA38F /* PhotoCropEditorBorder.png */; }; + 0565133A1EF489C0009EA38F /* PhotoCropEditorBorder@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 056513301EF489C0009EA38F /* PhotoCropEditorBorder@2x.png */; }; + 0565133B1EF489C0009EA38F /* PhotoCropEditorBorder@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 056513311EF489C0009EA38F /* PhotoCropEditorBorder@3x.png */; }; + 0565133C1EF489C0009EA38F /* StickerCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 056513321EF489C0009EA38F /* StickerCollectionViewCell.xib */; }; + 0565133D1EF489C0009EA38F /* PhotoEditorViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 056513331EF489C0009EA38F /* PhotoEditorViewController.xib */; }; + 056513461EF489CD009EA38F /* PhotoEditor+Gestures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0565133E1EF489CD009EA38F /* PhotoEditor+Gestures.swift */; }; + 056513471EF489CD009EA38F /* PhotoEditor+Drawing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0565133F1EF489CD009EA38F /* PhotoEditor+Drawing.swift */; }; + 056513481EF489CD009EA38F /* PhotoEditor+Keyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513401EF489CD009EA38F /* PhotoEditor+Keyboard.swift */; }; + 056513491EF489CD009EA38F /* PhotoEditor+StickersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513411EF489CD009EA38F /* PhotoEditor+StickersViewController.swift */; }; + 0565134A1EF489CD009EA38F /* PhotoEditor+UITextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513421EF489CD009EA38F /* PhotoEditor+UITextView.swift */; }; + 0565134B1EF489CD009EA38F /* PhotoEditor+Controls.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513431EF489CD009EA38F /* PhotoEditor+Controls.swift */; }; + 0565134C1EF489CD009EA38F /* PhotoEditor+Crop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513441EF489CD009EA38F /* PhotoEditor+Crop.swift */; }; + 0565134D1EF489CD009EA38F /* PhotoEditor+Font.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056513451EF489CD009EA38F /* PhotoEditor+Font.swift */; }; 059EA71D1EACB8790072C0FE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 059EA71C1EACB8790072C0FE /* AppDelegate.swift */; }; - 059EA71F1EACB8790072C0FE /* PhotoEditorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 059EA71E1EACB8790072C0FE /* PhotoEditorViewController.swift */; }; - 059EA7221EACB8790072C0FE /* PhotoEditor.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 059EA7201EACB8790072C0FE /* PhotoEditor.storyboard */; }; 059EA7241EACB8790072C0FE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 059EA7231EACB8790072C0FE /* Assets.xcassets */; }; 059EA7271EACB8790072C0FE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 059EA7251EACB8790072C0FE /* LaunchScreen.storyboard */; }; - 059EA73A1EACD9620072C0FE /* BottomSheetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 059EA7381EACD9620072C0FE /* BottomSheetViewController.swift */; }; - 059EA73B1EACD9620072C0FE /* BottomSheetViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 059EA7391EACD9620072C0FE /* BottomSheetViewController.xib */; }; - 059EA7471EAD1B550072C0FE /* StickerCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 059EA7451EAD1B550072C0FE /* StickerCollectionViewCell.swift */; }; - 059EA7481EAD1B550072C0FE /* StickerCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 059EA7461EAD1B550072C0FE /* StickerCollectionViewCell.xib */; }; - 05CE343C1EBB792F0010A758 /* Eventtus-Icons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 05CE34361EBB792F0010A758 /* Eventtus-Icons.ttf */; }; - 05CE343D1EBB792F0010A758 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CE34371EBB792F0010A758 /* GradientView.swift */; }; - 05CE343E1EBB792F0010A758 /* Pencil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CE34381EBB792F0010A758 /* Pencil.swift */; }; - 05CE34401EBB792F0010A758 /* UIView+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CE343A1EBB792F0010A758 /* UIView+Image.swift */; }; - 05CE34411EBB792F0010A758 /* ViewGestures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CE343B1EBB792F0010A758 /* ViewGestures.swift */; }; - 05DD7E261EC33BDA005979EC /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05DD7E251EC33BDA005979EC /* UIImageViewExtensions.swift */; }; - 05DD7E281EC33C35005979EC /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05DD7E271EC33C35005979EC /* UIImageExtensions.swift */; }; - 05E50F8B1EB7488F002A92A0 /* ColorsCollectionViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05E50F8A1EB7488F002A92A0 /* ColorsCollectionViewDelegate.swift */; }; - 05E50F8E1EB74937002A92A0 /* ColorCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05E50F8C1EB74937002A92A0 /* ColorCollectionViewCell.swift */; }; - 05E50F8F1EB74937002A92A0 /* ColorCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 05E50F8D1EB74937002A92A0 /* ColorCollectionViewCell.xib */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 055C05071EB6375800B32735 /* EmojiCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmojiCollectionViewCell.swift; sourceTree = ""; }; - 055C05081EB6375800B32735 /* EmojiCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = EmojiCollectionViewCell.xib; sourceTree = ""; }; - 055C050B1EB638A500B32735 /* EmojisCollectionViewDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmojisCollectionViewDelegate.swift; sourceTree = ""; }; + 056513081EF489B4009EA38F /* PhotoEditorViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoEditorViewController.swift; sourceTree = ""; }; + 056513091EF489B4009EA38F /* StickersViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StickersViewController.swift; sourceTree = ""; }; + 0565130A1EF489B4009EA38F /* ColorCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorCollectionViewCell.swift; sourceTree = ""; }; + 0565130B1EF489B4009EA38F /* ColorsCollectionViewDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorsCollectionViewDelegate.swift; sourceTree = ""; }; + 0565130C1EF489B4009EA38F /* EmojiCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmojiCollectionViewCell.swift; sourceTree = ""; }; + 0565130D1EF489B4009EA38F /* EmojisCollectionViewDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmojisCollectionViewDelegate.swift; sourceTree = ""; }; + 0565130E1EF489B4009EA38F /* StickerCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StickerCollectionViewCell.swift; sourceTree = ""; }; + 0565130F1EF489B4009EA38F /* UIImage+Size.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Size.swift"; sourceTree = ""; }; + 056513101EF489B4009EA38F /* UIImageView+Alpha.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImageView+Alpha.swift"; sourceTree = ""; }; + 056513111EF489B4009EA38F /* UIView+Image.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Image.swift"; sourceTree = ""; }; + 056513121EF489B4009EA38F /* Protocols.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Protocols.swift; sourceTree = ""; }; + 056513131EF489B4009EA38F /* GradientView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = ""; }; + 056513141EF489B4009EA38F /* CropView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CropView.swift; sourceTree = ""; }; + 056513151EF489B4009EA38F /* CropRectView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CropRectView.swift; sourceTree = ""; }; + 056513161EF489B4009EA38F /* CropViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CropViewController.swift; sourceTree = ""; }; + 056513171EF489B4009EA38F /* UIImage+Crop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Crop.swift"; sourceTree = ""; }; + 056513181EF489B4009EA38F /* ResizeControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResizeControl.swift; sourceTree = ""; }; + 0565132A1EF489C0009EA38F /* StickersViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = StickersViewController.xib; sourceTree = ""; }; + 0565132B1EF489C0009EA38F /* ColorCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ColorCollectionViewCell.xib; sourceTree = ""; }; + 0565132C1EF489C0009EA38F /* EmojiCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = EmojiCollectionViewCell.xib; sourceTree = ""; }; + 0565132D1EF489C0009EA38F /* icomoon.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = icomoon.ttf; sourceTree = ""; }; + 0565132E1EF489C0009EA38F /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; + 0565132F1EF489C0009EA38F /* PhotoCropEditorBorder.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = PhotoCropEditorBorder.png; sourceTree = ""; }; + 056513301EF489C0009EA38F /* PhotoCropEditorBorder@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PhotoCropEditorBorder@2x.png"; sourceTree = ""; }; + 056513311EF489C0009EA38F /* PhotoCropEditorBorder@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PhotoCropEditorBorder@3x.png"; sourceTree = ""; }; + 056513321EF489C0009EA38F /* StickerCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = StickerCollectionViewCell.xib; sourceTree = ""; }; + 056513331EF489C0009EA38F /* PhotoEditorViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PhotoEditorViewController.xib; sourceTree = ""; }; + 0565133E1EF489CD009EA38F /* PhotoEditor+Gestures.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PhotoEditor+Gestures.swift"; sourceTree = ""; }; + 0565133F1EF489CD009EA38F /* PhotoEditor+Drawing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PhotoEditor+Drawing.swift"; sourceTree = ""; }; + 056513401EF489CD009EA38F /* PhotoEditor+Keyboard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PhotoEditor+Keyboard.swift"; sourceTree = ""; }; + 056513411EF489CD009EA38F /* PhotoEditor+StickersViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PhotoEditor+StickersViewController.swift"; sourceTree = ""; }; + 056513421EF489CD009EA38F /* PhotoEditor+UITextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PhotoEditor+UITextView.swift"; sourceTree = ""; }; + 056513431EF489CD009EA38F /* PhotoEditor+Controls.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PhotoEditor+Controls.swift"; sourceTree = ""; }; + 056513441EF489CD009EA38F /* PhotoEditor+Crop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PhotoEditor+Crop.swift"; sourceTree = ""; }; + 056513451EF489CD009EA38F /* PhotoEditor+Font.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PhotoEditor+Font.swift"; sourceTree = ""; }; 059EA7191EACB8790072C0FE /* Photo Editor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Photo Editor.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 059EA71C1EACB8790072C0FE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 059EA71E1EACB8790072C0FE /* PhotoEditorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoEditorViewController.swift; sourceTree = ""; }; - 059EA7211EACB8790072C0FE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/PhotoEditor.storyboard; sourceTree = ""; }; 059EA7231EACB8790072C0FE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 059EA7261EACB8790072C0FE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 059EA7281EACB8790072C0FE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 059EA7381EACD9620072C0FE /* BottomSheetViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomSheetViewController.swift; sourceTree = ""; }; - 059EA7391EACD9620072C0FE /* BottomSheetViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = BottomSheetViewController.xib; sourceTree = ""; }; - 059EA7451EAD1B550072C0FE /* StickerCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StickerCollectionViewCell.swift; sourceTree = ""; }; - 059EA7461EAD1B550072C0FE /* StickerCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = StickerCollectionViewCell.xib; sourceTree = ""; }; - 05CE34361EBB792F0010A758 /* Eventtus-Icons.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Eventtus-Icons.ttf"; sourceTree = ""; }; - 05CE34371EBB792F0010A758 /* GradientView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = ""; }; - 05CE34381EBB792F0010A758 /* Pencil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Pencil.swift; sourceTree = ""; }; - 05CE343A1EBB792F0010A758 /* UIView+Image.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Image.swift"; sourceTree = ""; }; - 05CE343B1EBB792F0010A758 /* ViewGestures.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewGestures.swift; sourceTree = ""; }; - 05DD7E251EC33BDA005979EC /* UIImageViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageViewExtensions.swift; sourceTree = ""; }; - 05DD7E271EC33C35005979EC /* UIImageExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtensions.swift; sourceTree = ""; }; - 05E50F8A1EB7488F002A92A0 /* ColorsCollectionViewDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorsCollectionViewDelegate.swift; sourceTree = ""; }; - 05E50F8C1EB74937002A92A0 /* ColorCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorCollectionViewCell.swift; sourceTree = ""; }; - 05E50F8D1EB74937002A92A0 /* ColorCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ColorCollectionViewCell.xib; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -88,29 +120,45 @@ 059EA71B1EACB8790072C0FE /* Photo Editor */ = { isa = PBXGroup; children = ( - 05CE34361EBB792F0010A758 /* Eventtus-Icons.ttf */, - 05CE34371EBB792F0010A758 /* GradientView.swift */, - 05CE34381EBB792F0010A758 /* Pencil.swift */, - 05DD7E251EC33BDA005979EC /* UIImageViewExtensions.swift */, - 05DD7E271EC33C35005979EC /* UIImageExtensions.swift */, - 05CE343A1EBB792F0010A758 /* UIView+Image.swift */, - 05CE343B1EBB792F0010A758 /* ViewGestures.swift */, + 056513081EF489B4009EA38F /* PhotoEditorViewController.swift */, + 056513091EF489B4009EA38F /* StickersViewController.swift */, + 0565130A1EF489B4009EA38F /* ColorCollectionViewCell.swift */, + 0565130B1EF489B4009EA38F /* ColorsCollectionViewDelegate.swift */, + 0565130C1EF489B4009EA38F /* EmojiCollectionViewCell.swift */, + 0565130D1EF489B4009EA38F /* EmojisCollectionViewDelegate.swift */, + 0565130E1EF489B4009EA38F /* StickerCollectionViewCell.swift */, + 0565130F1EF489B4009EA38F /* UIImage+Size.swift */, + 056513101EF489B4009EA38F /* UIImageView+Alpha.swift */, + 056513111EF489B4009EA38F /* UIView+Image.swift */, + 056513121EF489B4009EA38F /* Protocols.swift */, + 056513131EF489B4009EA38F /* GradientView.swift */, + 056513141EF489B4009EA38F /* CropView.swift */, + 056513151EF489B4009EA38F /* CropRectView.swift */, + 056513161EF489B4009EA38F /* CropViewController.swift */, + 056513171EF489B4009EA38F /* UIImage+Crop.swift */, + 056513181EF489B4009EA38F /* ResizeControl.swift */, 059EA71C1EACB8790072C0FE /* AppDelegate.swift */, - 059EA71E1EACB8790072C0FE /* PhotoEditorViewController.swift */, - 059EA7201EACB8790072C0FE /* PhotoEditor.storyboard */, + 0565133E1EF489CD009EA38F /* PhotoEditor+Gestures.swift */, + 0565133F1EF489CD009EA38F /* PhotoEditor+Drawing.swift */, + 056513401EF489CD009EA38F /* PhotoEditor+Keyboard.swift */, + 056513411EF489CD009EA38F /* PhotoEditor+StickersViewController.swift */, + 056513421EF489CD009EA38F /* PhotoEditor+UITextView.swift */, + 056513431EF489CD009EA38F /* PhotoEditor+Controls.swift */, + 056513441EF489CD009EA38F /* PhotoEditor+Crop.swift */, + 056513451EF489CD009EA38F /* PhotoEditor+Font.swift */, + 0565132A1EF489C0009EA38F /* StickersViewController.xib */, + 0565132B1EF489C0009EA38F /* ColorCollectionViewCell.xib */, + 0565132C1EF489C0009EA38F /* EmojiCollectionViewCell.xib */, + 0565132D1EF489C0009EA38F /* icomoon.ttf */, + 0565132E1EF489C0009EA38F /* LaunchScreen.storyboard */, + 0565132F1EF489C0009EA38F /* PhotoCropEditorBorder.png */, + 056513301EF489C0009EA38F /* PhotoCropEditorBorder@2x.png */, + 056513311EF489C0009EA38F /* PhotoCropEditorBorder@3x.png */, + 056513321EF489C0009EA38F /* StickerCollectionViewCell.xib */, + 056513331EF489C0009EA38F /* PhotoEditorViewController.xib */, 059EA7231EACB8790072C0FE /* Assets.xcassets */, 059EA7251EACB8790072C0FE /* LaunchScreen.storyboard */, 059EA7281EACB8790072C0FE /* Info.plist */, - 059EA7381EACD9620072C0FE /* BottomSheetViewController.swift */, - 059EA7391EACD9620072C0FE /* BottomSheetViewController.xib */, - 059EA7451EAD1B550072C0FE /* StickerCollectionViewCell.swift */, - 059EA7461EAD1B550072C0FE /* StickerCollectionViewCell.xib */, - 055C05071EB6375800B32735 /* EmojiCollectionViewCell.swift */, - 055C05081EB6375800B32735 /* EmojiCollectionViewCell.xib */, - 055C050B1EB638A500B32735 /* EmojisCollectionViewDelegate.swift */, - 05E50F8A1EB7488F002A92A0 /* ColorsCollectionViewDelegate.swift */, - 05E50F8C1EB74937002A92A0 /* ColorCollectionViewCell.swift */, - 05E50F8D1EB74937002A92A0 /* ColorCollectionViewCell.xib */, ); path = "Photo Editor"; sourceTree = ""; @@ -176,13 +224,17 @@ buildActionMask = 2147483647; files = ( 059EA7271EACB8790072C0FE /* LaunchScreen.storyboard in Resources */, - 05E50F8F1EB74937002A92A0 /* ColorCollectionViewCell.xib in Resources */, - 059EA73B1EACD9620072C0FE /* BottomSheetViewController.xib in Resources */, - 05CE343C1EBB792F0010A758 /* Eventtus-Icons.ttf in Resources */, + 0565133B1EF489C0009EA38F /* PhotoCropEditorBorder@3x.png in Resources */, + 0565133D1EF489C0009EA38F /* PhotoEditorViewController.xib in Resources */, 059EA7241EACB8790072C0FE /* Assets.xcassets in Resources */, - 059EA7221EACB8790072C0FE /* PhotoEditor.storyboard in Resources */, - 059EA7481EAD1B550072C0FE /* StickerCollectionViewCell.xib in Resources */, - 055C050A1EB6375800B32735 /* EmojiCollectionViewCell.xib in Resources */, + 056513351EF489C0009EA38F /* ColorCollectionViewCell.xib in Resources */, + 0565133A1EF489C0009EA38F /* PhotoCropEditorBorder@2x.png in Resources */, + 0565133C1EF489C0009EA38F /* StickerCollectionViewCell.xib in Resources */, + 056513371EF489C0009EA38F /* icomoon.ttf in Resources */, + 056513381EF489C0009EA38F /* LaunchScreen.storyboard in Resources */, + 056513341EF489C0009EA38F /* StickersViewController.xib in Resources */, + 056513361EF489C0009EA38F /* EmojiCollectionViewCell.xib in Resources */, + 056513391EF489C0009EA38F /* PhotoCropEditorBorder.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -193,34 +245,38 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 05CE34401EBB792F0010A758 /* UIView+Image.swift in Sources */, - 05E50F8B1EB7488F002A92A0 /* ColorsCollectionViewDelegate.swift in Sources */, - 05DD7E281EC33C35005979EC /* UIImageExtensions.swift in Sources */, - 059EA7471EAD1B550072C0FE /* StickerCollectionViewCell.swift in Sources */, - 05CE343D1EBB792F0010A758 /* GradientView.swift in Sources */, - 059EA71F1EACB8790072C0FE /* PhotoEditorViewController.swift in Sources */, - 05E50F8E1EB74937002A92A0 /* ColorCollectionViewCell.swift in Sources */, - 059EA73A1EACD9620072C0FE /* BottomSheetViewController.swift in Sources */, - 05CE34411EBB792F0010A758 /* ViewGestures.swift in Sources */, - 055C05091EB6375800B32735 /* EmojiCollectionViewCell.swift in Sources */, - 055C050C1EB638A500B32735 /* EmojisCollectionViewDelegate.swift in Sources */, - 05CE343E1EBB792F0010A758 /* Pencil.swift in Sources */, - 05DD7E261EC33BDA005979EC /* UIImageViewExtensions.swift in Sources */, + 056513281EF489B4009EA38F /* UIImage+Crop.swift in Sources */, + 056513221EF489B4009EA38F /* UIView+Image.swift in Sources */, + 056513461EF489CD009EA38F /* PhotoEditor+Gestures.swift in Sources */, + 056513201EF489B4009EA38F /* UIImage+Size.swift in Sources */, + 056513471EF489CD009EA38F /* PhotoEditor+Drawing.swift in Sources */, + 056513191EF489B4009EA38F /* PhotoEditorViewController.swift in Sources */, + 056513261EF489B4009EA38F /* CropRectView.swift in Sources */, + 056513231EF489B4009EA38F /* Protocols.swift in Sources */, + 0565134C1EF489CD009EA38F /* PhotoEditor+Crop.swift in Sources */, + 056513491EF489CD009EA38F /* PhotoEditor+StickersViewController.swift in Sources */, + 0565131D1EF489B4009EA38F /* EmojiCollectionViewCell.swift in Sources */, + 056513271EF489B4009EA38F /* CropViewController.swift in Sources */, + 0565134D1EF489CD009EA38F /* PhotoEditor+Font.swift in Sources */, + 0565131C1EF489B4009EA38F /* ColorsCollectionViewDelegate.swift in Sources */, + 0565131E1EF489B4009EA38F /* EmojisCollectionViewDelegate.swift in Sources */, + 0565131A1EF489B4009EA38F /* StickersViewController.swift in Sources */, + 056513481EF489CD009EA38F /* PhotoEditor+Keyboard.swift in Sources */, + 0565131B1EF489B4009EA38F /* ColorCollectionViewCell.swift in Sources */, + 0565131F1EF489B4009EA38F /* StickerCollectionViewCell.swift in Sources */, + 056513251EF489B4009EA38F /* CropView.swift in Sources */, + 0565134A1EF489CD009EA38F /* PhotoEditor+UITextView.swift in Sources */, + 056513241EF489B4009EA38F /* GradientView.swift in Sources */, 059EA71D1EACB8790072C0FE /* AppDelegate.swift in Sources */, + 0565134B1EF489CD009EA38F /* PhotoEditor+Controls.swift in Sources */, + 056513211EF489B4009EA38F /* UIImageView+Alpha.swift in Sources */, + 056513291EF489B4009EA38F /* ResizeControl.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ - 059EA7201EACB8790072C0FE /* PhotoEditor.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 059EA7211EACB8790072C0FE /* Base */, - ); - name = PhotoEditor.storyboard; - sourceTree = ""; - }; 059EA7251EACB8790072C0FE /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( diff --git a/Photo Editor/Photo Editor.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Photo Editor/Photo Editor.xcodeproj/project.xcworkspace/contents.xcworkspacedata old mode 100755 new mode 100644 diff --git a/Photo Editor/Photo Editor.xcodeproj/project.xcworkspace/xcuserdata/hamed.xcuserdatad/UserInterfaceState.xcuserstate b/Photo Editor/Photo Editor.xcodeproj/project.xcworkspace/xcuserdata/hamed.xcuserdatad/UserInterfaceState.xcuserstate old mode 100755 new mode 100644 index 5c8764d4b..fbc9b1d8f Binary files a/Photo Editor/Photo Editor.xcodeproj/project.xcworkspace/xcuserdata/hamed.xcuserdatad/UserInterfaceState.xcuserstate and b/Photo Editor/Photo Editor.xcodeproj/project.xcworkspace/xcuserdata/hamed.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Photo Editor/Photo Editor.xcodeproj/project.xcworkspace/xcuserdata/manch.xcuserdatad/UserInterfaceState.xcuserstate b/Photo Editor/Photo Editor.xcodeproj/project.xcworkspace/xcuserdata/manch.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 000000000..9773acc40 Binary files /dev/null and b/Photo Editor/Photo Editor.xcodeproj/project.xcworkspace/xcuserdata/manch.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Photo Editor/Photo Editor.xcodeproj/xcshareddata/xcschemes/Photo Editor.xcscheme b/Photo Editor/Photo Editor.xcodeproj/xcshareddata/xcschemes/Photo Editor.xcscheme new file mode 100644 index 000000000..9d11aa1b6 --- /dev/null +++ b/Photo Editor/Photo Editor.xcodeproj/xcshareddata/xcschemes/Photo Editor.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Photo Editor/Photo Editor.xcodeproj/xcuserdata/hamed.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Photo Editor/Photo Editor.xcodeproj/xcuserdata/hamed.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist old mode 100755 new mode 100644 diff --git a/Photo Editor/Photo Editor.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/Photo Editor.xcscheme b/Photo Editor/Photo Editor.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/Photo Editor.xcscheme old mode 100755 new mode 100644 diff --git a/Photo Editor/Photo Editor.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/xcschememanagement.plist b/Photo Editor/Photo Editor.xcodeproj/xcuserdata/hamed.xcuserdatad/xcschemes/xcschememanagement.plist old mode 100755 new mode 100644 diff --git a/Photo Editor/Photo Editor.xcodeproj/xcuserdata/manch.xcuserdatad/xcschemes/xcschememanagement.plist b/Photo Editor/Photo Editor.xcodeproj/xcuserdata/manch.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 000000000..d956e3036 --- /dev/null +++ b/Photo Editor/Photo Editor.xcodeproj/xcuserdata/manch.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + Photo Editor.xcscheme_^#shared#^_ + + orderHint + 0 + + + SuppressBuildableAutocreation + + 059EA7181EACB8790072C0FE + + primary + + + + + diff --git a/Photo Editor/Photo Editor/AppDelegate.swift b/Photo Editor/Photo Editor/AppDelegate.swift old mode 100755 new mode 100644 diff --git a/Photo Editor/Photo Editor/Assets.xcassets/AppIcon.appiconset/Contents.json b/Photo Editor/Photo Editor/Assets.xcassets/AppIcon.appiconset/Contents.json old mode 100755 new mode 100644 diff --git a/Photo Editor/Photo Editor/Assets.xcassets/Contents.json b/Photo Editor/Photo Editor/Assets.xcassets/Contents.json old mode 100755 new mode 100644 diff --git a/Photo Editor/Photo Editor/Base.lproj/LaunchScreen.storyboard b/Photo Editor/Photo Editor/Base.lproj/LaunchScreen.storyboard old mode 100755 new mode 100644 diff --git a/Photo Editor/Photo Editor/Base.lproj/PhotoEditor.storyboard b/Photo Editor/Photo Editor/Base.lproj/PhotoEditor.storyboard deleted file mode 100755 index 862d1e399..000000000 --- a/Photo Editor/Photo Editor/Base.lproj/PhotoEditor.storyboard +++ /dev/null @@ -1,322 +0,0 @@ - - - - - - - - - - - - Eventtus-Icons - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Photo Editor/Photo Editor/ColorCollectionViewCell.swift b/Photo Editor/Photo Editor/ColorCollectionViewCell.swift old mode 100755 new mode 100644 diff --git a/Photo Editor/Photo Editor/ColorCollectionViewCell.xib b/Photo Editor/Photo Editor/ColorCollectionViewCell.xib old mode 100755 new mode 100644 diff --git a/Photo Editor/Photo Editor/ColorsCollectionViewDelegate.swift b/Photo Editor/Photo Editor/ColorsCollectionViewDelegate.swift old mode 100755 new mode 100644 index a51d8a9eb..6d3acd47d --- a/Photo Editor/Photo Editor/ColorsCollectionViewDelegate.swift +++ b/Photo Editor/Photo Editor/ColorsCollectionViewDelegate.swift @@ -8,30 +8,40 @@ import UIKit -protocol ColorDelegate { - func chosedColor(color: UIColor) -} - class ColorsCollectionViewDelegate: NSObject, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { var colorDelegate : ColorDelegate? - let colors = [UIColor.black, UIColor.darkGray, UIColor.gray, - UIColor.lightGray, UIColor.white, UIColor.blue, UIColor.green, UIColor.red, UIColor.yellow, - UIColor.orange, UIColor.purple, UIColor.cyan, UIColor.brown, UIColor.purple] + /** + Array of Colors that will show while drawing or typing + */ + var colors = [UIColor.black, + UIColor.darkGray, + UIColor.gray, + UIColor.lightGray, + UIColor.white, + UIColor.blue, + UIColor.green, + UIColor.red, + UIColor.yellow, + UIColor.orange, + UIColor.purple, + UIColor.cyan, + UIColor.brown, + UIColor.magenta] override init() { super.init() } - var stickerDelegate : StickerDelegate? + var stickersViewControllerDelegate : StickersViewControllerDelegate? func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return colors.count } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - colorDelegate?.chosedColor(color: colors[indexPath.item]) + colorDelegate?.didSelectColor(color: colors[indexPath.item]) } func numberOfSections(in collectionView: UICollectionView) -> Int { diff --git a/Photo Editor/Photo Editor/CropRectView.swift b/Photo Editor/Photo Editor/CropRectView.swift new file mode 100755 index 000000000..c8f4ec910 --- /dev/null +++ b/Photo Editor/Photo Editor/CropRectView.swift @@ -0,0 +1,324 @@ + +// +// CropRectView.swift +// CropViewController +// +// Created by Guilherme Moura on 2/26/16. +// Copyright © 2016 Reefactor, Inc. All rights reserved. +// Credit https://github.com/sprint84/PhotoCropEditor + +import UIKit + +protocol CropRectViewDelegate: class { + func cropRectViewDidBeginEditing(_ view: CropRectView) + func cropRectViewDidChange(_ view: CropRectView) + func cropRectViewDidEndEditing(_ view: CropRectView) +} + +class CropRectView: UIView, ResizeControlDelegate { + weak var delegate: CropRectViewDelegate? + var showsGridMajor = true { + didSet { + setNeedsDisplay() + } + } + var showsGridMinor = false { + didSet { + setNeedsDisplay() + } + } + var keepAspectRatio = false { + didSet { + if keepAspectRatio { + let width = bounds.width + let height = bounds.height + fixedAspectRatio = min(width / height, height / width) + } + } + } + + fileprivate var resizeImageView: UIImageView! + fileprivate let topLeftCornerView = ResizeControl() + fileprivate let topRightCornerView = ResizeControl() + fileprivate let bottomLeftCornerView = ResizeControl() + fileprivate let bottomRightCornerView = ResizeControl() + fileprivate let topEdgeView = ResizeControl() + fileprivate let leftEdgeView = ResizeControl() + fileprivate let rightEdgeView = ResizeControl() + fileprivate let bottomEdgeView = ResizeControl() + fileprivate var initialRect = CGRect.zero + fileprivate var fixedAspectRatio: CGFloat = 0.0 + + override init(frame: CGRect) { + super.init(frame: frame) + initialize() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + initialize() + } + + fileprivate func initialize() { + backgroundColor = UIColor.clear + contentMode = .redraw + + resizeImageView = UIImageView(frame: bounds.insetBy(dx: -2.0, dy: -2.0)) + resizeImageView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + let bundle = Bundle(for: type(of: self)) + let image = UIImage(named: "PhotoCropEditorBorder", in: bundle, compatibleWith: nil) + resizeImageView.image = image?.resizableImage(withCapInsets: UIEdgeInsets(top: 23.0, left: 23.0, bottom: 23.0, right: 23.0)) + addSubview(resizeImageView) + + topEdgeView.delegate = self + addSubview(topEdgeView) + leftEdgeView.delegate = self + addSubview(leftEdgeView) + rightEdgeView.delegate = self + addSubview(rightEdgeView) + bottomEdgeView.delegate = self + addSubview(bottomEdgeView) + + topLeftCornerView.delegate = self + addSubview(topLeftCornerView) + topRightCornerView.delegate = self + addSubview(topRightCornerView) + bottomLeftCornerView.delegate = self + addSubview(bottomLeftCornerView) + bottomRightCornerView.delegate = self + addSubview(bottomRightCornerView) + } + + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + for subview in subviews where subview is ResizeControl { + if subview.frame.contains(point) { + return subview + } + } + return nil + } + + override func draw(_ rect: CGRect) { + super.draw(rect) + + let width = bounds.width + let height = bounds.height + + for i in 0 ..< 3 { + let borderPadding: CGFloat = 0.5 + + if showsGridMinor { + for j in 1 ..< 3 { + UIColor(red: 1.0, green: 1.0, blue: 0.0, alpha: 0.3).set() + UIRectFill(CGRect(x: round((width / 9.0) * CGFloat(j) + (width / 3.0) * CGFloat(i)), y: borderPadding, width: 1.0, height: round(height) - borderPadding * 2.0)) + UIRectFill(CGRect(x: borderPadding, y: round((height / 9.0) * CGFloat(j) + (height / 3.0) * CGFloat(i)), width: round(width) - borderPadding * 2.0, height: 1.0)) + } + } + + if showsGridMajor { + if i > 0 { + UIColor.white.set() + UIRectFill(CGRect(x: round(CGFloat(i) * width / 3.0), y: borderPadding, width: 1.0, height: round(height) - borderPadding * 2.0)) + UIRectFill(CGRect(x: borderPadding, y: round(CGFloat(i) * height / 3.0), width: round(width) - borderPadding * 2.0, height: 1.0)) + } + } + } + } + + override func layoutSubviews() { + super.layoutSubviews() + + topLeftCornerView.frame.origin = CGPoint(x: topLeftCornerView.bounds.width / -2.0, y: topLeftCornerView.bounds.height / -2.0) + topRightCornerView.frame.origin = CGPoint(x: bounds.width - topRightCornerView.bounds.width - 2.0, y: topRightCornerView.bounds.height / -2.0) + bottomLeftCornerView.frame.origin = CGPoint(x: bottomLeftCornerView.bounds.width / -2.0, y: bounds.height - bottomLeftCornerView.bounds.height / 2.0) + bottomRightCornerView.frame.origin = CGPoint(x: bounds.width - bottomRightCornerView.bounds.width / 2.0, y: bounds.height - bottomRightCornerView.bounds.height / 2.0) + + topEdgeView.frame = CGRect(x: topLeftCornerView.frame.maxX, y: topEdgeView.frame.height / -2.0, width: topRightCornerView.frame.minX - topLeftCornerView.frame.maxX, height: topEdgeView.bounds.height) + leftEdgeView.frame = CGRect(x: leftEdgeView.frame.width / -2.0, y: topLeftCornerView.frame.maxY, width: leftEdgeView.frame.width, height: bottomLeftCornerView.frame.minY - topLeftCornerView.frame.maxY) + bottomEdgeView.frame = CGRect(x: bottomLeftCornerView.frame.maxX, y: bottomLeftCornerView.frame.minY, width: bottomRightCornerView.frame.minX - bottomLeftCornerView.frame.maxX, height: bottomEdgeView.frame.height) + rightEdgeView.frame = CGRect(x: bounds.width - rightEdgeView.frame.width / 2.0, y: topRightCornerView.frame.maxY, width: rightEdgeView.frame.width, height: bottomRightCornerView.frame.minY - topRightCornerView.frame.maxY) + } + + func enableResizing(_ enabled: Bool) { + resizeImageView.isHidden = !enabled + + topLeftCornerView.enabled = enabled + topRightCornerView.enabled = enabled + bottomLeftCornerView.enabled = enabled + bottomRightCornerView.enabled = enabled + + topEdgeView.enabled = enabled + leftEdgeView.enabled = enabled + bottomEdgeView.enabled = enabled + rightEdgeView.enabled = enabled + } + + // MARK: - ResizeControl delegate methods + func resizeControlDidBeginResizing(_ control: ResizeControl) { + initialRect = frame + delegate?.cropRectViewDidBeginEditing(self) + } + + func resizeControlDidResize(_ control: ResizeControl) { + frame = cropRectWithResizeControlView(control) + delegate?.cropRectViewDidChange(self) + } + + func resizeControlDidEndResizing(_ control: ResizeControl) { + delegate?.cropRectViewDidEndEditing(self) + } + + fileprivate func cropRectWithResizeControlView(_ resizeControl: ResizeControl) -> CGRect { + var rect = frame + + if resizeControl == topEdgeView { + rect = CGRect(x: initialRect.minX, + y: initialRect.minY + resizeControl.translation.y, + width: initialRect.width, + height: initialRect.height - resizeControl.translation.y) + + if keepAspectRatio { + rect = constrainedRectWithRectBasisOfHeight(rect) + } + } else if resizeControl == leftEdgeView { + rect = CGRect(x: initialRect.minX + resizeControl.translation.x, + y: initialRect.minY, + width: initialRect.width - resizeControl.translation.x, + height: initialRect.height) + + if keepAspectRatio { + rect = constrainedRectWithRectBasisOfWidth(rect) + } + } else if resizeControl == bottomEdgeView { + rect = CGRect(x: initialRect.minX, + y: initialRect.minY, + width: initialRect.width, + height: initialRect.height + resizeControl.translation.y) + + if keepAspectRatio { + rect = constrainedRectWithRectBasisOfHeight(rect) + } + } else if resizeControl == rightEdgeView { + rect = CGRect(x: initialRect.minX, + y: initialRect.minY, + width: initialRect.width + resizeControl.translation.x, + height: initialRect.height) + + if keepAspectRatio { + rect = constrainedRectWithRectBasisOfWidth(rect) + } + } else if resizeControl == topLeftCornerView { + rect = CGRect(x: initialRect.minX + resizeControl.translation.x, + y: initialRect.minY + resizeControl.translation.y, + width: initialRect.width - resizeControl.translation.x, + height: initialRect.height - resizeControl.translation.y) + + if keepAspectRatio { + var constrainedFrame: CGRect + if abs(resizeControl.translation.x) < abs(resizeControl.translation.y) { + constrainedFrame = constrainedRectWithRectBasisOfHeight(rect) + } else { + constrainedFrame = constrainedRectWithRectBasisOfWidth(rect) + } + constrainedFrame.origin.x -= constrainedFrame.width - rect.width + constrainedFrame.origin.y -= constrainedFrame.height - rect.height + rect = constrainedFrame + } + } else if resizeControl == topRightCornerView { + rect = CGRect(x: initialRect.minX, + y: initialRect.minY + resizeControl.translation.y, + width: initialRect.width + resizeControl.translation.x, + height: initialRect.height - resizeControl.translation.y) + + if keepAspectRatio { + if abs(resizeControl.translation.x) < abs(resizeControl.translation.y) { + rect = constrainedRectWithRectBasisOfHeight(rect) + } else { + rect = constrainedRectWithRectBasisOfWidth(rect) + } + } + } else if resizeControl == bottomLeftCornerView { + rect = CGRect(x: initialRect.minX + resizeControl.translation.x, + y: initialRect.minY, + width: initialRect.width - resizeControl.translation.x, + height: initialRect.height + resizeControl.translation.y) + + if keepAspectRatio { + var constrainedFrame: CGRect + if abs(resizeControl.translation.x) < abs(resizeControl.translation.y) { + constrainedFrame = constrainedRectWithRectBasisOfHeight(rect) + } else { + constrainedFrame = constrainedRectWithRectBasisOfWidth(rect) + } + constrainedFrame.origin.x -= constrainedFrame.width - rect.width + rect = constrainedFrame + } + } else if resizeControl == bottomRightCornerView { + rect = CGRect(x: initialRect.minX, + y: initialRect.minY, + width: initialRect.width + resizeControl.translation.x, + height: initialRect.height + resizeControl.translation.y) + + if keepAspectRatio { + if abs(resizeControl.translation.x) < abs(resizeControl.translation.y) { + rect = constrainedRectWithRectBasisOfHeight(rect) + } else { + rect = constrainedRectWithRectBasisOfWidth(rect) + } + } + } + + let minWidth = leftEdgeView.bounds.width + rightEdgeView.bounds.width + if rect.width < minWidth { + rect.origin.x = frame.maxX - minWidth + rect.size.width = minWidth + } + + let minHeight = topEdgeView.bounds.height + bottomEdgeView.bounds.height + if rect.height < minHeight { + rect.origin.y = frame.maxY - minHeight + rect.size.height = minHeight + } + + if fixedAspectRatio > 0 { + var constraintedFrame = rect + if rect.width < minWidth { + constraintedFrame.size.width = rect.size.height * (minWidth / rect.size.width) + } + if rect.height < minHeight { + constraintedFrame.size.height = rect.size.width * (minHeight / rect.size.height) + } + rect = constraintedFrame + } + + return rect + } + + fileprivate func constrainedRectWithRectBasisOfWidth(_ frame: CGRect) -> CGRect { + var result = frame + let width = frame.width + var height = frame.height + + if width < height { + height = width / fixedAspectRatio + } else { + height = width * fixedAspectRatio + } + result.size = CGSize(width: width, height: height) + return result + } + + fileprivate func constrainedRectWithRectBasisOfHeight(_ frame: CGRect) -> CGRect { + var result = frame + var width = frame.width + let height = frame.height + + if width < height { + width = height * fixedAspectRatio + } else { + width = height / fixedAspectRatio + } + result.size = CGSize(width: width, height: height) + return result + } +} diff --git a/Photo Editor/Photo Editor/CropView.swift b/Photo Editor/Photo Editor/CropView.swift new file mode 100755 index 000000000..11fbd49eb --- /dev/null +++ b/Photo Editor/Photo Editor/CropView.swift @@ -0,0 +1,489 @@ +// +// CropView.swift +// CropViewController +// +// Created by Guilherme Moura on 2/25/16. +// Copyright © 2016 Reefactor, Inc. All rights reserved. +// Credit https://github.com/sprint84/PhotoCropEditor + +import UIKit +import AVFoundation + +open class CropView: UIView, UIScrollViewDelegate, UIGestureRecognizerDelegate, CropRectViewDelegate { + open var image: UIImage? { + didSet { + if image != nil { + imageSize = image!.size + } + imageView?.removeFromSuperview() + imageView = nil + zoomingView?.removeFromSuperview() + zoomingView = nil + setNeedsLayout() + } + } + open var imageView: UIView? { + didSet { + if let view = imageView , image == nil { + imageSize = view.frame.size + } + usingCustomImageView = true + setNeedsLayout() + } + } + open var croppedImage: UIImage? { + return image?.rotatedImageWithTransform(rotation, croppedToRect: zoomedCropRect()) + } + open var keepAspectRatio = false { + didSet { + cropRectView.keepAspectRatio = keepAspectRatio + } + } + open var cropAspectRatio: CGFloat { + set { + setCropAspectRatio(newValue, shouldCenter: true) + } + get { + let rect = scrollView.frame + let width = rect.width + let height = rect.height + return width / height + } + } + open var rotation: CGAffineTransform { + guard let imgView = imageView else { + return CGAffineTransform.identity + } + return imgView.transform + } + open var rotationAngle: CGFloat { + set { + imageView?.transform = CGAffineTransform(rotationAngle: newValue) + } + get { + return atan2(rotation.b, rotation.a) + } + } + open var cropRect: CGRect { + set { + zoomToCropRect(newValue) + } + get { + return scrollView.frame + } + } + open var imageCropRect = CGRect.zero { + didSet { + resetCropRect() + + let scale = min(scrollView.frame.width / imageSize.width, scrollView.frame.height / imageSize.height) + let x = imageCropRect.minX * scale + scrollView.frame.minX + let y = imageCropRect.minY * scale + scrollView.frame.minY + let width = imageCropRect.width * scale + let height = imageCropRect.height * scale + + let rect = CGRect(x: x, y: y, width: width, height: height) + let intersection = rect.intersection(scrollView.frame) + + if !intersection.isNull { + cropRect = intersection + } + } + } + open var resizeEnabled = true { + didSet { + cropRectView.enableResizing(resizeEnabled) + } + } + open var showCroppedArea = true { + didSet { + layoutIfNeeded() + scrollView.clipsToBounds = !showCroppedArea + showOverlayView(showCroppedArea) + } + } + open var rotationGestureRecognizer: UIRotationGestureRecognizer! + fileprivate var imageSize = CGSize(width: 1.0, height: 1.0) + fileprivate var scrollView: UIScrollView! + fileprivate var zoomingView: UIView? + fileprivate let cropRectView = CropRectView() + fileprivate let topOverlayView = UIView() + fileprivate let leftOverlayView = UIView() + fileprivate let rightOverlayView = UIView() + fileprivate let bottomOverlayView = UIView() + fileprivate var insetRect = CGRect.zero + fileprivate var editingRect = CGRect.zero + fileprivate var interfaceOrientation = UIApplication.shared.statusBarOrientation + fileprivate var resizing = false + fileprivate var usingCustomImageView = false + fileprivate let MarginTop: CGFloat = 37.0 + fileprivate let MarginLeft: CGFloat = 20.0 + + public override init(frame: CGRect) { + super.init(frame: frame) + initialize() + } + + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + initialize() + } + + fileprivate func initialize() { + autoresizingMask = [.flexibleWidth, .flexibleHeight] + backgroundColor = UIColor.clear + + scrollView = UIScrollView(frame: bounds) + scrollView.delegate = self + scrollView.autoresizingMask = [.flexibleTopMargin, .flexibleLeftMargin, .flexibleBottomMargin, .flexibleRightMargin] + scrollView.backgroundColor = UIColor.clear + scrollView.maximumZoomScale = 20.0 + scrollView.minimumZoomScale = 1.0 + scrollView.showsHorizontalScrollIndicator = false + scrollView.showsVerticalScrollIndicator = false + scrollView.bounces = false + scrollView.bouncesZoom = false + scrollView.clipsToBounds = false + addSubview(scrollView) + + rotationGestureRecognizer = UIRotationGestureRecognizer(target: self, action: #selector(CropView.handleRotation(_:))) + rotationGestureRecognizer?.delegate = self + scrollView.addGestureRecognizer(rotationGestureRecognizer) + + cropRectView.delegate = self + addSubview(cropRectView) + + showOverlayView(showCroppedArea) + addSubview(topOverlayView) + addSubview(leftOverlayView) + addSubview(rightOverlayView) + addSubview(bottomOverlayView) + } + + open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + if !isUserInteractionEnabled { + return nil + } + + if let hitView = cropRectView.hitTest(convert(point, to: cropRectView), with: event) { + return hitView + } + let locationInImageView = convert(point, to: zoomingView) + let zoomedPoint = CGPoint(x: locationInImageView.x * scrollView.zoomScale, y: locationInImageView.y * scrollView.zoomScale) + if zoomingView!.frame.contains(zoomedPoint) { + return scrollView + } + return super.hitTest(point, with: event) + } + + open override func layoutSubviews() { + super.layoutSubviews() + let interfaceOrientation = UIApplication.shared.statusBarOrientation + + if image == nil && imageView == nil { + return + } + + setupEditingRect() + + if imageView == nil { + if UIInterfaceOrientationIsPortrait(interfaceOrientation) { + insetRect = bounds.insetBy(dx: MarginLeft, dy: MarginTop) + } else { + insetRect = bounds.insetBy(dx: MarginLeft, dy: MarginLeft) + } + if !showCroppedArea { + insetRect = editingRect + } + setupZoomingView() + setupImageView() + } else if usingCustomImageView { + if UIInterfaceOrientationIsPortrait(interfaceOrientation) { + insetRect = bounds.insetBy(dx: MarginLeft, dy: MarginTop) + } else { + insetRect = bounds.insetBy(dx: MarginLeft, dy: MarginLeft) + } + if !showCroppedArea { + insetRect = editingRect + } + setupZoomingView() + imageView?.frame = zoomingView!.bounds + zoomingView?.addSubview(imageView!) + usingCustomImageView = false + } + + if !resizing { + layoutCropRectViewWithCropRect(scrollView.frame) + if self.interfaceOrientation != interfaceOrientation { + zoomToCropRect(scrollView.frame) + } + } + + + self.interfaceOrientation = interfaceOrientation + } + + open func setRotationAngle(_ rotationAngle: CGFloat, snap: Bool) { + var rotation = rotationAngle + if snap { + rotation = nearbyint(rotationAngle / CGFloat(Double.pi/2)) * CGFloat(Double.pi/2) + } + self.rotationAngle = rotation + } + + open func resetCropRect() { + resetCropRectAnimated(false) + } + + open func resetCropRectAnimated(_ animated: Bool) { + if animated { + UIView.beginAnimations(nil, context: nil) + UIView.setAnimationDuration(0.25) + UIView.setAnimationBeginsFromCurrentState(true) + } + imageView?.transform = CGAffineTransform.identity + let contentSize = scrollView.contentSize + let initialRect = CGRect(x: 0, y: 0, width: contentSize.width, height: contentSize.height) + scrollView.zoom(to: initialRect, animated: false) + + layoutCropRectViewWithCropRect(scrollView.bounds) + + if animated { + UIView.commitAnimations() + } + } + + open func zoomedCropRect() -> CGRect { + let cropRect = convert(scrollView.frame, to: zoomingView) + var ratio: CGFloat = 1.0 + let orientation = UIApplication.shared.statusBarOrientation + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad || UIInterfaceOrientationIsPortrait(orientation)) { + ratio = AVMakeRect(aspectRatio: imageSize, insideRect: insetRect).width / imageSize.width + } else { + ratio = AVMakeRect(aspectRatio: imageSize, insideRect: insetRect).height / imageSize.height + } + + let zoomedCropRect = CGRect(x: cropRect.origin.x / ratio, + y: cropRect.origin.y / ratio, + width: cropRect.size.width / ratio, + height: cropRect.size.height / ratio) + + return zoomedCropRect + } + + open func croppedImage(_ image: UIImage) -> UIImage { + imageSize = image.size + return image.rotatedImageWithTransform(rotation, croppedToRect: zoomedCropRect()) + } + + func handleRotation(_ gestureRecognizer: UIRotationGestureRecognizer) { + if let imageView = imageView { + let rotation = gestureRecognizer.rotation + let transform = imageView.transform.rotated(by: rotation) + imageView.transform = transform + gestureRecognizer.rotation = 0.0 + } + + switch gestureRecognizer.state { + case .began, .changed: + cropRectView.showsGridMinor = true + default: + cropRectView.showsGridMinor = false + } + } + + // MARK: - Private methods + fileprivate func showOverlayView(_ show: Bool) { + let color = show ? UIColor(white: 0.0, alpha: 0.4) : UIColor.clear + + topOverlayView.backgroundColor = color + leftOverlayView.backgroundColor = color + rightOverlayView.backgroundColor = color + bottomOverlayView.backgroundColor = color + } + + fileprivate func setupEditingRect() { + let interfaceOrientation = UIApplication.shared.statusBarOrientation + if UIInterfaceOrientationIsPortrait(interfaceOrientation) { + editingRect = bounds.insetBy(dx: MarginLeft, dy: MarginTop) + } else { + editingRect = bounds.insetBy(dx: MarginLeft, dy: MarginLeft) + } + if !showCroppedArea { + editingRect = CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height) + } + } + + fileprivate func setupZoomingView() { + let cropRect = AVMakeRect(aspectRatio: imageSize, insideRect: insetRect) + + scrollView.frame = cropRect + scrollView.contentSize = cropRect.size + + zoomingView = UIView(frame: scrollView.bounds) + zoomingView?.backgroundColor = .clear + scrollView.addSubview(zoomingView!) + } + + fileprivate func setupImageView() { + let imageView = UIImageView(frame: zoomingView!.bounds) + imageView.backgroundColor = .clear + imageView.contentMode = .scaleAspectFit + imageView.image = image + zoomingView?.addSubview(imageView) + self.imageView = imageView + usingCustomImageView = false + } + + fileprivate func layoutCropRectViewWithCropRect(_ cropRect: CGRect) { + cropRectView.frame = cropRect + layoutOverlayViewsWithCropRect(cropRect) + } + + fileprivate func layoutOverlayViewsWithCropRect(_ cropRect: CGRect) { + topOverlayView.frame = CGRect(x: 0, y: 0, width: bounds.width, height: cropRect.minY) + leftOverlayView.frame = CGRect(x: 0, y: cropRect.minY, width: cropRect.minX, height: cropRect.height) + rightOverlayView.frame = CGRect(x: cropRect.maxX, y: cropRect.minY, width: bounds.width - cropRect.maxX, height: cropRect.height) + bottomOverlayView.frame = CGRect(x: 0, y: cropRect.maxY, width: bounds.width, height: bounds.height - cropRect.maxY) + } + + fileprivate func zoomToCropRect(_ toRect: CGRect) { + zoomToCropRect(toRect, shouldCenter: false, animated: true) + } + + fileprivate func zoomToCropRect(_ toRect: CGRect, shouldCenter: Bool, animated: Bool, completion: (() -> Void)? = nil) { + if scrollView.frame.equalTo(toRect) { + return + } + + let width = toRect.width + let height = toRect.height + let scale = min(editingRect.width / width, editingRect.height / height) + + let scaledWidth = width * scale + let scaledHeight = height * scale + let cropRect = CGRect(x: (bounds.width - scaledWidth) / 2.0, y: (bounds.height - scaledHeight) / 2.0, width: scaledWidth, height: scaledHeight) + + var zoomRect = convert(toRect, to: zoomingView) + zoomRect.size.width = cropRect.width / (scrollView.zoomScale * scale) + zoomRect.size.height = cropRect.height / (scrollView.zoomScale * scale) + + if let imgView = imageView , shouldCenter { + let imageViewBounds = imgView.bounds + zoomRect.origin.x = (imageViewBounds.width / 2.0) - (zoomRect.width / 2.0) + zoomRect.origin.y = (imageViewBounds.height / 2.0) - (zoomRect.height / 2.0) + } + + var duration = 0.0 + if animated { + duration = 0.25 + } + + UIView.animate(withDuration: duration, delay: 0.0, options: .beginFromCurrentState, animations: { [unowned self] in + self.scrollView.bounds = cropRect + self.scrollView.zoom(to: zoomRect, animated: false) + self.layoutCropRectViewWithCropRect(cropRect) + }) { finished in + completion?() + } + } + + fileprivate func cappedCropRectInImageRectWithCropRectView(_ cropRectView: CropRectView) -> CGRect { + var cropRect = cropRectView.frame + + let rect = convert(cropRect, to: scrollView) + if rect.minX < zoomingView!.frame.minX { + cropRect.origin.x = scrollView.convert(zoomingView!.frame, to: self).minX + let cappedWidth = rect.maxX + let height = !keepAspectRatio ? cropRect.size.height : cropRect.size.height * (cappedWidth / cropRect.size.width) + cropRect.size = CGSize(width: cappedWidth, height: height) + } + + if rect.minY < zoomingView!.frame.minY { + cropRect.origin.y = scrollView.convert(zoomingView!.frame, to: self).minY + let cappedHeight = rect.maxY + let width = !keepAspectRatio ? cropRect.size.width : cropRect.size.width * (cappedHeight / cropRect.size.height) + cropRect.size = CGSize(width: width, height: cappedHeight) + } + + if rect.maxX > zoomingView!.frame.maxX { + let cappedWidth = scrollView.convert(zoomingView!.frame, to: self).maxX - cropRect.minX + let height = !keepAspectRatio ? cropRect.size.height : cropRect.size.height * (cappedWidth / cropRect.size.width) + cropRect.size = CGSize(width: cappedWidth, height: height) + } + + if rect.maxY > zoomingView!.frame.maxY { + let cappedHeight = scrollView.convert(zoomingView!.frame, to: self).maxY - cropRect.minY + let width = !keepAspectRatio ? cropRect.size.width : cropRect.size.width * (cappedHeight / cropRect.size.height) + cropRect.size = CGSize(width: width, height: cappedHeight) + } + + return cropRect + } + + fileprivate func automaticZoomIfEdgeTouched(_ cropRect: CGRect) { + if cropRect.minX < editingRect.minX - 5.0 || + cropRect.maxX > editingRect.maxX + 5.0 || + cropRect.minY < editingRect.minY - 5.0 || + cropRect.maxY > editingRect.maxY + 5.0 { + UIView.animate(withDuration: 1.0, delay: 0.0, options: .beginFromCurrentState, animations: { [unowned self] in + self.zoomToCropRect(self.cropRectView.frame) + }, completion: nil) + } + } + + fileprivate func setCropAspectRatio(_ ratio: CGFloat, shouldCenter: Bool) { + var cropRect = scrollView.frame + var width = cropRect.width + var height = cropRect.height + if ratio <= 1.0 { + width = height * ratio + if width > imageView!.bounds.width { + width = cropRect.width + height = width / ratio + } + } else { + height = width / ratio + if height > imageView!.bounds.height { + height = cropRect.height + width = height * ratio + } + } + cropRect.size = CGSize(width: width, height: height) + zoomToCropRect(cropRect, shouldCenter: shouldCenter, animated: false) { + let scale = self.scrollView.zoomScale + self.scrollView.minimumZoomScale = scale + } + } + + // MARK: - CropView delegate methods + func cropRectViewDidBeginEditing(_ view: CropRectView) { + resizing = true + } + + func cropRectViewDidChange(_ view: CropRectView) { + let cropRect = cappedCropRectInImageRectWithCropRectView(view) + layoutCropRectViewWithCropRect(cropRect) + automaticZoomIfEdgeTouched(cropRect) + } + + func cropRectViewDidEndEditing(_ view: CropRectView) { + resizing = false + zoomToCropRect(cropRectView.frame) + } + + // MARK: - ScrollView delegate methods + open func viewForZooming(in scrollView: UIScrollView) -> UIView? { + return zoomingView + } + + open func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { + let contentOffset = scrollView.contentOffset + targetContentOffset.pointee = contentOffset + } + + // MARK: - Gesture Recognizer delegate methods + open func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { + return true + } +} diff --git a/Photo Editor/Photo Editor/CropViewController.swift b/Photo Editor/Photo Editor/CropViewController.swift new file mode 100755 index 000000000..2c17de4d0 --- /dev/null +++ b/Photo Editor/Photo Editor/CropViewController.swift @@ -0,0 +1,243 @@ +// +// CropViewController.swift +// CropViewController +// +// Created by Guilherme Moura on 2/25/16. +// Copyright © 2016 Reefactor, Inc. All rights reserved. +// Credit https://github.com/sprint84/PhotoCropEditor + +import UIKit + +public protocol CropViewControllerDelegate: class { + func cropViewController(_ controller: CropViewController, didFinishCroppingImage image: UIImage, transform: CGAffineTransform, cropRect: CGRect) + func cropViewControllerDidCancel(_ controller: CropViewController) +} + +open class CropViewController: UIViewController { + open weak var delegate: CropViewControllerDelegate? + open var image: UIImage? { + didSet { + cropView?.image = image + } + } + open var keepAspectRatio = false { + didSet { + cropView?.keepAspectRatio = keepAspectRatio + } + } + open var cropAspectRatio: CGFloat = 0.0 { + didSet { + cropView?.cropAspectRatio = cropAspectRatio + } + } + open var cropRect = CGRect.zero { + didSet { + adjustCropRect() + } + } + open var imageCropRect = CGRect.zero { + didSet { + cropView?.imageCropRect = imageCropRect + } + } + open var toolbarHidden = false + open var rotationEnabled = false { + didSet { + cropView?.rotationGestureRecognizer.isEnabled = rotationEnabled + } + } + open var rotationTransform: CGAffineTransform { + return cropView!.rotation + } + open var zoomedCropRect: CGRect { + return cropView!.zoomedCropRect() + } + + fileprivate var cropView: CropView? + + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + initialize() + } + + public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + initialize() + } + + fileprivate func initialize() { + rotationEnabled = true + } + + open override func loadView() { + let contentView = UIView() + contentView.autoresizingMask = .flexibleWidth + contentView.backgroundColor = UIColor.black + view = contentView + + // Add CropView + cropView = CropView(frame: contentView.bounds) + contentView.addSubview(cropView!) + + } + + open override func viewDidLoad() { + super.viewDidLoad() + + navigationController?.navigationBar.isTranslucent = false + navigationController?.toolbar.isTranslucent = false + navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(CropViewController.cancel(_:))) + navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(CropViewController.done(_:))) + + if self.toolbarItems == nil { + let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) + let constrainButton = UIBarButtonItem(title: "Constrain", style: .plain, target: self, action: #selector(CropViewController.constrain(_:))) + toolbarItems = [flexibleSpace, constrainButton, flexibleSpace] + } + + navigationController?.isToolbarHidden = toolbarHidden + + cropView?.image = image + cropView?.rotationGestureRecognizer.isEnabled = rotationEnabled + } + + open override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + if cropAspectRatio != 0 { + cropView?.cropAspectRatio = cropAspectRatio + } + + if !cropRect.equalTo(CGRect.zero) { + adjustCropRect() + } + + if !imageCropRect.equalTo(CGRect.zero) { + cropView?.imageCropRect = imageCropRect + } + + cropView?.keepAspectRatio = keepAspectRatio + } + + open func resetCropRect() { + cropView?.resetCropRect() + } + + open func resetCropRectAnimated(_ animated: Bool) { + cropView?.resetCropRectAnimated(animated) + } + + func cancel(_ sender: UIBarButtonItem) { + delegate?.cropViewControllerDidCancel(self) + } + + func done(_ sender: UIBarButtonItem) { + if let image = cropView?.croppedImage { + guard let rotation = cropView?.rotation else { + return + } + guard let rect = cropView?.zoomedCropRect() else { + return + } + delegate?.cropViewController(self, didFinishCroppingImage: image, transform: rotation, cropRect: rect) + } + } + + func constrain(_ sender: UIBarButtonItem) { + let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) + let original = UIAlertAction(title: "Original", style: .default) { [unowned self] action in + guard let image = self.cropView?.image else { + return + } + guard var cropRect = self.cropView?.cropRect else { + return + } + let width = image.size.width + let height = image.size.height + let ratio: CGFloat + if width < height { + ratio = width / height + cropRect.size = CGSize(width: cropRect.height * ratio, height: cropRect.height) + } else { + ratio = height / width + cropRect.size = CGSize(width: cropRect.width, height: cropRect.width * ratio) + } + self.cropView?.cropRect = cropRect + } + actionSheet.addAction(original) + let square = UIAlertAction(title: "Square", style: .default) { [unowned self] action in + let ratio: CGFloat = 1.0 +// self.cropView?.cropAspectRatio = ratio + if var cropRect = self.cropView?.cropRect { + let width = cropRect.width + cropRect.size = CGSize(width: width, height: width * ratio) + self.cropView?.cropRect = cropRect + } + } + actionSheet.addAction(square) + let threeByTwo = UIAlertAction(title: "3 x 2", style: .default) { [unowned self] action in + self.cropView?.cropAspectRatio = 2.0 / 3.0 + } + actionSheet.addAction(threeByTwo) + let threeByFive = UIAlertAction(title: "3 x 5", style: .default) { [unowned self] action in + self.cropView?.cropAspectRatio = 3.0 / 5.0 + } + actionSheet.addAction(threeByFive) + let fourByThree = UIAlertAction(title: "4 x 3", style: .default) { [unowned self] action in + let ratio: CGFloat = 3.0 / 4.0 + if var cropRect = self.cropView?.cropRect { + let width = cropRect.width + cropRect.size = CGSize(width: width, height: width * ratio) + self.cropView?.cropRect = cropRect + } + } + actionSheet.addAction(fourByThree) + let fourBySix = UIAlertAction(title: "4 x 6", style: .default) { [unowned self] action in + self.cropView?.cropAspectRatio = 4.0 / 6.0 + } + actionSheet.addAction(fourBySix) + let fiveBySeven = UIAlertAction(title: "5 x 7", style: .default) { [unowned self] action in + self.cropView?.cropAspectRatio = 5.0 / 7.0 + } + actionSheet.addAction(fiveBySeven) + let eightByTen = UIAlertAction(title: "8 x 10", style: .default) { [unowned self] action in + self.cropView?.cropAspectRatio = 8.0 / 10.0 + } + actionSheet.addAction(eightByTen) + let widescreen = UIAlertAction(title: "16 x 9", style: .default) { [unowned self] action in + let ratio: CGFloat = 9.0 / 16.0 + if var cropRect = self.cropView?.cropRect { + let width = cropRect.width + cropRect.size = CGSize(width: width, height: width * ratio) + self.cropView?.cropRect = cropRect + } + } + actionSheet.addAction(widescreen) + let cancel = UIAlertAction(title: "Cancel", style: .default) { [unowned self] action in + self.dismiss(animated: true, completion: nil) + } + actionSheet.addAction(cancel) + + present(actionSheet, animated: true, completion: nil) + } + + // MARK: - Private methods + fileprivate func adjustCropRect() { + imageCropRect = CGRect.zero + + guard var cropViewCropRect = cropView?.cropRect else { + return + } + cropViewCropRect.origin.x += cropRect.origin.x + cropViewCropRect.origin.y += cropRect.origin.y + + let minWidth = min(cropViewCropRect.maxX - cropViewCropRect.minX, cropRect.width) + let minHeight = min(cropViewCropRect.maxY - cropViewCropRect.minY, cropRect.height) + let size = CGSize(width: minWidth, height: minHeight) + cropViewCropRect.size = size + cropView?.cropRect = cropViewCropRect + } + + + +} diff --git a/Photo Editor/Photo Editor/EmojiCollectionViewCell.swift b/Photo Editor/Photo Editor/EmojiCollectionViewCell.swift old mode 100755 new mode 100644 diff --git a/Photo Editor/Photo Editor/EmojiCollectionViewCell.xib b/Photo Editor/Photo Editor/EmojiCollectionViewCell.xib old mode 100755 new mode 100644 index 4e98a0bd0..0ec548943 --- a/Photo Editor/Photo Editor/EmojiCollectionViewCell.xib +++ b/Photo Editor/Photo Editor/EmojiCollectionViewCell.xib @@ -1,16 +1,16 @@ - + - + - + @@ -18,8 +18,8 @@ diff --git a/Photo Editor/Photo Editor/EmojisCollectionViewDelegate.swift b/Photo Editor/Photo Editor/EmojisCollectionViewDelegate.swift old mode 100755 new mode 100644 index bf4bc9b69..1c461b879 --- a/Photo Editor/Photo Editor/EmojisCollectionViewDelegate.swift +++ b/Photo Editor/Photo Editor/EmojisCollectionViewDelegate.swift @@ -9,10 +9,11 @@ import UIKit class EmojisCollectionViewDelegate: NSObject, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { - + + var stickersViewControllerDelegate : StickersViewControllerDelegate? + let emojiRanges = [ 0x1F601...0x1F64F, // emoticons - // 0x1F600...0x1F636, // Additional emoticons 0x1F30D...0x1F567, // Other additional symbols 0x1F680...0x1F6C0, // Transport and map symbols 0x1F681...0x1F6C5 //Additional transport and map symbols @@ -31,18 +32,16 @@ class EmojisCollectionViewDelegate: NSObject, UICollectionViewDataSource, UIColl } } - var stickerDelegate : StickerDelegate? - - func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return emojis.count } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - let emojiLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 70, height: 70)) + let emojiLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 90, height: 90)) + emojiLabel.textAlignment = .center emojiLabel.text = emojis[indexPath.item] - emojiLabel.font = UIFont.systemFont(ofSize: 50) - stickerDelegate?.viewTapped(view: emojiLabel) + emojiLabel.font = UIFont.systemFont(ofSize: 70) + stickersViewControllerDelegate?.didSelectView(view: emojiLabel) } func numberOfSections(in collectionView: UICollectionView) -> Int { diff --git a/Photo Editor/Photo Editor/Eventtus-Icons.ttf b/Photo Editor/Photo Editor/Eventtus-Icons.ttf deleted file mode 100755 index 11b1a572d..000000000 Binary files a/Photo Editor/Photo Editor/Eventtus-Icons.ttf and /dev/null differ diff --git a/Photo Editor/Photo Editor/GradientView.swift b/Photo Editor/Photo Editor/GradientView.swift old mode 100755 new mode 100644 index 5c959b592..dc72ec784 --- a/Photo Editor/Photo Editor/GradientView.swift +++ b/Photo Editor/Photo Editor/GradientView.swift @@ -1,9 +1,9 @@ // // GradientView.swift -// EventtusWhiteLabel +// Photo Editor // // Created by Mohamed Hamed on 4/11/17. -// Copyright © 2017 Eventtus. All rights reserved. +// Copyright © 2017 Mohamed Hamed. All rights reserved. // import UIKit @@ -14,7 +14,6 @@ class GradientView: UIView { var gradientLayer = CAGradientLayer() - override func awakeFromNib() { super.awakeFromNib() if gradientFromtop == false { diff --git a/Photo Editor/Photo Editor/Info.plist b/Photo Editor/Photo Editor/Info.plist old mode 100755 new mode 100644 diff --git a/Photo Editor/Photo Editor/LaunchScreen.storyboard b/Photo Editor/Photo Editor/LaunchScreen.storyboard new file mode 100644 index 000000000..fdf3f97d1 --- /dev/null +++ b/Photo Editor/Photo Editor/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Photo Editor/Photo Editor/PhotoCropEditorBorder.png b/Photo Editor/Photo Editor/PhotoCropEditorBorder.png new file mode 100755 index 000000000..fd19d8e2d Binary files /dev/null and b/Photo Editor/Photo Editor/PhotoCropEditorBorder.png differ diff --git a/Photo Editor/Photo Editor/PhotoCropEditorBorder@2x.png b/Photo Editor/Photo Editor/PhotoCropEditorBorder@2x.png new file mode 100755 index 000000000..f56e4aec4 Binary files /dev/null and b/Photo Editor/Photo Editor/PhotoCropEditorBorder@2x.png differ diff --git a/Photo Editor/Photo Editor/PhotoCropEditorBorder@3x.png b/Photo Editor/Photo Editor/PhotoCropEditorBorder@3x.png new file mode 100755 index 000000000..193eb9b95 Binary files /dev/null and b/Photo Editor/Photo Editor/PhotoCropEditorBorder@3x.png differ diff --git a/Photo Editor/Photo Editor/PhotoEditor+Controls.swift b/Photo Editor/Photo Editor/PhotoEditor+Controls.swift new file mode 100644 index 000000000..e59e60262 --- /dev/null +++ b/Photo Editor/Photo Editor/PhotoEditor+Controls.swift @@ -0,0 +1,139 @@ +// +// PhotoEditor+Controls.swift +// Pods +// +// Created by Mohamed Hamed on 6/16/17. +// +// + +import Foundation +import UIKit + +// MARK: - Control +public enum control { + case crop + case sticker + case draw + case text + case save + case share + case clear +} + +extension PhotoEditorViewController { + + //MARK: Top Toolbar + + @IBAction func cancelButtonTapped(_ sender: Any) { + photoEditorDelegate?.canceledEditing() + self.dismiss(animated: true, completion: nil) + } + + @IBAction func cropButtonTapped(_ sender: UIButton) { + let controller = CropViewController() + controller.delegate = self + controller.image = image + let navController = UINavigationController(rootViewController: controller) + present(navController, animated: true, completion: nil) + } + + @IBAction func stickersButtonTapped(_ sender: Any) { + addStickersViewController() + } + + @IBAction func drawButtonTapped(_ sender: Any) { + isDrawing = true + canvasImageView.isUserInteractionEnabled = false + doneButton.isHidden = false + colorPickerView.isHidden = false + hideToolbar(hide: true) + } + + @IBAction func textButtonTapped(_ sender: Any) { + isTyping = true + let textView = UITextView(frame: CGRect(x: 0, y: canvasImageView.center.y, + width: UIScreen.main.bounds.width, height: 30)) + + textView.textAlignment = .center + textView.font = UIFont(name: "Helvetica", size: 30) + textView.textColor = textColor + textView.layer.shadowColor = UIColor.black.cgColor + textView.layer.shadowOffset = CGSize(width: 1.0, height: 0.0) + textView.layer.shadowOpacity = 0.2 + textView.layer.shadowRadius = 1.0 + textView.layer.backgroundColor = UIColor.clear.cgColor + textView.autocorrectionType = .no + textView.isScrollEnabled = false + textView.delegate = self + self.canvasImageView.addSubview(textView) + addGestures(view: textView) + textView.becomeFirstResponder() + } + + @IBAction func doneButtonTapped(_ sender: Any) { + view.endEditing(true) + doneButton.isHidden = true + colorPickerView.isHidden = true + canvasImageView.isUserInteractionEnabled = true + hideToolbar(hide: false) + isDrawing = false + } + + //MARK: Bottom Toolbar + + @IBAction func saveButtonTapped(_ sender: AnyObject) { + UIImageWriteToSavedPhotosAlbum(canvasView.toImage(),self, #selector(PhotoEditorViewController.image(_:withPotentialError:contextInfo:)), nil) + } + + @IBAction func shareButtonTapped(_ sender: UIButton) { + let activity = UIActivityViewController(activityItems: [canvasView.toImage()], applicationActivities: nil) + present(activity, animated: true, completion: nil) + + } + + @IBAction func clearButtonTapped(_ sender: AnyObject) { + //clear drawing + canvasImageView.image = nil + //clear stickers and textviews + for subview in canvasImageView.subviews { + subview.removeFromSuperview() + } + } + + @IBAction func continueButtonPressed(_ sender: Any) { + let img = self.canvasView.toImage() + photoEditorDelegate?.doneEditing(image: img) + self.dismiss(animated: true, completion: nil) + } + + //MAKR: helper methods + + func image(_ image: UIImage, withPotentialError error: NSErrorPointer, contextInfo: UnsafeRawPointer) { + let alert = UIAlertController(title: "Image Saved", message: "Image successfully saved to Photos library", preferredStyle: UIAlertControllerStyle.alert) + alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) + self.present(alert, animated: true, completion: nil) + } + + func hideControls() { + for control in hiddenControls { + switch control { + + case .clear: + clearButton.isHidden = true + case .crop: + cropButton.isHidden = true + case .draw: + drawButton.isHidden = true + case .save: + saveButton.isHidden = true + case .share: + shareButton.isHidden = true + case .sticker: + stickerButton.isHidden = true + case .text: + stickerButton.isHidden = true + } + } + } + +} diff --git a/Photo Editor/Photo Editor/PhotoEditor+Crop.swift b/Photo Editor/Photo Editor/PhotoEditor+Crop.swift new file mode 100644 index 000000000..dc3289b40 --- /dev/null +++ b/Photo Editor/Photo Editor/PhotoEditor+Crop.swift @@ -0,0 +1,24 @@ +// +// PhotoEditor+Crop.swift +// Pods +// +// Created by Mohamed Hamed on 6/16/17. +// +// + +import Foundation +import UIKit + +// MARK: - CropView +extension PhotoEditorViewController: CropViewControllerDelegate { + + public func cropViewController(_ controller: CropViewController, didFinishCroppingImage image: UIImage, transform: CGAffineTransform, cropRect: CGRect) { + controller.dismiss(animated: true, completion: nil) + self.setImageView(image: image) + } + + public func cropViewControllerDidCancel(_ controller: CropViewController) { + controller.dismiss(animated: true, completion: nil) + } + +} diff --git a/Photo Editor/Photo Editor/Pencil.swift b/Photo Editor/Photo Editor/PhotoEditor+Drawing.swift old mode 100755 new mode 100644 similarity index 68% rename from Photo Editor/Photo Editor/Pencil.swift rename to Photo Editor/Photo Editor/PhotoEditor+Drawing.swift index abe82cc5e..49b42ed6f --- a/Photo Editor/Photo Editor/Pencil.swift +++ b/Photo Editor/Photo Editor/PhotoEditor+Drawing.swift @@ -1,31 +1,29 @@ // -// Pencil.swift +// PhotoEditor+Drawing.swift // Photo Editor // -// Created by Mohamed Hamed on 4/26/17. -// Copyright © 2017 Mohamed Hamed. All rights reserved. +// Created by Mohamed Hamed on 6/16/17. +// // import UIKit extension PhotoEditorViewController { - //MARK: Pencil override public func touchesBegan(_ touches: Set, with event: UIEvent?){ if isDrawing { - // self.view.bringSubview(toFront: tempImageView) swiped = false if let touch = touches.first { - lastPoint = touch.location(in: self.tempImageView) + lastPoint = touch.location(in: self.canvasImageView) } } - //Hide BottomSheet if clicked outside it - else if bottomSheetIsVisible == true { + //Hide stickersVC if clicked outside it + else if stickersVCIsVisible == true { if let touch = touches.first { let location = touch.location(in: self.view) - if !bottomSheetVC.view.frame.contains(location) { - removeBottomSheetView() + if !stickersViewController.view.frame.contains(location) { + removeStickersView() } } } @@ -38,7 +36,7 @@ extension PhotoEditorViewController { // 6 swiped = true if let touch = touches.first { - let currentPoint = touch.location(in: tempImageView) + let currentPoint = touch.location(in: canvasImageView) drawLineFrom(lastPoint, toPoint: currentPoint) // 7 @@ -60,9 +58,9 @@ extension PhotoEditorViewController { func drawLineFrom(_ fromPoint: CGPoint, toPoint: CGPoint) { // 1 - UIGraphicsBeginImageContext(imageView.frame.size) + UIGraphicsBeginImageContext(canvasImageView.frame.size) if let context = UIGraphicsGetCurrentContext() { - tempImageView.image?.draw(in: CGRect(x: 0, y: 0, width: imageView.frame.size.width, height: imageView.frame.size.height)) + canvasImageView.image?.draw(in: CGRect(x: 0, y: 0, width: canvasImageView.frame.size.width, height: canvasImageView.frame.size.height)) // 2 context.move(to: CGPoint(x: fromPoint.x, y: fromPoint.y)) context.addLine(to: CGPoint(x: toPoint.x, y: toPoint.y)) @@ -74,8 +72,7 @@ extension PhotoEditorViewController { // 4 context.strokePath() // 5 - tempImageView.image = UIGraphicsGetImageFromCurrentImageContext() - tempImageView.alpha = opacity + canvasImageView.image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() } } diff --git a/Photo Editor/Photo Editor/PhotoEditor+Font.swift b/Photo Editor/Photo Editor/PhotoEditor+Font.swift new file mode 100644 index 000000000..5f771f519 --- /dev/null +++ b/Photo Editor/Photo Editor/PhotoEditor+Font.swift @@ -0,0 +1,28 @@ +// +// PhotoEditor+Font.swift +// +// +// Created by Mohamed Hamed on 6/16/17. +// +// + +import Foundation +import UIKit + +extension PhotoEditorViewController { + + //Resources don't load in main bundle we have to register the font + func registerFont(){ + let bundle = Bundle(for: PhotoEditorViewController.self) + let url = bundle.url(forResource: "icomoon", withExtension: "ttf") + + guard let fontDataProvider = CGDataProvider(url: url! as CFURL) else { + return + } + let font = CGFont(fontDataProvider) + var error: Unmanaged? + guard CTFontManagerRegisterGraphicsFont(font, &error) else { + return + } + } +} diff --git a/Photo Editor/Photo Editor/ViewGestures.swift b/Photo Editor/Photo Editor/PhotoEditor+Gestures.swift old mode 100755 new mode 100644 similarity index 70% rename from Photo Editor/Photo Editor/ViewGestures.swift rename to Photo Editor/Photo Editor/PhotoEditor+Gestures.swift index a383c6469..d65b28872 --- a/Photo Editor/Photo Editor/ViewGestures.swift +++ b/Photo Editor/Photo Editor/PhotoEditor+Gestures.swift @@ -1,22 +1,28 @@ // -// ViewGestures.swift +// PhotoEditor+Gestures.swift // Photo Editor // -// Created by Mohamed Hamed on 4/24/17. -// Copyright © 2017 Mohamed Hamed. All rights reserved. +// Created by Mohamed Hamed on 6/16/17. // +// + +import Foundation + import UIKit extension PhotoEditorViewController : UIGestureRecognizerDelegate { - //Translation is moving object + /** + UIPanGestureRecognizer - Moving Objects + Selecting transparent parts of the imageview won't move the object + */ func panGesture(_ recognizer: UIPanGestureRecognizer) { if let view = recognizer.view { if view is UIImageView { //Tap only on visible parts on the image if recognizer.state == .began { - for imageView in subImageViews(view: tempImageView) { + for imageView in subImageViews(view: canvasImageView) { let location = recognizer.location(in: imageView) let alpha = imageView.alphaAtPoint(location) if alpha > 0 { @@ -34,18 +40,29 @@ extension PhotoEditorViewController : UIGestureRecognizerDelegate { } } + /** + UIPinchGestureRecognizer - Pinching Objects + If it's a UITextView will make the font bigger so it doen't look pixlated + */ func pinchGesture(_ recognizer: UIPinchGestureRecognizer) { if let view = recognizer.view { if view is UITextView { let textView = view as! UITextView - let font = UIFont(name: textView.font!.fontName, size: textView.font!.pointSize * recognizer.scale) - textView.font = font - let sizeToFit = textView.sizeThatFits(CGSize(width: UIScreen.main.bounds.size.width, - height:CGFloat.greatestFiniteMagnitude)) + if textView.font!.pointSize * recognizer.scale < 90 { + let font = UIFont(name: textView.font!.fontName, size: textView.font!.pointSize * recognizer.scale) + textView.font = font + let sizeToFit = textView.sizeThatFits(CGSize(width: UIScreen.main.bounds.size.width, + height:CGFloat.greatestFiniteMagnitude)) + textView.bounds.size = CGSize(width: textView.intrinsicContentSize.width, + height: sizeToFit.height) + } else { + let sizeToFit = textView.sizeThatFits(CGSize(width: UIScreen.main.bounds.size.width, + height:CGFloat.greatestFiniteMagnitude)) + textView.bounds.size = CGSize(width: textView.intrinsicContentSize.width, + height: sizeToFit.height) + } - textView.bounds.size = CGSize(width: textView.intrinsicContentSize.width, - height: sizeToFit.height) textView.setNeedsDisplay() } else { @@ -55,6 +72,9 @@ extension PhotoEditorViewController : UIGestureRecognizerDelegate { } } + /** + UIRotationGestureRecognizer - Rotating Objects + */ func rotationGesture(_ recognizer: UIRotationGestureRecognizer) { if let view = recognizer.view { view.transform = view.transform.rotated(by: recognizer.rotation) @@ -62,11 +82,16 @@ extension PhotoEditorViewController : UIGestureRecognizerDelegate { } } + /** + UITapGestureRecognizer - Taping on Objects + Will make scale scale Effect + Selecting transparent parts of the imageview won't move the object + */ func tapGesture(_ recognizer: UITapGestureRecognizer) { if let view = recognizer.view { if view is UIImageView { //Tap only on visible parts on the image - for imageView in subImageViews(view: tempImageView) { + for imageView in subImageViews(view: canvasImageView) { let location = recognizer.location(in: imageView) let alpha = imageView.alphaAtPoint(location) if alpha > 0 { @@ -80,6 +105,9 @@ extension PhotoEditorViewController : UIGestureRecognizerDelegate { } } + /* + Support Multiple Gesture at the same time + */ public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true } @@ -94,8 +122,8 @@ extension PhotoEditorViewController : UIGestureRecognizerDelegate { func screenEdgeSwiped(_ recognizer: UIScreenEdgePanGestureRecognizer) { if recognizer.state == .recognized { - if !bottomSheetIsVisible { - addBottomSheetView() + if !stickersVCIsVisible { + addStickersViewController() } } } @@ -105,6 +133,9 @@ extension PhotoEditorViewController : UIGestureRecognizerDelegate { return true } + /** + Scale Effect + */ func scaleEffect(view: UIView) { view.superview?.bringSubview(toFront: view) @@ -124,6 +155,12 @@ extension PhotoEditorViewController : UIGestureRecognizerDelegate { }) } + /** + Moving Objects + delete the view if it's inside the delete view + Snap the view back if it's out of the canvas + */ + func moveView(view: UIView, recognizer: UIPanGestureRecognizer) { hideToolbar(hide: true) @@ -131,14 +168,11 @@ extension PhotoEditorViewController : UIGestureRecognizerDelegate { view.superview?.bringSubview(toFront: view) let pointToSuperView = recognizer.location(in: self.view) - // - view.center = CGPoint(x: view.center.x + recognizer.translation(in: tempImageView).x, - y: view.center.y + recognizer.translation(in: tempImageView).y) - - // let point = recognizer.location(in: tempImageView) - // view.center = point + + view.center = CGPoint(x: view.center.x + recognizer.translation(in: canvasImageView).x, + y: view.center.y + recognizer.translation(in: canvasImageView).y) - recognizer.setTranslation(CGPoint.zero, in: tempImageView) + recognizer.setTranslation(CGPoint.zero, in: canvasImageView) if let previousPoint = lastPanPoint { //View is going into deleteView @@ -149,7 +183,7 @@ extension PhotoEditorViewController : UIGestureRecognizerDelegate { } UIView.animate(withDuration: 0.3, animations: { view.transform = view.transform.scaledBy(x: 0.25, y: 0.25) - view.center = recognizer.location(in: self.tempImageView) + view.center = recognizer.location(in: self.canvasImageView) }) } //View is going out of deleteView @@ -157,7 +191,7 @@ extension PhotoEditorViewController : UIGestureRecognizerDelegate { //Scale to original Size UIView.animate(withDuration: 0.3, animations: { view.transform = view.transform.scaledBy(x: 4, y: 4) - view.center = recognizer.location(in: self.tempImageView) + view.center = recognizer.location(in: self.canvasImageView) }) } } @@ -176,9 +210,9 @@ extension PhotoEditorViewController : UIGestureRecognizerDelegate { let generator = UINotificationFeedbackGenerator() generator.notificationOccurred(.success) } - } else if !tempImageView.bounds.contains(view.center) { //Snap the view back to tempimageview + } else if !canvasImageView.bounds.contains(view.center) { //Snap the view back to canvasImageView UIView.animate(withDuration: 0.3, animations: { - view.center = self.tempImageView.center + view.center = self.canvasImageView.center }) } diff --git a/Photo Editor/Photo Editor/PhotoEditor+Keyboard.swift b/Photo Editor/Photo Editor/PhotoEditor+Keyboard.swift new file mode 100644 index 000000000..b8bcb249a --- /dev/null +++ b/Photo Editor/Photo Editor/PhotoEditor+Keyboard.swift @@ -0,0 +1,48 @@ +// +// PhotoEditor+Keyboard.swift +// Pods +// +// Created by Mohamed Hamed on 6/16/17. +// +// + +import Foundation +import UIKit + +extension PhotoEditorViewController { + + func keyboardDidShow(notification: NSNotification) { + if isTyping { + doneButton.isHidden = false + colorPickerView.isHidden = false + hideToolbar(hide: true) + } + } + + func keyboardWillHide(notification: NSNotification) { + isTyping = false + doneButton.isHidden = true + hideToolbar(hide: false) + } + + func keyboardWillChangeFrame(_ notification: NSNotification) { + if let userInfo = notification.userInfo { + let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue + let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0 + let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber + let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue + let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw) + if (endFrame?.origin.y)! >= UIScreen.main.bounds.size.height { + self.colorPickerViewBottomConstraint?.constant = 0.0 + } else { + self.colorPickerViewBottomConstraint?.constant = endFrame?.size.height ?? 0.0 + } + UIView.animate(withDuration: duration, + delay: TimeInterval(0), + options: animationCurve, + animations: { self.view.layoutIfNeeded() }, + completion: nil) + } + } + +} diff --git a/Photo Editor/Photo Editor/PhotoEditor+StickersViewController.swift b/Photo Editor/Photo Editor/PhotoEditor+StickersViewController.swift new file mode 100644 index 000000000..36d11d7a8 --- /dev/null +++ b/Photo Editor/Photo Editor/PhotoEditor+StickersViewController.swift @@ -0,0 +1,104 @@ +// +// PhotoEditor+StickersViewController.swift +// Pods +// +// Created by Mohamed Hamed on 6/16/17. +// +// + +import Foundation +import UIKit + +extension PhotoEditorViewController { + + func addStickersViewController() { + stickersVCIsVisible = true + hideToolbar(hide: true) + self.canvasImageView.isUserInteractionEnabled = false + stickersViewController.stickersViewControllerDelegate = self + + for image in self.stickers { + stickersViewController.stickers.append(image) + } + self.addChildViewController(stickersViewController) + self.view.addSubview(stickersViewController.view) + stickersViewController.didMove(toParentViewController: self) + let height = view.frame.height + let width = view.frame.width + stickersViewController.view.frame = CGRect(x: 0, y: self.view.frame.maxY , width: width, height: height) + } + + func removeStickersView() { + stickersVCIsVisible = false + self.canvasImageView.isUserInteractionEnabled = true + UIView.animate(withDuration: 0.3, + delay: 0, + options: UIViewAnimationOptions.curveEaseIn, + animations: { () -> Void in + var frame = self.stickersViewController.view.frame + frame.origin.y = UIScreen.main.bounds.maxY + self.stickersViewController.view.frame = frame + + }, completion: { (finished) -> Void in + self.stickersViewController.view.removeFromSuperview() + self.stickersViewController.removeFromParentViewController() + self.hideToolbar(hide: false) + }) + } +} + +extension PhotoEditorViewController: StickersViewControllerDelegate { + + func didSelectView(view: UIView) { + self.removeStickersView() + + view.center = canvasImageView.center + self.canvasImageView.addSubview(view) + //Gestures + addGestures(view: view) + } + + func didSelectImage(image: UIImage) { + self.removeStickersView() + + let imageView = UIImageView(image: image) + imageView.contentMode = .scaleAspectFit + imageView.frame.size = CGSize(width: 150, height: 150) + imageView.center = canvasImageView.center + + self.canvasImageView.addSubview(imageView) + //Gestures + addGestures(view: imageView) + } + + func stickersViewDidDisappear() { + stickersVCIsVisible = false + hideToolbar(hide: false) + } + + func addGestures(view: UIView) { + //Gestures + view.isUserInteractionEnabled = true + + let panGesture = UIPanGestureRecognizer(target: self, + action: #selector(PhotoEditorViewController.panGesture)) + panGesture.minimumNumberOfTouches = 1 + panGesture.maximumNumberOfTouches = 1 + panGesture.delegate = self + view.addGestureRecognizer(panGesture) + + let pinchGesture = UIPinchGestureRecognizer(target: self, + action: #selector(PhotoEditorViewController.pinchGesture)) + pinchGesture.delegate = self + view.addGestureRecognizer(pinchGesture) + + let rotationGestureRecognizer = UIRotationGestureRecognizer(target: self, + action:#selector(PhotoEditorViewController.rotationGesture) ) + rotationGestureRecognizer.delegate = self + view.addGestureRecognizer(rotationGestureRecognizer) + + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(PhotoEditorViewController.tapGesture)) + view.addGestureRecognizer(tapGesture) + + } +} diff --git a/Photo Editor/Photo Editor/PhotoEditor+UITextView.swift b/Photo Editor/Photo Editor/PhotoEditor+UITextView.swift new file mode 100644 index 000000000..ed273802b --- /dev/null +++ b/Photo Editor/Photo Editor/PhotoEditor+UITextView.swift @@ -0,0 +1,53 @@ +// +// PhotoEditor+UITextView.swift +// Pods +// +// Created by Mohamed Hamed on 6/16/17. +// +// + +import Foundation +import UIKit + +extension PhotoEditorViewController: UITextViewDelegate { + + public func textViewDidChange(_ textView: UITextView) { + let rotation = atan2(textView.transform.b, textView.transform.a) + if rotation == 0 { + let oldFrame = textView.frame + let sizeToFit = textView.sizeThatFits(CGSize(width: oldFrame.width, height:CGFloat.greatestFiniteMagnitude)) + textView.frame.size = CGSize(width: oldFrame.width, height: sizeToFit.height) + } + } + public func textViewDidBeginEditing(_ textView: UITextView) { + isTyping = true + lastTextViewTransform = textView.transform + lastTextViewTransCenter = textView.center + lastTextViewFont = textView.font! + activeTextView = textView + textView.superview?.bringSubview(toFront: textView) + textView.font = UIFont(name: "Helvetica", size: 30) + UIView.animate(withDuration: 0.3, + animations: { + textView.transform = CGAffineTransform.identity + textView.center = CGPoint(x: UIScreen.main.bounds.width / 2, + y: UIScreen.main.bounds.height / 5) + }, completion: nil) + + } + + public func textViewDidEndEditing(_ textView: UITextView) { + guard lastTextViewTransform != nil && lastTextViewTransCenter != nil && lastTextViewFont != nil + else { + return + } + activeTextView = nil + textView.font = self.lastTextViewFont! + UIView.animate(withDuration: 0.3, + animations: { + textView.transform = self.lastTextViewTransform! + textView.center = self.lastTextViewTransCenter! + }, completion: nil) + } + +} diff --git a/Photo Editor/Photo Editor/PhotoEditorViewController.swift b/Photo Editor/Photo Editor/PhotoEditorViewController.swift old mode 100755 new mode 100644 index bfb874f0a..3c66f6526 --- a/Photo Editor/Photo Editor/PhotoEditorViewController.swift +++ b/Photo Editor/Photo Editor/PhotoEditorViewController.swift @@ -8,54 +8,70 @@ import UIKit -public protocol PhotoEditorDelegate { - func imageEdited(image: UIImage) - func editorCanceled() -} - public final class PhotoEditorViewController: UIViewController { + /** holding the 2 imageViews original image and drawing & stickers */ @IBOutlet weak var canvasView: UIView! //To hold the image @IBOutlet var imageView: UIImageView! @IBOutlet weak var imageViewHeightConstraint: NSLayoutConstraint! - //To hold the drawings and stickers - @IBOutlet weak var tempImageView: UIImageView! + @IBOutlet weak var canvasImageView: UIImageView! + @IBOutlet weak var topToolbar: UIView! - @IBOutlet weak var topGradient: UIView! @IBOutlet weak var bottomToolbar: UIView! + + @IBOutlet weak var topGradient: UIView! @IBOutlet weak var bottomGradient: UIView! + @IBOutlet weak var doneButton: UIButton! @IBOutlet weak var deleteView: UIView! @IBOutlet weak var colorsCollectionView: UICollectionView! - @IBOutlet weak var colorPickerView: UIView! @IBOutlet weak var colorPickerViewBottomConstraint: NSLayoutConstraint! - var colorsCollectionViewDelegate: ColorsCollectionViewDelegate! + //Controls + @IBOutlet weak var cropButton: UIButton! + @IBOutlet weak var stickerButton: UIButton! + @IBOutlet weak var drawButton: UIButton! + @IBOutlet weak var textButton: UIButton! + @IBOutlet weak var saveButton: UIButton! + @IBOutlet weak var shareButton: UIButton! + @IBOutlet weak var clearButton: UIButton! public var image: UIImage? + /** + Array of Stickers -UIImage- that the user will choose from + */ public var stickers : [UIImage] = [] + /** + Array of Colors that will show while drawing or typing + */ + public var colors : [UIColor] = [] public var photoEditorDelegate: PhotoEditorDelegate? - // - var bottomSheetIsVisible = false + var colorsCollectionViewDelegate: ColorsCollectionViewDelegate! + + // list of controls to be hidden + public var hiddenControls : [control] = [] + + var stickersVCIsVisible = false var drawColor: UIColor = UIColor.black var textColor: UIColor = UIColor.white var isDrawing: Bool = false var lastPoint: CGPoint! var swiped = false - var opacity: CGFloat = 1.0 var lastPanPoint: CGPoint? var lastTextViewTransform: CGAffineTransform? var lastTextViewTransCenter: CGPoint? var lastTextViewFont:UIFont? var activeTextView: UITextView? - var imageRotated: Bool = false var imageViewToPan: UIImageView? - // + var isTyping: Bool = false + + var stickersViewController: StickersViewController! + //Register Custom font before we load XIB public override func loadView() { registerFont() @@ -64,10 +80,7 @@ public final class PhotoEditorViewController: UIViewController { override public func viewDidLoad() { super.viewDidLoad() - imageView.image = image! - - let size = image!.sutibleSize(widthLimit: UIScreen.main.bounds.width) - imageViewHeightConstraint.constant = (size?.height)! + self.setImageView(image: image!) deleteView.layer.cornerRadius = deleteView.bounds.height / 2 deleteView.layer.borderWidth = 2.0 @@ -79,20 +92,20 @@ public final class PhotoEditorViewController: UIViewController { edgePan.delegate = self self.view.addGestureRecognizer(edgePan) - NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), - name: .UIKeyboardWillShow, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow), + name: .UIKeyboardDidShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: .UIKeyboardWillHide, object: nil) NotificationCenter.default.addObserver(self,selector: #selector(keyboardWillChangeFrame(_:)), name: .UIKeyboardWillChangeFrame, object: nil) - configureCollectionView() - bottomSheetVC = BottomSheetViewController(nibName: "BottomSheetViewController", bundle: Bundle(for: BottomSheetViewController.self)) + configureCollectionView() + stickersViewController = StickersViewController(nibName: "StickersViewController", bundle: Bundle(for: StickersViewController.self)) + hideControls() } func configureCollectionView() { - let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() layout.itemSize = CGSize(width: 30, height: 30) layout.scrollDirection = .horizontal @@ -101,167 +114,21 @@ public final class PhotoEditorViewController: UIViewController { colorsCollectionView.collectionViewLayout = layout colorsCollectionViewDelegate = ColorsCollectionViewDelegate() colorsCollectionViewDelegate.colorDelegate = self + if !colors.isEmpty { + colorsCollectionViewDelegate.colors = colors + } colorsCollectionView.delegate = colorsCollectionViewDelegate colorsCollectionView.dataSource = colorsCollectionViewDelegate colorsCollectionView.register( UINib(nibName: "ColorCollectionViewCell", bundle: Bundle(for: ColorCollectionViewCell.self)), forCellWithReuseIdentifier: "ColorCollectionViewCell") - - } - - @IBAction func saveButtonTapped(_ sender: AnyObject) { - - UIImageWriteToSavedPhotosAlbum(canvasView.toImage(),self, #selector(PhotoEditorViewController.image(_:withPotentialError:contextInfo:)), nil) - - ///To Share - //let activity = UIActivityViewController(activityItems: [self.imageView.toImage()], applicationActivities: nil) - //present(activity, animated: true, completion: nil) - } - @IBAction func clearButtonTapped(_ sender: AnyObject) { - //clear drawing + func setImageView(image: UIImage) { imageView.image = image - tempImageView.image = nil - //clear stickers and textviews - for subview in tempImageView.subviews { - subview.removeFromSuperview() - } - } - - @IBAction func doneButtonTapped(_ sender: Any) { - view.endEditing(true) - doneButton.isHidden = true - colorPickerView.isHidden = true - tempImageView.isUserInteractionEnabled = true - hideToolbar(hide: false) - isDrawing = false - } - - func keyboardWillShow(notification: NSNotification) { - doneButton.isHidden = false - colorPickerView.isHidden = false - hideToolbar(hide: true) - } - - func keyboardWillHide(notification: NSNotification) { - doneButton.isHidden = true - hideToolbar(hide: false) - } - - func keyboardWillChangeFrame(_ notification: NSNotification) { - if let userInfo = notification.userInfo { - let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue - let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0 - let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber - let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue - let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw) - if (endFrame?.origin.y)! >= UIScreen.main.bounds.size.height { - self.colorPickerViewBottomConstraint?.constant = 0.0 - } else { - self.colorPickerViewBottomConstraint?.constant = endFrame?.size.height ?? 0.0 - } - UIView.animate(withDuration: duration, - delay: TimeInterval(0), - options: animationCurve, - animations: { self.view.layoutIfNeeded() }, - completion: nil) - } - } - - func image(_ image: UIImage, withPotentialError error: NSErrorPointer, contextInfo: UnsafeRawPointer) { - let alert = UIAlertController(title: "Image Saved", message: "Image successfully saved to Photos library", preferredStyle: UIAlertControllerStyle.alert) - alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) - self.present(alert, animated: true, completion: nil) - } - - @IBAction func continueButtonPressed(_ sender: Any) { - - var img = self.canvasView.toImage() - if imageRotated { - img = img.rotateImage(orientation: .left) - } - photoEditorDelegate?.imageEdited(image: img) - self.dismiss(animated: true, completion: nil) - } - - @IBAction func cancelButtonTapped(_ sender: Any) { - photoEditorDelegate?.editorCanceled() - self.dismiss(animated: true, completion: nil) - } - - @IBAction func stickersButtonTapped(_ sender: Any) { - addBottomSheetView() - } - - @IBAction func textButtonTapped(_ sender: Any) { - - let textView = UITextView(frame: CGRect(x: 0, y: tempImageView.center.y, - width: UIScreen.main.bounds.width, height: 30)) - - //Text Attributes - textView.textAlignment = .center - textView.font = UIFont(name: "Helvetica", size: 30) - textView.textColor = textColor - textView.layer.shadowColor = UIColor.black.cgColor - textView.layer.shadowOffset = CGSize(width: 1.0, height: 0.0) - textView.layer.shadowOpacity = 0.2 - textView.layer.shadowRadius = 1.0 - textView.layer.backgroundColor = UIColor.clear.cgColor - // - textView.autocorrectionType = .no - textView.isScrollEnabled = false - textView.delegate = self - self.tempImageView.addSubview(textView) - addGestures(view: textView) - textView.becomeFirstResponder() - } - - @IBAction func pencilButtonTapped(_ sender: Any) { - isDrawing = true - tempImageView.isUserInteractionEnabled = false - doneButton.isHidden = false - colorPickerView.isHidden = false - hideToolbar(hide: true) - } - - - var bottomSheetVC: BottomSheetViewController! - - func addBottomSheetView() { - bottomSheetIsVisible = true - hideToolbar(hide: true) - self.tempImageView.isUserInteractionEnabled = false - bottomSheetVC.stickerDelegate = self - - for image in self.stickers { - bottomSheetVC.stickers.append(image) - } - self.addChildViewController(bottomSheetVC) - self.view.addSubview(bottomSheetVC.view) - bottomSheetVC.didMove(toParentViewController: self) - let height = view.frame.height - let width = view.frame.width - bottomSheetVC.view.frame = CGRect(x: 0, y: self.view.frame.maxY , width: width, height: height) - } - - func removeBottomSheetView() { - bottomSheetIsVisible = false - self.tempImageView.isUserInteractionEnabled = true - UIView.animate(withDuration: 0.3, - delay: 0, - options: UIViewAnimationOptions.curveEaseIn, - animations: { () -> Void in - var frame = self.bottomSheetVC.view.frame - frame.origin.y = UIScreen.main.bounds.maxY - self.bottomSheetVC.view.frame = frame - - }, completion: { (finished) -> Void in - self.bottomSheetVC.view.removeFromSuperview() - self.bottomSheetVC.removeFromParentViewController() - self.hideToolbar(hide: false) - }) + let size = image.suitableSize(widthLimit: UIScreen.main.bounds.width) + imageViewHeightConstraint.constant = (size?.height)! } func hideToolbar(hide: Bool) { @@ -270,11 +137,10 @@ public final class PhotoEditorViewController: UIViewController { bottomToolbar.isHidden = hide bottomGradient.isHidden = hide } - } extension PhotoEditorViewController: ColorDelegate { - func chosedColor(color: UIColor) { + func didSelectColor(color: UIColor) { if isDrawing { self.drawColor = color } else if activeTextView != nil { @@ -284,116 +150,7 @@ extension PhotoEditorViewController: ColorDelegate { } } -extension PhotoEditorViewController: UITextViewDelegate { - public func textViewDidChange(_ textView: UITextView) { - let rotation = atan2(textView.transform.b, textView.transform.a) - if rotation == 0 { - let oldFrame = textView.frame - let sizeToFit = textView.sizeThatFits(CGSize(width: oldFrame.width, height:CGFloat.greatestFiniteMagnitude)) - textView.frame.size = CGSize(width: oldFrame.width, height: sizeToFit.height) - } - } - public func textViewDidBeginEditing(_ textView: UITextView) { - lastTextViewTransform = textView.transform - lastTextViewTransCenter = textView.center - lastTextViewFont = textView.font! - activeTextView = textView - textView.superview?.bringSubview(toFront: textView) - textView.font = UIFont(name: "Helvetica", size: 30) - UIView.animate(withDuration: 0.3, - animations: { - textView.transform = CGAffineTransform.identity - textView.center = CGPoint(x: UIScreen.main.bounds.width / 2, y: 100) - }, completion: nil) - - } - - public func textViewDidEndEditing(_ textView: UITextView) { - guard lastTextViewTransform != nil && lastTextViewTransCenter != nil && lastTextViewFont != nil - else { - return - } - activeTextView = nil - textView.font = self.lastTextViewFont! - UIView.animate(withDuration: 0.3, - animations: { - textView.transform = self.lastTextViewTransform! - textView.center = self.lastTextViewTransCenter! - }, completion: nil) - } - -} -extension PhotoEditorViewController: StickerDelegate { - - func viewTapped(view: UIView) { - self.removeBottomSheetView() - view.center = tempImageView.center - - self.tempImageView.addSubview(view) - //Gestures - addGestures(view: view) - } - func imageTapped(image: UIImage) { - self.removeBottomSheetView() - - let imageView = UIImageView(image: image) - imageView.contentMode = .scaleAspectFit - imageView.frame.size = CGSize(width: 150, height: 150) - imageView.center = tempImageView.center - - self.tempImageView.addSubview(imageView) - //Gestures - addGestures(view: imageView) - } - - func bottomSheetDidDisappear() { - bottomSheetIsVisible = false - hideToolbar(hide: false) - } - - func addGestures(view: UIView) { - //Gestures - view.isUserInteractionEnabled = true - - let panGesture = UIPanGestureRecognizer(target: self, - action: #selector(PhotoEditorViewController.panGesture)) - panGesture.minimumNumberOfTouches = 1 - panGesture.maximumNumberOfTouches = 1 - panGesture.delegate = self - view.addGestureRecognizer(panGesture) - - let pinchGesture = UIPinchGestureRecognizer(target: self, - action: #selector(PhotoEditorViewController.pinchGesture)) - pinchGesture.delegate = self - view.addGestureRecognizer(pinchGesture) - - let rotationGestureRecognizer = UIRotationGestureRecognizer(target: self, - action:#selector(PhotoEditorViewController.rotationGesture) ) - rotationGestureRecognizer.delegate = self - view.addGestureRecognizer(rotationGestureRecognizer) - - let tapGesture = UITapGestureRecognizer(target: self, action: #selector(PhotoEditorViewController.tapGesture)) - view.addGestureRecognizer(tapGesture) - - } -} -extension PhotoEditorViewController { - - //Resources don't load in main bundle we have to register the font - func registerFont(){ - let bundle = Bundle(for: PhotoEditorViewController.self) - let url = bundle.url(forResource: "Eventtus-Icons", withExtension: "ttf") - - guard let fontDataProvider = CGDataProvider(url: url! as CFURL) else { - return - } - let font = CGFont(fontDataProvider) - var error: Unmanaged? - guard CTFontManagerRegisterGraphicsFont(font, &error) else { - return - } - } -} + diff --git a/Photo Editor/Photo Editor/PhotoEditorViewController.xib b/Photo Editor/Photo Editor/PhotoEditorViewController.xib new file mode 100644 index 000000000..9c128c53f --- /dev/null +++ b/Photo Editor/Photo Editor/PhotoEditorViewController.xib @@ -0,0 +1,324 @@ + + + + + + + + + + + + icomoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Photo Editor/Photo Editor/Protocols.swift b/Photo Editor/Photo Editor/Protocols.swift new file mode 100644 index 000000000..119ef6601 --- /dev/null +++ b/Photo Editor/Photo Editor/Protocols.swift @@ -0,0 +1,54 @@ +// +// Protocols.swift +// Photo Editor +// +// Created by Mohamed Hamed on 6/15/17. +// +// + +import Foundation +import UIKit +/** + - didSelectView + - didSelectImage + - stickersViewDidDisappear + */ + +public protocol PhotoEditorDelegate { + /** + - Parameter image: edited Image + */ + func doneEditing(image: UIImage) + /** + StickersViewController did Disappear + */ + func canceledEditing() +} + + +/** + - didSelectView + - didSelectImage + - stickersViewDidDisappear + */ +protocol StickersViewControllerDelegate { + /** + - Parameter view: selected view from StickersViewController + */ + func didSelectView(view: UIView) + /** + - Parameter image: selected Image from StickersViewController + */ + func didSelectImage(image: UIImage) + /** + StickersViewController did Disappear + */ + func stickersViewDidDisappear() +} + +/** + - didSelectColor + */ +protocol ColorDelegate { + func didSelectColor(color: UIColor) +} diff --git a/Photo Editor/Photo Editor/ResizeControl.swift b/Photo Editor/Photo Editor/ResizeControl.swift new file mode 100755 index 000000000..7749776cf --- /dev/null +++ b/Photo Editor/Photo Editor/ResizeControl.swift @@ -0,0 +1,61 @@ +// +// ResizeControl.swift +// CropViewController +// +// Created by Guilherme Moura on 2/26/16. +// Copyright © 2016 Reefactor, Inc. All rights reserved. +// Credit https://github.com/sprint84/PhotoCropEditor + +import UIKit + +protocol ResizeControlDelegate: class { + func resizeControlDidBeginResizing(_ control: ResizeControl) + func resizeControlDidResize(_ control: ResizeControl) + func resizeControlDidEndResizing(_ control: ResizeControl) +} + +class ResizeControl: UIView { + weak var delegate: ResizeControlDelegate? + var translation = CGPoint.zero + var enabled = true + fileprivate var startPoint = CGPoint.zero + + override init(frame: CGRect) { + super.init(frame: CGRect(x: frame.origin.x, y: frame.origin.y, width: 44.0, height: 44.0)) + initialize() + } + + required init?(coder aDecoder: NSCoder) { + super.init(frame: CGRect(x: 0, y: 0, width: 44.0, height: 44.0)) + initialize() + } + + fileprivate func initialize() { + backgroundColor = UIColor.clear + isExclusiveTouch = true + + let gestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(ResizeControl.handlePan(_:))) + addGestureRecognizer(gestureRecognizer) + } + + func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) { + if !enabled { + return + } + + switch gestureRecognizer.state { + case .began: + let translation = gestureRecognizer.translation(in: superview) + startPoint = CGPoint(x: round(translation.x), y: round(translation.y)) + delegate?.resizeControlDidBeginResizing(self) + case .changed: + let translation = gestureRecognizer.translation(in: superview) + self.translation = CGPoint(x: round(startPoint.x + translation.x), y: round(startPoint.y + translation.y)) + delegate?.resizeControlDidResize(self) + case .ended, .cancelled: + delegate?.resizeControlDidEndResizing(self) + default: () + } + + } +} diff --git a/Photo Editor/Photo Editor/StickerCollectionViewCell.swift b/Photo Editor/Photo Editor/StickerCollectionViewCell.swift old mode 100755 new mode 100644 diff --git a/Photo Editor/Photo Editor/StickerCollectionViewCell.xib b/Photo Editor/Photo Editor/StickerCollectionViewCell.xib old mode 100755 new mode 100644 index 17dd1ca53..417eccbae --- a/Photo Editor/Photo Editor/StickerCollectionViewCell.xib +++ b/Photo Editor/Photo Editor/StickerCollectionViewCell.xib @@ -1,23 +1,23 @@ - + - + - + - + @@ -36,7 +36,4 @@ - - - diff --git a/Photo Editor/Photo Editor/BottomSheetViewController.swift b/Photo Editor/Photo Editor/StickersViewController.swift similarity index 92% rename from Photo Editor/Photo Editor/BottomSheetViewController.swift rename to Photo Editor/Photo Editor/StickersViewController.swift index 9bba9f699..c2f700241 100755 --- a/Photo Editor/Photo Editor/BottomSheetViewController.swift +++ b/Photo Editor/Photo Editor/StickersViewController.swift @@ -1,19 +1,14 @@ // -// BottomSheetViewController.swift +// StickersViewController.swift // Photo Editor // // Created by Mohamed Hamed on 4/23/17. // Copyright © 2017 Mohamed Hamed. All rights reserved. -// -import UIKit +// Credit https://github.com/AhmedElassuty/IOS-BottomSheet -protocol StickerDelegate { - func viewTapped(view: UIView) - func imageTapped(image: UIImage) - func bottomSheetDidDisappear() -} +import UIKit -class BottomSheetViewController: UIViewController, UIGestureRecognizerDelegate { +class StickersViewController: UIViewController, UIGestureRecognizerDelegate { @IBOutlet weak var headerView: UIView! @IBOutlet weak var holdView: UIView! @IBOutlet weak var scrollView: UIScrollView! @@ -25,7 +20,7 @@ class BottomSheetViewController: UIViewController, UIGestureRecognizerDelegate { var emojisDelegate: EmojisCollectionViewDelegate! var stickers : [UIImage] = [] - var stickerDelegate : StickerDelegate? + var stickersViewControllerDelegate : StickersViewControllerDelegate? let screenSize = UIScreen.main.bounds.size @@ -47,7 +42,7 @@ class BottomSheetViewController: UIViewController, UIGestureRecognizerDelegate { pageControl.numberOfPages = 2 holdView.layer.cornerRadius = 3 - let gesture = UIPanGestureRecognizer.init(target: self, action: #selector(BottomSheetViewController.panGesture)) + let gesture = UIPanGestureRecognizer.init(target: self, action: #selector(StickersViewController.panGesture)) gesture.delegate = self view.addGestureRecognizer(gesture) } @@ -84,13 +79,13 @@ class BottomSheetViewController: UIViewController, UIGestureRecognizerDelegate { let emojislayout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() emojislayout.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10) - emojislayout.itemSize = CGSize(width: 60, height: 60) + emojislayout.itemSize = CGSize(width: 70, height: 70) emojisCollectioView = UICollectionView(frame: emojisFrame, collectionViewLayout: emojislayout) emojisCollectioView.backgroundColor = .clear scrollView.addSubview(emojisCollectioView) emojisDelegate = EmojisCollectionViewDelegate() - emojisDelegate.stickerDelegate = stickerDelegate + emojisDelegate.stickersViewControllerDelegate = stickersViewControllerDelegate emojisCollectioView.delegate = emojisDelegate emojisCollectioView.dataSource = emojisDelegate @@ -191,7 +186,7 @@ class BottomSheetViewController: UIViewController, UIGestureRecognizerDelegate { }, completion: { (finished) -> Void in self.view.removeFromSuperview() self.removeFromParentViewController() - self.stickerDelegate?.bottomSheetDidDisappear() + self.stickersViewControllerDelegate?.stickersViewDidDisappear() }) } @@ -209,7 +204,7 @@ class BottomSheetViewController: UIViewController, UIGestureRecognizerDelegate { } -extension BottomSheetViewController: UIScrollViewDelegate { +extension StickersViewController: UIScrollViewDelegate { func scrollViewDidScroll(_ scrollView: UIScrollView) { let pageWidth = scrollView.bounds.width @@ -219,14 +214,14 @@ extension BottomSheetViewController: UIScrollViewDelegate { } // MARK: - UICollectionViewDataSource -extension BottomSheetViewController: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { +extension StickersViewController: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return stickers.count } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - stickerDelegate?.imageTapped(image: stickers[indexPath.item]) + stickersViewControllerDelegate?.didSelectImage(image: stickers[indexPath.item]) } func numberOfSections(in collectionView: UICollectionView) -> Int { diff --git a/Photo Editor/Photo Editor/BottomSheetViewController.xib b/Photo Editor/Photo Editor/StickersViewController.xib similarity index 93% rename from Photo Editor/Photo Editor/BottomSheetViewController.xib rename to Photo Editor/Photo Editor/StickersViewController.xib index 1c801433f..d3996b7e2 100755 --- a/Photo Editor/Photo Editor/BottomSheetViewController.xib +++ b/Photo Editor/Photo Editor/StickersViewController.xib @@ -1,14 +1,14 @@ - + - + - + diff --git a/Photo Editor/Photo Editor/UIImage+Crop.swift b/Photo Editor/Photo Editor/UIImage+Crop.swift new file mode 100755 index 000000000..7726ff366 --- /dev/null +++ b/Photo Editor/Photo Editor/UIImage+Crop.swift @@ -0,0 +1,34 @@ +// +// UIImage+Crop.swift +// CropViewController +// +// Created by Guilherme Moura on 2/26/16. +// Copyright © 2016 Reefactor, Inc. All rights reserved. +// Credit https://github.com/sprint84/PhotoCropEditor + +import UIKit + +extension UIImage { + func rotatedImageWithTransform(_ rotation: CGAffineTransform, croppedToRect rect: CGRect) -> UIImage { + let rotatedImage = rotatedImageWithTransform(rotation) + + let scale = rotatedImage.scale + let cropRect = rect.applying(CGAffineTransform(scaleX: scale, y: scale)) + + let croppedImage = rotatedImage.cgImage?.cropping(to: cropRect) + let image = UIImage(cgImage: croppedImage!, scale: self.scale, orientation: rotatedImage.imageOrientation) + return image + } + + fileprivate func rotatedImageWithTransform(_ transform: CGAffineTransform) -> UIImage { + UIGraphicsBeginImageContextWithOptions(size, true, scale) + let context = UIGraphicsGetCurrentContext() + context?.translateBy(x: size.width / 2.0, y: size.height / 2.0) + context?.concatenate(transform) + context?.translateBy(x: size.width / -2.0, y: size.height / -2.0) + draw(in: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)) + let rotatedImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return rotatedImage! + } +} diff --git a/Photo Editor/Photo Editor/UIImageExtensions.swift b/Photo Editor/Photo Editor/UIImage+Size.swift old mode 100755 new mode 100644 similarity index 53% rename from Photo Editor/Photo Editor/UIImageExtensions.swift rename to Photo Editor/Photo Editor/UIImage+Size.swift index a307fd911..9c45afbe5 --- a/Photo Editor/Photo Editor/UIImageExtensions.swift +++ b/Photo Editor/Photo Editor/UIImage+Size.swift @@ -1,5 +1,5 @@ // -// UIImage+Rotate.swift +// UIImage+Size.swift // Photo Editor // // Created by Mohamed Hamed on 5/2/17. @@ -10,23 +10,10 @@ import UIKit public extension UIImage { - func rotateImageIfNeeded() -> UIImage - { - if size.width > size.height { // Landscape - return self.rotateImage(orientation: .right) - } else { //Portrait - return self - } - } - - func rotateImage(orientation: UIImageOrientation) -> UIImage { - let rotatedImage = UIImage(cgImage:self.cgImage!, - scale: 1, - orientation:orientation); - return rotatedImage - } - - func sutibleSize(heightLimit: CGFloat? = nil, + /** + Suitable size for specific height or width to keep same image ratio + */ + func suitableSize(heightLimit: CGFloat? = nil, widthLimit: CGFloat? = nil )-> CGSize? { if let height = heightLimit { @@ -43,5 +30,4 @@ public extension UIImage { return nil } - } diff --git a/Photo Editor/Photo Editor/UIImageViewExtensions.swift b/Photo Editor/Photo Editor/UIImageView+Alpha.swift old mode 100755 new mode 100644 similarity index 97% rename from Photo Editor/Photo Editor/UIImageViewExtensions.swift rename to Photo Editor/Photo Editor/UIImageView+Alpha.swift index fce862137..387763090 --- a/Photo Editor/Photo Editor/UIImageViewExtensions.swift +++ b/Photo Editor/Photo Editor/UIImageView+Alpha.swift @@ -1,6 +1,6 @@ // // UIImageViewExtenstions.swift -// Pods +// Photo Editor // // Created by Mohamed Hamed on 5/10/17. // diff --git a/Photo Editor/Photo Editor/UIView+Image.swift b/Photo Editor/Photo Editor/UIView+Image.swift old mode 100755 new mode 100644 index 55c7d4b40..9ff6ab290 --- a/Photo Editor/Photo Editor/UIView+Image.swift +++ b/Photo Editor/Photo Editor/UIView+Image.swift @@ -9,7 +9,9 @@ import UIKit extension UIView { - + /** + Convert UIView to UIImage + */ func toImage() -> UIImage { UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.isOpaque, 0.0) self.drawHierarchy(in: self.bounds, afterScreenUpdates: false) @@ -17,12 +19,4 @@ extension UIView { UIGraphicsEndImageContext() return snapshotImageFromMyView! } - - func toImageView() -> UIImageView { - let imageView = UIImageView() - imageView.image = toImage() - imageView.frame = frame - imageView.contentMode = .scaleAspectFit - return imageView - } } diff --git a/Photo Editor/Photo Editor/icomoon.ttf b/Photo Editor/Photo Editor/icomoon.ttf new file mode 100755 index 000000000..b677a83b2 Binary files /dev/null and b/Photo Editor/Photo Editor/icomoon.ttf differ diff --git a/Photo Editor/iOSPhotoEditor.podspec b/Photo Editor/iOSPhotoEditor.podspec old mode 100755 new mode 100644 index b1e0026e4..6d90d591f --- a/Photo Editor/iOSPhotoEditor.podspec +++ b/Photo Editor/iOSPhotoEditor.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'iOSPhotoEditor' - s.version = '0.3.5' + s.version = '0.5' s.summary = 'Photo Editor supports drawing, writing text and adding stickers and emojis' s.description = <<-DESC diff --git a/README.md b/README.md old mode 100755 new mode 100644 index 101f3379b..33297225e --- a/README.md +++ b/README.md @@ -1,15 +1,22 @@ # iOS Photo Editor ## Features +- [x] Cropping - [x] Adding images -Stickers- - [x] Adding Text with colors - [x] Drawing wihtcolors - [x] Scaling and rotating objects - [x] Deleting objects -- [x] Saving to photos +- [x] Saving to photos and Sharing - [x] Cool animations - [x] Uses iOS Taptic Engine feedback +## New Features in V 0.4 + +Thanks to https://github.com/sprint84/PhotoCropEditor + +It now supports Cropping 💃🏻 + ## Installation ### CocoaPods diff --git a/appetize.png b/appetize.png old mode 100755 new mode 100644