From 5c882e1475f94028c51f28feed4af5bfb1e4d411 Mon Sep 17 00:00:00 2001 From: Alexandr Romanov Date: Sat, 12 Nov 2022 11:23:32 +0300 Subject: [PATCH] Add styles for bar button and fix small bugs --- .../Controls/Button/BarButton.swift | 16 ++++++ .../Controls/ContentView/ContentView.swift | 6 +-- .../Controls/PageView/PageView.swift | 54 +++++++++++-------- Sources/OversizeUI/Controls/Row/Row.swift | 12 +++-- .../OversizeUI/Controls/Row/RowButton.swift | 41 +++++++++++--- .../Core/Appearance/ThemeSettings.swift | 2 +- .../Extensions/HalfSheet/HalfSheet.swift | 5 ++ 7 files changed, 97 insertions(+), 39 deletions(-) diff --git a/Sources/OversizeUI/Controls/Button/BarButton.swift b/Sources/OversizeUI/Controls/Button/BarButton.swift index d2690d9..64aab0b 100644 --- a/Sources/OversizeUI/Controls/Button/BarButton.swift +++ b/Sources/OversizeUI/Controls/Button/BarButton.swift @@ -14,6 +14,8 @@ public enum BarButtonType { case primary(_ text: String, action: () -> Void) case secondary(_ text: String, action: () -> Void) case disabled(_ text: String) + case image(_ image: Image, action: () -> Void) + case icon(_ icon: IconsNames, action: () -> Void) } public struct BarButton: View { @@ -91,6 +93,20 @@ extension BarButton { } .style(.gray, size: .medium, rounded: .full, shadow: false) .disabled(true) + case let .image(image, action): + Button { + action() + } label: { + image + .renderingMode(.template) + .foregroundOnSurfaceHighEmphasis() + } + .style(.secondary, size: .medium, rounded: .full, width: .round, shadow: true) + case let .icon(icon, action): + Button(action: action) { + Icon(icon) + } + .style(.secondary, size: .medium, rounded: .full, width: .round, shadow: true) } } } diff --git a/Sources/OversizeUI/Controls/ContentView/ContentView.swift b/Sources/OversizeUI/Controls/ContentView/ContentView.swift index 68bd7c9..2828990 100644 --- a/Sources/OversizeUI/Controls/ContentView/ContentView.swift +++ b/Sources/OversizeUI/Controls/ContentView/ContentView.swift @@ -27,9 +27,9 @@ public struct ContentView: View { private let primaryButton: ContenButtonType? private let secondaryButton: ContenButtonType? - public init(image: Image?, + public init(image: Image? = nil, title: String, - subtitle: String?, + subtitle: String? = nil, primaryButton: ContenButtonType? = nil, secondaryButton: ContenButtonType? = nil) { @@ -45,7 +45,7 @@ public struct ContentView: View { VStack(alignment: vStackAlignment, spacing: .medium) { if let image { image - .frame(width: 218, height: 218, alignment: .center) + .frame(width: 218, height: 218, alignment: .bottom) } TextBox(title: title, subtitle: subtitle) diff --git a/Sources/OversizeUI/Controls/PageView/PageView.swift b/Sources/OversizeUI/Controls/PageView/PageView.swift index 035d72f..46c2e5b 100644 --- a/Sources/OversizeUI/Controls/PageView/PageView.swift +++ b/Sources/OversizeUI/Controls/PageView/PageView.swift @@ -5,27 +5,26 @@ import SwiftUI - public struct PageView: View where Content: View, LeadingBar: View, TrailingBar: View, TopToolbar: View, TitleLabel: View { @Environment(\.screenSize) var screenSize - + private let title: String? private let content: Content private var isModalable = false private var isLargeTitle = false private var isAlwaysSlideSmallTile = false @State private var offset: CGPoint = .init(x: 0, y: 0) - + private var leadingBar: LeadingBar? private var trailingBar: TrailingBar? private var topToolbar: TopToolbar? private var titleLabel: TitleLabel? - + private var backgroundColor: Color = .backgroundPrimary private var backgroundLinerGradient: LinearGradient? - + private let onOffsetChanged: (CGFloat) -> Void - + public init(_ title: String? = nil, onOffsetChanged: @escaping (CGFloat) -> Void = { _ in }, @ViewBuilder content: () -> Content) @@ -34,7 +33,7 @@ public struct PageView self.onOffsetChanged = onOffsetChanged self.content = content() } - + public var body: some View { VStack(spacing: .zero) { if title != nil || leadingBar != nil || trailingBar != nil || topToolbar != nil || titleLabel != nil { @@ -47,7 +46,7 @@ public struct PageView trailingBar: { trailingBar }, bottomBar: { topToolbar }, titleLabel: { titleLabel }) - .zIndex(999_999_999) + .zIndex(999_999_999) } ScrollViewOffset(offset: $offset) { content @@ -59,7 +58,7 @@ public struct PageView onOffsetChanged(offset.y) } } - + var background: some View { Group { if let backgroundLinerGradient { @@ -69,73 +68,73 @@ public struct PageView } } } - + public func modalable(_ isModalable: Bool = true) -> PageView { var control = self control.isModalable = isModalable return control } - + public func slideSmallTile(_ isSlise: Bool = true) -> PageView { var control = self control.isAlwaysSlideSmallTile = isSlise return control } - + public func navigationBarHidden(_ isModalable: Bool = true) -> PageView { var control = self control.isModalable = isModalable return control } - + public func largeTitle(_ isLargeTitle: Bool = true) -> PageView { var control = self control.isLargeTitle = isLargeTitle return control } - + public func backgroundColor(_ backgroundColor: Color = .backgroundSecondary) -> PageView { var control = self control.backgroundColor = backgroundColor return control } - + public func backgroundSecondary() -> PageView { var control = self control.backgroundColor = .backgroundSecondary return control } - + public func backgroundLinerGradient(_ gradient: LinearGradient) -> PageView { var control = self control.backgroundLinerGradient = gradient return control } - + public func leadingBar(@ViewBuilder leadingBar: @escaping () -> LeadingBar) -> PageView { var control = self control.leadingBar = leadingBar() return control } - + public func trailingBar(@ViewBuilder trailingBar: @escaping () -> TrailingBar) -> PageView { var control = self control.trailingBar = trailingBar() return control } - + public func topToolbar(@ViewBuilder topToolbar: @escaping () -> TopToolbar) -> PageView { var control = self control.topToolbar = topToolbar() return control } - + public func titleLabel(@ViewBuilder titleLabel: @escaping () -> TitleLabel) -> PageView { var control = self control.titleLabel = titleLabel() return control } - + public func bottomToolbar(style: PageViewBottomType = .shadow, ignoreSafeArea: Bool = true, @ViewBuilder bottomToolbar: @escaping () -> some View) -> some View { VStack(spacing: .zero) { self @@ -147,7 +146,7 @@ public struct PageView LinearGradient(colors: [backgroundColor.opacity(0), Color.surfacePrimary.opacity(1)], startPoint: .top, endPoint: .bottom) - .frame(height: 60) + .frame(height: 60) } } if style == .none { @@ -348,3 +347,14 @@ public extension PageView where TopToolbar == EmptyView { } } +public extension PageView where TitleLabel == EmptyView { + init(_ title: String? = nil, + onOffsetChanged: @escaping (CGFloat) -> Void = { _ in }, + @ViewBuilder content: () -> Content) + { + self.title = title + self.onOffsetChanged = onOffsetChanged + self.content = content() + titleLabel = nil + } +} diff --git a/Sources/OversizeUI/Controls/Row/Row.swift b/Sources/OversizeUI/Controls/Row/Row.swift index 93ad9f9..1cd2451 100644 --- a/Sources/OversizeUI/Controls/Row/Row.swift +++ b/Sources/OversizeUI/Controls/Row/Row.swift @@ -20,7 +20,7 @@ public enum RowTrailingType { public enum RowLeadingType { case icon(_ name: IconsNames) case iconOnSurface(_ name: IconsNames) - case image(_ image: Image) + case image(_ image: Image, color: Color? = .onSurfaceHighEmphasis) case imageOnSurface(_ image: Image, color: Color? = nil) case systemImage(_ imageName: String) case avatar(_ avatar: AvatarView) @@ -130,12 +130,14 @@ public struct Row: View { Icon(icon) .padding(.trailing, Constants.spacingIconAndText) - case let .image(image): + case let .image(image, color): image - .renderingMode(.template) + .renderingMode(color != nil ? .template : .original) .resizable() - .foregroundColor(.onSurfaceHighEmphasis) - .frame(width: 24, height: 24) + .scaledToFill() + .foregroundColor(color) + .frame(width: subtitle != nil ? 48 : 24, height: subtitle != nil ? 48 : 24) + .cornerRadius(subtitle != nil ? 4 : 2) case let .avatar(avatar): avatar diff --git a/Sources/OversizeUI/Controls/Row/RowButton.swift b/Sources/OversizeUI/Controls/Row/RowButton.swift index 79fedd8..ad8a7fc 100644 --- a/Sources/OversizeUI/Controls/Row/RowButton.swift +++ b/Sources/OversizeUI/Controls/Row/RowButton.swift @@ -12,6 +12,8 @@ public enum RowButtonStyle { } public struct RowButton: View { + @Environment(\.multilineTextAlignment) var multilineTextAlignment + @Environment(\.controlPadding) var controlPadding: ControlPadding public var text: String public var style: RowButtonStyle public var icon: IconsNames @@ -30,8 +32,12 @@ public struct RowButton: View { public var body: some View { VStack(alignment: .leading) { - Button(action: self.tapAction) { + Button(action: tapAction) { HStack { + if multilineTextAlignment == .center || multilineTextAlignment == .trailing { + Spacer() + } + if icon != .none { Surface { Icon(icon) @@ -42,16 +48,35 @@ public struct RowButton: View { Text(text) .fontStyle(.headline) - .foregroundColor(style == .link - ? Color.link - : style == .delete - ? Color.error - : Color.onSurfaceHighEmphasis) + .foregroundColor(foregroundColor) - Spacer() + if multilineTextAlignment == .leading || multilineTextAlignment == .center { + Spacer() + } } + .padding(.vertical, verticalPadding) + .padding(.horizontal, controlPadding.horizontal) } + .buttonStyle(.row) + } + } + + private var verticalPadding: CGFloat { + switch controlPadding.vertical { + case .zero: + return .zero + case .xxSmall: + return .zero + default: + return controlPadding.vertical.rawValue - Space.xxSmall.rawValue + } + } - }.frame(minHeight: 70) + private var foregroundColor: Color { + style == .link + ? Color.link + : style == .delete + ? Color.error + : Color.onSurfaceHighEmphasis } } diff --git a/Sources/OversizeUI/Core/Appearance/ThemeSettings.swift b/Sources/OversizeUI/Core/Appearance/ThemeSettings.swift index 98fe342..6475a8a 100644 --- a/Sources/OversizeUI/Core/Appearance/ThemeSettings.swift +++ b/Sources/OversizeUI/Core/Appearance/ThemeSettings.swift @@ -25,7 +25,7 @@ public enum ThemeSettingsNames { public class ThemeSettings: ObservableObject { public init() {} - @AppStorage(ThemeSettingsNames.appearance) public var appearance: Appearance = .light + @AppStorage(ThemeSettingsNames.appearance) public var appearance: Appearance = .system #if os(iOS) @AppStorage(ThemeSettingsNames.accentColor) public var accentColor: Color = .blue diff --git a/Sources/OversizeUI/Extensions/HalfSheet/HalfSheet.swift b/Sources/OversizeUI/Extensions/HalfSheet/HalfSheet.swift index 87503a2..c32d813 100644 --- a/Sources/OversizeUI/Extensions/HalfSheet/HalfSheet.swift +++ b/Sources/OversizeUI/Extensions/HalfSheet/HalfSheet.swift @@ -55,6 +55,11 @@ import SwiftUI } } } + + @_disfavoredOverload + func presentationDragIndicator(_ visibility: Visibility) -> some View { + self + } } public struct SheetView: UIViewControllerRepresentable {