From 46d936264c2d32fbce64cd8149b27d060df3a48f Mon Sep 17 00:00:00 2001 From: Benedikt Betz Date: Thu, 19 Oct 2023 13:56:09 +0200 Subject: Updated Package implementation, Tests and README --- Assets/crop_circle.png | Bin 0 -> 1801566 bytes Assets/crop_square.png | Bin 0 -> 2173417 bytes Package.swift | 1 + README.md | 32 +++++++++++++++------ Sources/SwiftyCrop/Models/Configuration.swift | 17 ----------- Sources/SwiftyCrop/Models/MaskShape.swift | 2 +- .../Models/SwiftyCropConfiguration.swift | 17 +++++++++++ Sources/SwiftyCrop/SwiftyCrop.swift | 24 ++++++++++++---- Sources/SwiftyCrop/View/CropView.swift | 6 ++-- Tests/SwiftyCropTests/SwiftyCropTests.swift | 10 +++---- 10 files changed, 67 insertions(+), 42 deletions(-) create mode 100644 Assets/crop_circle.png create mode 100644 Assets/crop_square.png delete mode 100644 Sources/SwiftyCrop/Models/Configuration.swift create mode 100644 Sources/SwiftyCrop/Models/SwiftyCropConfiguration.swift diff --git a/Assets/crop_circle.png b/Assets/crop_circle.png new file mode 100644 index 0000000..f0a553b Binary files /dev/null and b/Assets/crop_circle.png differ diff --git a/Assets/crop_square.png b/Assets/crop_square.png new file mode 100644 index 0000000..a080843 Binary files /dev/null and b/Assets/crop_square.png differ diff --git a/Package.swift b/Package.swift index 388d74a..ca79f2e 100644 --- a/Package.swift +++ b/Package.swift @@ -5,6 +5,7 @@ import PackageDescription let package = Package( name: "SwiftyCrop", + defaultLocalization: "en", platforms: [.iOS(.v16)], products: [ // Products define the executables and libraries a package produces, making them visible to other packages. diff --git a/README.md b/README.md index c07e0ad..3b5b95c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ -# SwiftyCrop +# SwiftyCrop - SwiftUI -// TODO: Screenshots, GIFs +

+ + +

## 🔭 Overview SwiftyCrop allows users to seamlessly crop images within their SwiftUI applications. It provides a user-friendly interface that makes cropping an image as simple as selecting the desired area. @@ -31,8 +34,8 @@ The localization file can be found in `Sources/SwiftyCrop/Resources`. ## 🧳 Requirements - iOS 16.0 or later -- Xcode 14.3 or later -- Swift 5.0 or later +- Xcode 15.0 or later +- Swift 5.9 or later ## 💻 Installation @@ -69,8 +72,6 @@ struct ExampleView: View { var body: some View { VStack { /* - Your view implementation here. - Update `selectedImage` with the image you want to crop, e.g. after picking it from the library or downloading it. @@ -79,8 +80,10 @@ struct ExampleView: View { Below is a sample implementation: */ - Button("Show cropper with system image") { - selectedImage = UIImage(systemName: "photo") + Button("Crop downloaded image") { + Task { + selectedImage = await downloadExampleImage() + } showImageCropper.toggle() } @@ -96,6 +99,17 @@ struct ExampleView: View { } } } + + // Example function for downloading an image + private func downloadExampleImage() async -> UIImage? { + let urlString = "https://picsum.photos/1000/1200" + guard let url = URL(string: urlString), + let (data, _) = try? await URLSession.shared.data(from: url), + let image = UIImage(data: data) + else { return nil } + + return image + } } ``` @@ -127,7 +141,7 @@ All issue reports, feature requests, pull requests and GitHub stars are welcomed ## ✍️ Author -Benedikt Betz +Benedikt Betz & Check24 ## 📃 License diff --git a/Sources/SwiftyCrop/Models/Configuration.swift b/Sources/SwiftyCrop/Models/Configuration.swift deleted file mode 100644 index bacdab0..0000000 --- a/Sources/SwiftyCrop/Models/Configuration.swift +++ /dev/null @@ -1,17 +0,0 @@ -import CoreGraphics - -/// `SwiftyCropConfiguration` is a struct that defines the configuration for cropping behavior. -struct SwiftyCropConfiguration { - let maxMagnificationScale: CGFloat - let maskRadius: CGFloat - - /// Creates a new instance of `SwiftyCropConfiguration`. - /// - /// - Parameters: - /// - maxMagnificationScale: The maximum scale factor that the image can be magnified while cropping. Defaults to `4.0`. - /// - maskRadius: The radius of the mask used for cropping. Defaults to `130`. - init(maxMagnificationScale: CGFloat = 4.0, maskRadius: CGFloat = 130) { - self.maxMagnificationScale = maxMagnificationScale - self.maskRadius = maskRadius - } -} diff --git a/Sources/SwiftyCrop/Models/MaskShape.swift b/Sources/SwiftyCrop/Models/MaskShape.swift index c4b1538..d20e722 100644 --- a/Sources/SwiftyCrop/Models/MaskShape.swift +++ b/Sources/SwiftyCrop/Models/MaskShape.swift @@ -1,3 +1,3 @@ -enum MaskShape { +public enum MaskShape { case circle, square } diff --git a/Sources/SwiftyCrop/Models/SwiftyCropConfiguration.swift b/Sources/SwiftyCrop/Models/SwiftyCropConfiguration.swift new file mode 100644 index 0000000..cc3d47a --- /dev/null +++ b/Sources/SwiftyCrop/Models/SwiftyCropConfiguration.swift @@ -0,0 +1,17 @@ +import CoreGraphics + +/// `SwiftyCropConfiguration` is a struct that defines the configuration for cropping behavior. +public struct SwiftyCropConfiguration { + let maxMagnificationScale: CGFloat + let maskRadius: CGFloat + + /// Creates a new instance of `SwiftyCropConfiguration`. + /// + /// - Parameters: + /// - maxMagnificationScale: The maximum scale factor that the image can be magnified while cropping. Defaults to `4.0`. + /// - maskRadius: The radius of the mask used for cropping. Defaults to `130`. + public init(maxMagnificationScale: CGFloat = 4.0, maskRadius: CGFloat = 130) { + self.maxMagnificationScale = maxMagnificationScale + self.maskRadius = maskRadius + } +} diff --git a/Sources/SwiftyCrop/SwiftyCrop.swift b/Sources/SwiftyCrop/SwiftyCrop.swift index ab252e6..0de933d 100644 --- a/Sources/SwiftyCrop/SwiftyCrop.swift +++ b/Sources/SwiftyCrop/SwiftyCrop.swift @@ -9,13 +9,25 @@ import SwiftUI /// - maskShape: The shape of the mask used for cropping. /// - configuration: The configuration for the cropping behavior. If nothing is specified, the default is used. /// - onComplete: A closure that's called when the cropping is complete. This closure returns the cropped `UIImage?`. If an error occurs the return value is nil. -struct SwiftyCropView: View { - let imageToCrop: UIImage - let maskShape: MaskShape - let configuration: SwiftyCropConfiguration = SwiftyCropConfiguration() - let onComplete: (UIImage?) -> Void +public struct SwiftyCropView: View { + private let imageToCrop: UIImage + private let maskShape: MaskShape + private let configuration: SwiftyCropConfiguration + private let onComplete: (UIImage?) -> Void - var body: some View { + public init( + imageToCrop: UIImage, + maskShape: MaskShape, + configuration: SwiftyCropConfiguration = SwiftyCropConfiguration(), + onComplete: @escaping (UIImage?) -> Void + ) { + self.imageToCrop = imageToCrop + self.maskShape = maskShape + self.configuration = configuration + self.onComplete = onComplete + } + + public var body: some View { CropView( image: imageToCrop, maskShape: maskShape, diff --git a/Sources/SwiftyCrop/View/CropView.swift b/Sources/SwiftyCrop/View/CropView.swift index 29cfb8a..3cb453a 100644 --- a/Sources/SwiftyCrop/View/CropView.swift +++ b/Sources/SwiftyCrop/View/CropView.swift @@ -31,7 +31,7 @@ struct CropView: View { var body: some View { VStack { - Text("interaction_instructions", tableName: localizableTableName) + Text("interaction_instructions", tableName: localizableTableName, bundle: .module) .font(.system(size: 16, weight: .regular)) .foregroundColor(.white) .padding(.top, 30) @@ -100,7 +100,7 @@ struct CropView: View { Button { dismiss() } label: { - Text("cancel_button", tableName: localizableTableName) + Text("cancel_button", tableName: localizableTableName, bundle: .module) } .foregroundColor(.white) @@ -110,7 +110,7 @@ struct CropView: View { onComplete(viewModel.crop(image)) dismiss() } label: { - Text("save_button", tableName: localizableTableName) + Text("save_button", tableName: localizableTableName, bundle: .module) } .foregroundColor(.white) } diff --git a/Tests/SwiftyCropTests/SwiftyCropTests.swift b/Tests/SwiftyCropTests/SwiftyCropTests.swift index e029923..3e0877f 100644 --- a/Tests/SwiftyCropTests/SwiftyCropTests.swift +++ b/Tests/SwiftyCropTests/SwiftyCropTests.swift @@ -2,11 +2,9 @@ import XCTest @testable import SwiftyCrop final class SwiftyCropTests: XCTestCase { - func testExample() throws { - // XCTest Documentation - // https://developer.apple.com/documentation/xctest - - // Defining Test Cases and Test Methods - // https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods + func testConfigurationInit() { + let configuration = SwiftyCropConfiguration(maxMagnificationScale: 1.0, maskRadius: 1.0) + XCTAssertEqual(configuration.maxMagnificationScale, 1.0) + XCTAssertEqual(configuration.maskRadius, 1.0) } } -- cgit v1.2.3