diff --git a/DebugFrame.podspec b/DebugFrame.podspec index d8e594a..e1ce7fb 100644 --- a/DebugFrame.podspec +++ b/DebugFrame.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = "DebugFrame" - spec.version = "0.0.2" + spec.version = "0.1.3" spec.summary = "Debug frame modifier for SwiftUI views." spec.homepage = "https://github.com/vdshko/DebugFrame.git" spec.license = { :type => "MIT", :file => "License" } diff --git a/Example/Example/ContentView.swift b/Example/Example/ContentView.swift index 5fd1994..5ec308c 100644 --- a/Example/Example/ContentView.swift +++ b/Example/Example/ContentView.swift @@ -2,7 +2,7 @@ // ContentView.swift // Example // -// Created by Vlad Shkodich on 19.12.2022. +// Created by Vladyslav Shkodych on 19.12.2022. // import SwiftUI @@ -16,7 +16,7 @@ struct ContentView: View { rectangles Spacer() } - .debugFrame() + .debugFrame(.size) .padding(20.0) .debugFrame() .padding(30.0) @@ -43,20 +43,20 @@ struct ContentView: View { RoundedRectangle(cornerRadius: 4.0) .frame(width: 220.0, height: 100.0) .foregroundColor(Color("first")) - .debugFrame() + .debugFrame(color: .black) HStack { Spacer() RoundedRectangle(cornerRadius: 4.0) .frame(width: 120.0, height: 150.0) .foregroundColor(Color("second")) - .debugFrame() + .debugFrame(.size) .padding(.trailing, 25.0) } HStack { RoundedRectangle(cornerRadius: 4.0) .frame(width: 120.0, height: 100.0) .foregroundColor(Color("third")) - .debugFrame() + .debugFrame(color: .white, .originX, .width) .padding(.leading, 20.0) Spacer() } diff --git a/Example/Example/ExampleApp.swift b/Example/Example/ExampleApp.swift index 5c0bde5..56d7b1f 100644 --- a/Example/Example/ExampleApp.swift +++ b/Example/Example/ExampleApp.swift @@ -2,7 +2,7 @@ // ExampleApp.swift // Example // -// Created by Vlad Shkodich on 19.12.2022. +// Created by Vladyslav Shkodych on 19.12.2022. // import SwiftUI @@ -10,6 +10,7 @@ import DebugFrame @main struct ExampleApp: App { + var body: some Scene { WindowGroup { ContentView() diff --git a/Example/ExampleTests/ContentViewTests.swift b/Example/ExampleTests/ContentViewTests.swift index 946a804..fb0fd09 100644 --- a/Example/ExampleTests/ContentViewTests.swift +++ b/Example/ExampleTests/ContentViewTests.swift @@ -2,7 +2,7 @@ // ExampleTests.swift // ExampleTests // -// Created by Vlad Shkodich on 19.12.2022. +// Created by Vladyslav Shkodych on 19.12.2022. // import XCTest diff --git a/Example/ExampleTests/ViewImageConfig.swift b/Example/ExampleTests/ViewImageConfig.swift index aebd2c4..040d179 100644 --- a/Example/ExampleTests/ViewImageConfig.swift +++ b/Example/ExampleTests/ViewImageConfig.swift @@ -2,7 +2,7 @@ // ViewImageConfig.swift // ExampleTests // -// Created by Vlad Shkodich on 19.12.2022. +// Created by Vladyslav Shkodych on 19.12.2022. // import Foundation diff --git a/Example/ExampleTests/__Snapshots__/ContentViewTests/test_body_loaded.1.png b/Example/ExampleTests/__Snapshots__/ContentViewTests/test_body_loaded.1.png index 2aa5429..a676800 100644 Binary files a/Example/ExampleTests/__Snapshots__/ContentViewTests/test_body_loaded.1.png and b/Example/ExampleTests/__Snapshots__/ContentViewTests/test_body_loaded.1.png differ diff --git a/Example/Podfile b/Example/Podfile index ac7c2d2..efb994e 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -4,10 +4,12 @@ use_frameworks! install! 'cocoapods', :warn_for_unused_master_specs_repo => false target 'Example' do - pod 'DebugFrame' + + pod 'DebugFrame', :path => '../' end target 'ExampleTests' do + # SnapshotTesting; https://github.com/pointfreeco/swift-snapshot-testing pod 'SnapshotTesting', '1.9.0', :inhibit_warnings => true end diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 417ead3..d339b18 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,20 +1,23 @@ PODS: - - DebugFrame (0.0.1) + - DebugFrame (0.1.3) - SnapshotTesting (1.9.0) DEPENDENCIES: - - DebugFrame + - DebugFrame (from `../`) - SnapshotTesting (= 1.9.0) SPEC REPOS: trunk: - - DebugFrame - SnapshotTesting +EXTERNAL SOURCES: + DebugFrame: + :path: "../" + SPEC CHECKSUMS: - DebugFrame: 39f20e1bbe6150058e239b744cccf0c8bf649f86 + DebugFrame: e563c37cd7499f172aad51c44fc2034f51a6544e SnapshotTesting: 6141c48b6aa76ead61431ca665c14ab9a066c53b -PODFILE CHECKSUM: 6e25a6dad0d57076d1de03bce513a768e5ed8d79 +PODFILE CHECKSUM: 8f2d82fe448e2e09320a9a650ed45b374d09e3ba COCOAPODS: 1.11.3 diff --git a/README.md b/README.md index 04937d9..2f08c8e 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,13 @@ DebugFrame is a modifier for SwiftUI view, which is very easy to use and add to ``` VStack { title + .debugFrame() Spacer() rectangles - .debugFrame() + .debugFrame(color: .black) Spacer() } -.debugFrame() +.debugFrame(color: .black, .size) ``` -Screenshot 2022-12-19 at 19 08 31 +Screenshot 2023-04-06 at 03 06 00 diff --git a/Source/DebugFrame/DebugFrame.h b/Source/DebugFrame/DebugFrame.h index 1626196..51d0676 100644 --- a/Source/DebugFrame/DebugFrame.h +++ b/Source/DebugFrame/DebugFrame.h @@ -2,7 +2,7 @@ // DebugFrame.h // DebugFrame // -// Created by Vlad Shkodich on 19.12.2022. +// Created by Vladyslav Shkodych on 19.12.2022. // #import diff --git a/Source/DebugFrame/DebugFrame.swift b/Source/DebugFrame/DebugFrame.swift index 4d96207..0b26d58 100644 --- a/Source/DebugFrame/DebugFrame.swift +++ b/Source/DebugFrame/DebugFrame.swift @@ -2,14 +2,27 @@ // DebugFrame.swift // DebugFrame // -// Created by Vlad Shkodich on 19.12.2022. +// Created by Vladyslav Shkodych on 19.12.2022. // +/* + DebugFrame is an overlay that can be appended to your view, for debugging its origin and size. + + DebugFrame will not be compiled in the release build, so you may not worry if you forget to remove it from some of your view. + To keep your code as clean as possible, it's probably a good idea to add a SwiftLint or any other linting rule to make an Xcode warning for this. + + There are two methods for modifying your view with debugFrame overlay. + The two methods need only for easier use of the Xcode autocomplete. + */ + import Foundation import SwiftUI private struct DebugFrame: ViewModifier { + let color: Color + let outputs: [DebugFrameOutput] + func body(content: Content) -> some View { #if !DEBUG return content @@ -18,29 +31,78 @@ private struct DebugFrame: ViewModifier { content .overlay( GeometryReader { geometry in - let globalOrigin: CGPoint = geometry.frame(in: .global).origin - let origin: String = "(x: \(rounded(globalOrigin.x)), y: \(rounded(globalOrigin.y)))" - let size: String = "(w: \(rounded(geometry.size.width)), h: \(rounded(geometry.size.height)))" ZStack(alignment: .bottom) { Rectangle() .strokeBorder(style: StrokeStyle(lineWidth: 1, dash: [5])) - .foregroundColor(Color.red) - Text("\(origin) | \(size)") - .foregroundColor(Color.red) + .foregroundColor(color) + Text(defineOutput(with: geometry)) + .foregroundColor(color) .font(.caption2) } } ) } + private func defineOutput(with geometry: GeometryProxy) -> String { + let globalOrigin: CGPoint = geometry.frame(in: .global).origin + let originX: String = "x: \(rounded(globalOrigin.x))" + let originY: String = "y: \(rounded(globalOrigin.y))" + let width: String = "w: \(rounded(geometry.size.width))" + let height: String = "h: \(rounded(geometry.size.height))" + return String( + outputs.reduce(into: String()) { + switch $1 { + case .all: $0 += "(\(originX), \(originY)) | (\(width), \(height))" + case .origin: $0 += "(\(originX), \(originY))" + case .size: $0 += "(\(width), \(height))" + case .originX: $0 += originX + case .originY: $0 += originY + case .width: $0 += width + case .height: $0 += height + } + $0 += " | " + }.dropLast(3) + ) + } + private func rounded(_ value: CGFloat) -> Float { return Float(round(100 * value) / 100) } } +public enum DebugFrameOutput { + + case all + case origin, size + case originX, originY + case width, height +} + public extension View { - func debugFrame() -> some View { - return modifier(DebugFrame()) + /// Applies an overlay to your view and returns a new view. The overlay contains a border of your view, its origin, and size. + /// - Parameter color: Default color for the border of the overlay and outputs. + /// - Returns: View that uses the debug overlay. + func debugFrame(color: Color = Color.red) -> some View { + return modifier( + DebugFrame( + color: color, + outputs: [DebugFrameOutput.all] + ) + ) + } + + /// Applies an overlay to your view and returns a new view. The overlay contains a border of your view, its origin, and size. + /// - Parameters: + /// - color: Default color for the border of the overlay and outputs. + /// - outputs: Default outputs of the overlay such as origin and size. + /// - Returns: View that uses the debug overlay. + func debugFrame(color: Color = Color.red, _ outputs: DebugFrameOutput...) -> some View { + return modifier( + DebugFrame( + color: color, + outputs: outputs.isEmpty ? [DebugFrameOutput.all] : outputs + ) + ) } }