diff --git a/Layers.xcodeproj/project.pbxproj b/Layers.xcodeproj/project.pbxproj index a100638..dc32e4c 100644 --- a/Layers.xcodeproj/project.pbxproj +++ b/Layers.xcodeproj/project.pbxproj @@ -23,11 +23,13 @@ 1111504A2AC8CD5A00C0D356 /* LayerActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111150392AC8CD5A00C0D356 /* LayerActions.swift */; }; 1111504B2AC8CD5A00C0D356 /* Layer+Example.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1111503A2AC8CD5A00C0D356 /* Layer+Example.swift */; }; 1111504C2AC8CD5A00C0D356 /* Layer+Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1111503C2AC8CD5A00C0D356 /* Layer+Constants.swift */; }; - 1111504E2AC8CD5A00C0D356 /* Layer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1111503E2AC8CD5A00C0D356 /* Layer+Extensions.swift */; }; 111150512AC96F4500C0D356 /* Layer+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111150502AC96F4500C0D356 /* Layer+Helpers.swift */; }; 111150532AC99EAA00C0D356 /* Layer+Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111150522AC99EAA00C0D356 /* Layer+Animations.swift */; }; 111150562AC9B66F00C0D356 /* ConfettiSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 111150552AC9B66F00C0D356 /* ConfettiSwiftUI */; }; 111150592AC9BD2300C0D356 /* FluidGradient in Frameworks */ = {isa = PBXBuildFile; productRef = 111150582AC9BD2300C0D356 /* FluidGradient */; }; + 118DD3D62ACB0F6300B03E88 /* Modifiers+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 118DD3D52ACB0F6300B03E88 /* Modifiers+Extensions.swift */; }; + 118DD3D82ACB101000B03E88 /* ButtonStyle+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 118DD3D72ACB101000B03E88 /* ButtonStyle+Extensions.swift */; }; + 118DD3DA2ACB105E00B03E88 /* Color+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 118DD3D92ACB105E00B03E88 /* Color+Extensions.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -48,9 +50,11 @@ 111150392AC8CD5A00C0D356 /* LayerActions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LayerActions.swift; sourceTree = ""; }; 1111503A2AC8CD5A00C0D356 /* Layer+Example.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Layer+Example.swift"; sourceTree = ""; }; 1111503C2AC8CD5A00C0D356 /* Layer+Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Layer+Constants.swift"; sourceTree = ""; }; - 1111503E2AC8CD5A00C0D356 /* Layer+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Layer+Extensions.swift"; sourceTree = ""; }; 111150502AC96F4500C0D356 /* Layer+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Layer+Helpers.swift"; sourceTree = ""; }; 111150522AC99EAA00C0D356 /* Layer+Animations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Layer+Animations.swift"; sourceTree = ""; }; + 118DD3D52ACB0F6300B03E88 /* Modifiers+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Modifiers+Extensions.swift"; sourceTree = ""; }; + 118DD3D72ACB101000B03E88 /* ButtonStyle+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ButtonStyle+Extensions.swift"; sourceTree = ""; }; + 118DD3D92ACB105E00B03E88 /* Color+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Extensions.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -85,6 +89,7 @@ 111150202AC8CCDF00C0D356 /* Layers */ = { isa = PBXGroup; children = ( + 118DD3D42ACB0F4D00B03E88 /* Helpers */, 1111502F2AC8CD5A00C0D356 /* Components */, 1111503B2AC8CD5A00C0D356 /* Utilities */, 111150212AC8CCDF00C0D356 /* LayersApp.swift */, @@ -125,13 +130,22 @@ children = ( 1111503A2AC8CD5A00C0D356 /* Layer+Example.swift */, 1111503C2AC8CD5A00C0D356 /* Layer+Constants.swift */, - 1111503E2AC8CD5A00C0D356 /* Layer+Extensions.swift */, 111150502AC96F4500C0D356 /* Layer+Helpers.swift */, 111150522AC99EAA00C0D356 /* Layer+Animations.swift */, ); path = Utilities; sourceTree = ""; }; + 118DD3D42ACB0F4D00B03E88 /* Helpers */ = { + isa = PBXGroup; + children = ( + 118DD3D52ACB0F6300B03E88 /* Modifiers+Extensions.swift */, + 118DD3D72ACB101000B03E88 /* ButtonStyle+Extensions.swift */, + 118DD3D92ACB105E00B03E88 /* Color+Extensions.swift */, + ); + path = Helpers; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -218,11 +232,13 @@ 111150472AC8CD5A00C0D356 /* LayerText.swift in Sources */, 111150242AC8CCDF00C0D356 /* ContentView.swift in Sources */, 111150222AC8CCDF00C0D356 /* LayersApp.swift in Sources */, + 118DD3D62ACB0F6300B03E88 /* Modifiers+Extensions.swift in Sources */, 1111504A2AC8CD5A00C0D356 /* LayerActions.swift in Sources */, 111150512AC96F4500C0D356 /* Layer+Helpers.swift in Sources */, - 1111504E2AC8CD5A00C0D356 /* Layer+Extensions.swift in Sources */, 111150532AC99EAA00C0D356 /* Layer+Animations.swift in Sources */, 1111504C2AC8CD5A00C0D356 /* Layer+Constants.swift in Sources */, + 118DD3D82ACB101000B03E88 /* ButtonStyle+Extensions.swift in Sources */, + 118DD3DA2ACB105E00B03E88 /* Color+Extensions.swift in Sources */, 111150432AC8CD5A00C0D356 /* LayerButton.swift in Sources */, 111150442AC8CD5A00C0D356 /* LayerHeader.swift in Sources */, 111150422AC8CD5A00C0D356 /* LayerImagePicker.swift in Sources */, diff --git a/Layers/Components/LayerBackground.swift b/Layers/Components/LayerBackground.swift index 01c8674..6bc2b69 100644 --- a/Layers/Components/LayerBackground.swift +++ b/Layers/Components/LayerBackground.swift @@ -8,10 +8,22 @@ import SwiftUI struct LayerBackground: View { + @State private var z: Double = 0 + @State private var opacity: Double + @State private var color: Color + + internal init(z: Double = 0, + opacity: Double = 0.25, + color: Color = .black) + { + self.z = z + self.opacity = opacity + self.color = color + } + var body: some View { ZStack { - Color(.black.opacity(0.25)) - .ignoresSafeArea() - } + Color(color.opacity(opacity)).ignoresSafeArea() + }.zIndex(z) } } diff --git a/Layers/Components/LayerStack.swift b/Layers/Components/LayerStack.swift index 8ad4e43..92e3158 100644 --- a/Layers/Components/LayerStack.swift +++ b/Layers/Components/LayerStack.swift @@ -12,13 +12,16 @@ struct LayerStack: View { var content: AnyView - public init(@ViewBuilder content: @escaping () -> Content) where Content: View { + public init( + @ViewBuilder content: @escaping () -> Content) where Content: View + { self.content = AnyView(content()) } var body: some View { VStack { Spacer() + ZStack { VStack(alignment: .leading, spacing: 24) { content @@ -41,13 +44,20 @@ struct LayerStack: View { } } } - .layerPadding() + .padding( + EdgeInsets( + top: 0, + leading: 16, + bottom: 0, + trailing: 16 + ) + ) } } #Preview { ZStack { - Color(.black.opacity(0.25)).ignoresSafeArea() + LayerBackground() LayerStack { VStack {} diff --git a/Layers/ContentView.swift b/Layers/ContentView.swift index 8a036ef..ccf70ac 100644 --- a/Layers/ContentView.swift +++ b/Layers/ContentView.swift @@ -46,7 +46,7 @@ struct ContentView: View { show.toggle() } } - }y + } } } diff --git a/Layers/Helpers/ButtonStyle+Extensions.swift b/Layers/Helpers/ButtonStyle+Extensions.swift new file mode 100644 index 0000000..6567540 --- /dev/null +++ b/Layers/Helpers/ButtonStyle+Extensions.swift @@ -0,0 +1,24 @@ +// +// ButtonStyle+Extensions.swift +// Layers +// +// Created by Raphael Salaja on 02/10/2023. +// + +import SwiftUI + +struct ScaleButtonStyle: ButtonStyle { + public init() {} + + public func makeBody(configuration: Self.Configuration) -> some View { + configuration.label + .scaleEffect(configuration.isPressed ? Constants.Scale.pressed : 1) + .transition(.scale(scale: 1.0)) + } +} + +extension ButtonStyle where Self == ScaleButtonStyle { + static var scale: ScaleButtonStyle { + ScaleButtonStyle() + } +} diff --git a/Layers/Helpers/Color+Extensions.swift b/Layers/Helpers/Color+Extensions.swift new file mode 100644 index 0000000..9a9fb75 --- /dev/null +++ b/Layers/Helpers/Color+Extensions.swift @@ -0,0 +1,30 @@ +// +// Color+Extensions.swift +// Layers +// +// Created by Raphael Salaja on 02/10/2023. +// + +import SwiftUI + +extension Color { + + /// Returns a Boolean value indicating whether the color is dark. + var isDark: Bool { + var red: CGFloat = 0 + var green: CGFloat = 0 + var blue: CGFloat = 0 + + guard UIColor(self).getRed(&red, green: &green, blue: &blue, alpha: nil) + else { + return false + } + + let luminance = + Constants.Luminance.red * red + + Constants.Luminance.green * green + + Constants.Luminance.blue * blue + + return luminance < Constants.Luminance.threshold + } +} diff --git a/Layers/Helpers/Modifiers+Extensions.swift b/Layers/Helpers/Modifiers+Extensions.swift new file mode 100644 index 0000000..5f8409b --- /dev/null +++ b/Layers/Helpers/Modifiers+Extensions.swift @@ -0,0 +1,68 @@ +// +// Modifiers+Extensions.swift +// Layers +// +// Created by Raphael Salaja on 02/10/2023. +// + +import SwiftUI + +// MARK: - Transition + +struct SimpleTransition: ViewModifier { + func body(content: Content) -> some View { + content + .transition(.scale(scale: 1.0)) + } +} + +extension View { + func simpleTransition() -> some View { + modifier(SimpleTransition()) + } +} + +// MARK: - Layer + +struct LayerTitleStyle: ViewModifier { + func body(content: Content) -> some View { + content + .font(.system(.title3, design: .rounded, weight: .bold)) + } +} + +struct LayerDescriptionStyle: ViewModifier { + func body(content: Content) -> some View { + content + .font(.system(.headline, design: .rounded, weight: .medium)) + .minimumScaleFactor(0.1) + .foregroundColor(Color(.systemGray)) + } +} + +struct LayerButtonStyle: ViewModifier { + var color: Color + + func body(content: Content) -> some View { + content + .fixedSize() + .font(.body) + .fontWeight(.bold) + .fontDesign(.rounded) + .foregroundColor(color.isDark ? Color.white : Color.black) + } +} + +extension View { + func layerTitleStyle() -> some View { + modifier(LayerTitleStyle()) + } + + func layerDescriptionStyle() -> some View { + modifier(LayerDescriptionStyle()) + } + + func layerButtonStyle(color: Color) -> some View { + modifier(LayerButtonStyle(color: color)) + } +} diff --git a/Layers/Utilities/Layer+Constants.swift b/Layers/Utilities/Layer+Constants.swift index 9a0df32..6aedbc2 100644 --- a/Layers/Utilities/Layer+Constants.swift +++ b/Layers/Utilities/Layer+Constants.swift @@ -20,10 +20,6 @@ public enum Constants { static let brightness: CGFloat = 0.85 } - enum Styling { - static let padding: EdgeInsets = .init(top: 0, leading: 16, bottom: 0, trailing: 16) - } - enum Animations { enum Namespaces { static let namespace: Namespace.ID = Namespace().wrappedValue diff --git a/Layers/Utilities/Layer+Example.swift b/Layers/Utilities/Layer+Example.swift index 621f810..88984d5 100644 --- a/Layers/Utilities/Layer+Example.swift +++ b/Layers/Utilities/Layer+Example.swift @@ -92,14 +92,28 @@ struct Layer_Example: View { ) } } - - LayerButton( - text: $action, - color: Color(.systemBlue) - ) { - withAnimation(.smooth) { - index = (index + 1) % 4 - action = actions[index][0] + if index == 3 { + LayerButton( + text: $action, + color: Color(.systemBlue), + icon: "photo" + ) { + withAnimation(.smooth) { + index = (index + 1) % 4 + action = actions[index][0] + } + } + } + else { + LayerButton( + text: $action, + color: Color(.systemBlue), + icon: "" + ) { + withAnimation(.smooth) { + index = (index + 1) % 4 + action = actions[index][0] + } } } } diff --git a/Layers/Utilities/Layer+Extensions.swift b/Layers/Utilities/Layer+Extensions.swift deleted file mode 100644 index 37dc555..0000000 --- a/Layers/Utilities/Layer+Extensions.swift +++ /dev/null @@ -1,118 +0,0 @@ -// -// LayerPadding.swift -// Eyedee -// -// Created by Raphael Salaja on 29/09/2023. -// - -import SwiftUI - -// MARK: - ViewModifier - -struct Plain: ViewModifier { - func body(content: Content) -> some View { - content - .transition(.scale(scale: 1.0)) - } -} - -struct LayerPadding: ViewModifier { - func body(content: Content) -> some View { - content - .padding(Constants.Styling.padding) - } -} - -struct LayerTitleStyle: ViewModifier { - func body(content: Content) -> some View { - content - .font(.system(.title3, design: .rounded, weight: .bold)) - } -} - -struct LayerDescriptionStyle: ViewModifier { - func body(content: Content) -> some View { - content - .font(.system(.headline, design: .rounded, weight: .medium)) - .minimumScaleFactor(0.1) - .foregroundColor(Color(.systemGray)) - } -} - -struct LayerButtonStyle: ViewModifier { - var color: Color - - func body(content: Content) -> some View { - content - .fixedSize() - .font(.body) - .fontWeight(.bold) - .fontDesign(.rounded) - .foregroundColor(color.isDark ? Color.white : Color.black) - } -} - -// MARK: - ButtonStyle - -struct ScaleButtonStyle: ButtonStyle { - public init() {} - - public func makeBody(configuration: Self.Configuration) -> some View { - configuration.label - .scaleEffect(configuration.isPressed ? Constants.Scale.pressed : 1) - .transition(.scale(scale: 1.0)) -// .animation(.linear, value: configuration.isPressed) - } -} - -extension ButtonStyle where Self == ScaleButtonStyle { - static var scale: ScaleButtonStyle { - ScaleButtonStyle() - } -} - -// MARK: - Color - -extension Color { - var isDark: Bool { - var red: CGFloat = 0 - var green: CGFloat = 0 - var blue: CGFloat = 0 - - guard UIColor(self).getRed(&red, green: &green, blue: &blue, alpha: nil) - else { - return false - } - - let luminance = - Constants.Luminance.red * red + - Constants.Luminance.green * green + - Constants.Luminance.blue * blue - - return luminance < Constants.Luminance.threshold - } -} - -// MARK: - View - -extension View { - func plainTransition() -> some View { - modifier(Plain()) - } - - func layerPadding() -> some View { - modifier(LayerPadding()) - } - - func layerTitleStyle() -> some View { - modifier(LayerTitleStyle()) - } - - func layerDescriptionStyle() -> some View { - modifier(LayerDescriptionStyle()) - } - - func layerButtonStyle(color color: Color) -> some View { - modifier(LayerButtonStyle(color: color)) - } -}