From 2843629e39be68ef9217b1d700cabd8a13a37c69 Mon Sep 17 00:00:00 2001 From: Alexandr Romanov Date: Fri, 9 Sep 2022 13:12:14 +0300 Subject: [PATCH 1/2] Update half sheet --- Package.swift | 16 ++++------------ .../Extensions/HalfSheet/HalfSheet.swift | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/Package.swift b/Package.swift index f92418d..6307f24 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 5.6 +// swift-tools-version: 5.7 // The swift-tools-version declares the minimum version of Swift required to build this package. // swiftlint:disable all @@ -14,19 +14,11 @@ let package = Package( .watchOS(.v8), ], products: [ - .library( - name: "OversizeUI", targets: ["OversizeUI"] - ), + .library(name: "OversizeUI", targets: ["OversizeUI"]), ], dependencies: [], targets: [ - .target( - name: "OversizeUI", - dependencies: [] - ), - .testTarget( - name: "OversizeUITests", - dependencies: ["OversizeUI"] - ), + .target(name: "OversizeUI", dependencies: [] ), + .testTarget(name: "OversizeUITests", dependencies: ["OversizeUI"]), ] ) diff --git a/Sources/OversizeUI/Extensions/HalfSheet/HalfSheet.swift b/Sources/OversizeUI/Extensions/HalfSheet/HalfSheet.swift index df97465..7c8adb0 100644 --- a/Sources/OversizeUI/Extensions/HalfSheet/HalfSheet.swift +++ b/Sources/OversizeUI/Extensions/HalfSheet/HalfSheet.swift @@ -20,12 +20,20 @@ import SwiftUI return .medium() } } + + @available(iOS 16, *) + func convertToSUI() -> PresentationDetent { + if self == .medium { + return PresentationDetent.medium + } else { + return PresentationDetent.large + } + } } #endif // swiftlint:disable line_length #if os(iOS) - @available(iOS 15, *) public struct SheetModifier: ViewModifier { public let detents: [Detents] public func body(content: Content) -> some View { @@ -38,7 +46,14 @@ import SwiftUI public extension View { @_disfavoredOverload func presentationDetents(_ detents: [Detents]) -> some View { - modifier(SheetModifier(detents: detents)) + Group { + if #available(iOS 16, *) { + let suiDetents: Set = Set(detents.compactMap { $0.convertToSUI() }) + self.presentationDetents(suiDetents) + } else { + modifier(SheetModifier(detents: detents)) + } + } } } From 46fd9e6ae4a8fd4734d89f63011211b61ddd98e8 Mon Sep 17 00:00:00 2001 From: Alexandr Romanov Date: Fri, 9 Sep 2022 14:03:59 +0300 Subject: [PATCH 2/2] Add PageIndexView and update readme for Xcode 14 --- Example/ExampleUITests/ExampleUITests.swift | 2 +- Example/Shared/ComponentsList.swift | 2 +- Package.swift | 2 +- README.md | 9 ++++-- .../Controls/BlurView/BlurView.swift | 6 ++-- .../Controls/GridSelect/GridSelectStyle.swift | 4 +-- .../LocationPicker/LocationPicker.swift | 2 +- .../Controls/LocationPicker/MapView.swift | 12 ++++---- .../Controls/PageControl/PageIndexView.swift | 29 +++++++++++++++++++ .../SegmentedControlStyle.swift | 14 ++++----- .../ScreenSizeEnvironment.swift | 2 +- .../AppStorage/RawRepresentable.swift | 4 +-- .../Extensions/Color/Color+Hex.swift | 4 +-- .../Extensions/HalfSheet/HalfSheet.swift | 2 +- 14 files changed, 63 insertions(+), 31 deletions(-) create mode 100644 Sources/OversizeUI/Controls/PageControl/PageIndexView.swift diff --git a/Example/ExampleUITests/ExampleUITests.swift b/Example/ExampleUITests/ExampleUITests.swift index 93cce9a..96ca4d0 100644 --- a/Example/ExampleUITests/ExampleUITests.swift +++ b/Example/ExampleUITests/ExampleUITests.swift @@ -22,7 +22,7 @@ class ExampleUITests: XCTestCase { func testExample() throws { // UI tests must launch the application that they test. - let app = XCUIApplication() + let app: XCUIApplication = .init() app.launch() // Use recording to get started writing UI tests. diff --git a/Example/Shared/ComponentsList.swift b/Example/Shared/ComponentsList.swift index 5aeff51..d225155 100644 --- a/Example/Shared/ComponentsList.swift +++ b/Example/Shared/ComponentsList.swift @@ -7,7 +7,7 @@ import OversizeUI import SwiftUI struct Page: Identifiable { - let id = UUID() + let id: UUID = .init() let name: String let page: AnyView } diff --git a/Package.swift b/Package.swift index 6307f24..15121f9 100644 --- a/Package.swift +++ b/Package.swift @@ -18,7 +18,7 @@ let package = Package( ], dependencies: [], targets: [ - .target(name: "OversizeUI", dependencies: [] ), + .target(name: "OversizeUI", dependencies: []), .testTarget(name: "OversizeUITests", dependencies: ["OversizeUI"]), ] ) diff --git a/README.md b/README.md index 4d15727..88d493f 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,9 @@ Yet another component library on SwiftUI +## Design System +Controls and styles in [Figma](https://www.figma.com/community/file/1144847542164788208) + ## Controls Some of the controls available include: @@ -34,13 +37,13 @@ Colors, Typography, Spacing and other styles in [core folder](Sources/OversizeUI #### Requirements - iOS 15+ or macOS 12.0+ -- Xcode 13.4+ -- Swift 5.6+ +- Xcode 14.0+ +- Swift 5.7+ #### Swift Package Manager - File > Swift Packages > Add Package Dependency - Add `https://github.com/oversizedev/OversizeUI.git` -- Select "Up to Next Major" with "2.0.0" +- Select "Up to Next Major" with "2.2.0" ### Import and use OversizeUI After the framework has been added you can import the module to use it: diff --git a/Sources/OversizeUI/Controls/BlurView/BlurView.swift b/Sources/OversizeUI/Controls/BlurView/BlurView.swift index f3e761a..b4ce9bf 100644 --- a/Sources/OversizeUI/Controls/BlurView/BlurView.swift +++ b/Sources/OversizeUI/Controls/BlurView/BlurView.swift @@ -16,10 +16,10 @@ import SwiftUI public let style: UIBlurEffect.Style public func makeUIView(context _: UIViewRepresentableContext) -> UIView { - let view = UIView(frame: .zero) + let view: UIView = .init(frame: .zero) view.backgroundColor = .clear - let blurEffect = UIBlurEffect(style: style) - let blurView = UIVisualEffectView(effect: blurEffect) + let blurEffect: UIBlurEffect = .init(style: style) + let blurView: UIVisualEffectView = .init(effect: blurEffect) blurView.translatesAutoresizingMaskIntoConstraints = false view.insertSubview(blurView, at: 0) NSLayoutConstraint.activate([ diff --git a/Sources/OversizeUI/Controls/GridSelect/GridSelectStyle.swift b/Sources/OversizeUI/Controls/GridSelect/GridSelectStyle.swift index 5afe2e2..6cace03 100644 --- a/Sources/OversizeUI/Controls/GridSelect/GridSelectStyle.swift +++ b/Sources/OversizeUI/Controls/GridSelect/GridSelectStyle.swift @@ -16,14 +16,14 @@ public extension View { func gridSelectStyle(_ style: GridSelectStyleType) -> some View { switch style { case let .default(selected: selected, icon: icon): - let style = IslandGridSelectStyle() + let style: IslandGridSelectStyle = .init() return environment(\.gridSelectStyle, AnyGridSelectStyle(seletionStyle: selected, unseletionStyle: style.unseletionStyle, icon: icon, style: style)) case let .onlySelection(selected: selected, icon: icon): - let style = SelectionOnlyGridSelectStyle() + let style: SelectionOnlyGridSelectStyle = .init() return environment(\.gridSelectStyle, AnyGridSelectStyle(seletionStyle: selected, unseletionStyle: style.unseletionStyle, diff --git a/Sources/OversizeUI/Controls/LocationPicker/LocationPicker.swift b/Sources/OversizeUI/Controls/LocationPicker/LocationPicker.swift index 5410c4b..bf34794 100644 --- a/Sources/OversizeUI/Controls/LocationPicker/LocationPicker.swift +++ b/Sources/OversizeUI/Controls/LocationPicker/LocationPicker.swift @@ -111,7 +111,7 @@ import SwiftUI longitude: coordinate.longitude ) - let geocoder = CLGeocoder() + let geocoder: CLGeocoder = .init() geocoder.reverseGeocodeLocation(loc) { placemarks, error in if error != nil { return } diff --git a/Sources/OversizeUI/Controls/LocationPicker/MapView.swift b/Sources/OversizeUI/Controls/LocationPicker/MapView.swift index c9b9db5..e1b6e7c 100644 --- a/Sources/OversizeUI/Controls/LocationPicker/MapView.swift +++ b/Sources/OversizeUI/Controls/LocationPicker/MapView.swift @@ -12,16 +12,16 @@ import SwiftUI public struct MapView: UIViewRepresentable { @Binding var centerCoordinate: CLLocationCoordinate2D - let mapView = MKMapView() + let mapView: MKMapView = .init() public func makeUIView(context: Context) -> MKMapView { mapView.delegate = context.coordinator // mapView.centerCoordinate = centerCoordinate - let center = CLLocationCoordinate2D(latitude: centerCoordinate.latitude, longitude: centerCoordinate.longitude) + let center: CLLocationCoordinate2D = .init(latitude: centerCoordinate.latitude, longitude: centerCoordinate.longitude) - let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1) - let region = MKCoordinateRegion(center: center, span: span) + let span: MKCoordinateSpan = .init(latitudeDelta: 0.1, longitudeDelta: 0.1) + let region: MKCoordinateRegion = .init(center: center, span: span) mapView.setRegion(region, animated: true) return mapView @@ -52,10 +52,10 @@ import SwiftUI let coordinate = parent.mapView.convert(location, toCoordinateFrom: parent.mapView) withAnimation { - let clObject = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude) + let clObject: CLLocationCoordinate2D = .init(latitude: coordinate.latitude, longitude: coordinate.longitude) parent.centerCoordinate = clObject - let annotation = MKPointAnnotation() + let annotation: MKPointAnnotation = .init() annotation.coordinate = clObject withAnimation { diff --git a/Sources/OversizeUI/Controls/PageControl/PageIndexView.swift b/Sources/OversizeUI/Controls/PageControl/PageIndexView.swift new file mode 100644 index 0000000..52b5aad --- /dev/null +++ b/Sources/OversizeUI/Controls/PageControl/PageIndexView.swift @@ -0,0 +1,29 @@ +// +// Copyright © 2022 Alexander Romanov +// PageIndexView.swift +// + +import SwiftUI + +public struct PageIndexView: View { + @Binding private var index: Int + private let maxIndex: Int + + public init(_ index: Binding, maxIndex: Int) { + _index = index + self.maxIndex = maxIndex + } + + public var body: some View { + HStack(spacing: 8) { + ForEach(0 ..< maxIndex, id: \.self) { index in + Capsule() + .fill(index == self.index ? Color.accent : Color.surfaceTertiary) + .frame(width: index == self.index ? 28 : 8, height: 8) + .animation(.default, value: index) + } + } + .padding(12) + .animation(.default, value: index) + } +} diff --git a/Sources/OversizeUI/Controls/SegmentedControl/SegmentedControlStyle.swift b/Sources/OversizeUI/Controls/SegmentedControl/SegmentedControlStyle.swift index 9bbe762..0bc8b8b 100644 --- a/Sources/OversizeUI/Controls/SegmentedControl/SegmentedControlStyle.swift +++ b/Sources/OversizeUI/Controls/SegmentedControl/SegmentedControlStyle.swift @@ -33,7 +33,7 @@ public extension View { func segmentedControlStyle(_ style: SegmentedControlStyleType) -> some View { switch style { case .default: - let style = RectangleSegmentedControlStyle() + let style: RectangleSegmentedControlStyle = .init() return environment(\.segmentedControlStyle, AnySegmentedControlStyle(isEquallySpacing: style.isEquallySpacing, @@ -42,7 +42,7 @@ public extension View { unseletionStyle: style.unseletionStyle, style: style)) case let .island(selected: selected): - let style = IslandSegmentedControlStyle() + let style: IslandSegmentedControlStyle = .init() return environment(\.segmentedControlStyle, AnySegmentedControlStyle(isEquallySpacing: true, @@ -51,7 +51,7 @@ public extension View { unseletionStyle: .surface, style: style)) case let .islandScroll(selected: selected): - let style = ScrollSegmentedControlStyle() + let style: ScrollSegmentedControlStyle = .init() return environment(\.segmentedControlStyle, AnySegmentedControlStyle(isEquallySpacing: false, @@ -60,7 +60,7 @@ public extension View { unseletionStyle: .surface, style: style)) case let .onlySelection(selected: selected): - let style = SelectionOnlySegmentedControlStyle() + let style: SelectionOnlySegmentedControlStyle = .init() return environment(\.segmentedControlStyle, AnySegmentedControlStyle(isEquallySpacing: true, @@ -69,7 +69,7 @@ public extension View { unseletionStyle: .clean, style: style)) case let .onlySelectionLeading(selected: selected): - let style = SelectionOnlySegmentedControlStyle() + let style: SelectionOnlySegmentedControlStyle = .init() return environment(\.segmentedControlStyle, AnySegmentedControlStyle(isEquallySpacing: false, @@ -78,7 +78,7 @@ public extension View { unseletionStyle: .clean, style: style)) case let .onlySelectionScroll(selected: selected): - let style = ScrollSegmentedControlStyle() + let style: ScrollSegmentedControlStyle = .init() return environment(\.segmentedControlStyle, AnySegmentedControlStyle(isEquallySpacing: false, @@ -87,7 +87,7 @@ public extension View { unseletionStyle: .clean, style: style)) case let .islandLeading(selected: selected): - let style = IslandSegmentedControlStyle() + let style: IslandSegmentedControlStyle = .init() return environment(\.segmentedControlStyle, AnySegmentedControlStyle(isEquallySpacing: false, diff --git a/Sources/OversizeUI/Core/EnvironmentKeys/ScreenSizeEnvironment.swift b/Sources/OversizeUI/Core/EnvironmentKeys/ScreenSizeEnvironment.swift index 222f854..d972612 100644 --- a/Sources/OversizeUI/Core/EnvironmentKeys/ScreenSizeEnvironment.swift +++ b/Sources/OversizeUI/Core/EnvironmentKeys/ScreenSizeEnvironment.swift @@ -56,7 +56,7 @@ public struct ScreenSize { } private struct ScreenSizeKey: EnvironmentKey { - static let defaultValue = ScreenSize(width: 375, height: 667) + static let defaultValue: ScreenSize = .init(width: 375, height: 667) } public extension EnvironmentValues { diff --git a/Sources/OversizeUI/Extensions/AppStorage/RawRepresentable.swift b/Sources/OversizeUI/Extensions/AppStorage/RawRepresentable.swift index 54fe9ad..36260ae 100644 --- a/Sources/OversizeUI/Extensions/AppStorage/RawRepresentable.swift +++ b/Sources/OversizeUI/Extensions/AppStorage/RawRepresentable.swift @@ -6,7 +6,7 @@ import SwiftUI extension Date: RawRepresentable { - private static let formatter = ISO8601DateFormatter() + private static let formatter: ISO8601DateFormatter = .init() public var rawValue: String { Date.formatter.string(from: self) @@ -29,7 +29,7 @@ extension Array: RawRepresentable where Element: Codable { public var rawValue: String { guard let data = try? JSONEncoder().encode(self), - let result = String(data: data, encoding: .utf8) + let result: String = .init(data: data, encoding: .utf8) else { return "[]" } diff --git a/Sources/OversizeUI/Extensions/Color/Color+Hex.swift b/Sources/OversizeUI/Extensions/Color/Color+Hex.swift index 5808dc3..39313c1 100644 --- a/Sources/OversizeUI/Extensions/Color/Color+Hex.swift +++ b/Sources/OversizeUI/Extensions/Color/Color+Hex.swift @@ -78,7 +78,7 @@ public extension Color { #if canImport(AppKit) let color = NSColor(self).usingColorSpace(.displayP3)! #elseif canImport(UIKit) - let color = UIColor(self) + let color: UIColor = .init(self) #endif var t = (CGFloat(), CGFloat(), CGFloat(), CGFloat()) @@ -117,7 +117,7 @@ private func hexIntFromColorComponents(rgba components: ColorComponentsRGBA) -> struct Hex_Preview: PreviewProvider { static var previews: some View { - let green = Color(hex: "#00FF00") + let green: Color = .init(hex: "#00FF00") return Circle() .frame(width: 100, height: 100) diff --git a/Sources/OversizeUI/Extensions/HalfSheet/HalfSheet.swift b/Sources/OversizeUI/Extensions/HalfSheet/HalfSheet.swift index 7c8adb0..87503a2 100644 --- a/Sources/OversizeUI/Extensions/HalfSheet/HalfSheet.swift +++ b/Sources/OversizeUI/Extensions/HalfSheet/HalfSheet.swift @@ -20,7 +20,7 @@ import SwiftUI return .medium() } } - + @available(iOS 16, *) func convertToSUI() -> PresentationDetent { if self == .medium {