Skip to content

Commit

Permalink
1.3.3
Browse files Browse the repository at this point in the history
  • Loading branch information
nathantannar4 committed Nov 1, 2024
1 parent eb872a6 commit c504e85
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
LastUpgradeVersion = "1530"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ let package = Package(
),
],
dependencies: [
.package(url: "https://github.com/nathantannar4/Engine", from: "1.8.1"),
.package(url: "https://github.com/nathantannar4/Engine", from: "1.8.8"),
],
targets: [
.target(
Expand Down
39 changes: 39 additions & 0 deletions Sources/Turbocharger/Sources/Alignment/FirstTextMidline.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// Copyright (c) Nathan Tannar
//

import SwiftUI

extension VerticalAlignment {
private enum FirstTextMidline: AlignmentID {
static func defaultValue(in context: ViewDimensions) -> CGFloat {
let dy = context[.lastTextBaseline] - context[.firstTextBaseline]
let lineHeight = context.height - dy
return lineHeight / 2
}
}

public static let firstTextMidline = VerticalAlignment(FirstTextMidline.self)
}

// MARK: - Previews

struct FirstTextMidline_Previews: PreviewProvider {
static var previews: some View {
VStack {
HStack(alignment: .firstTextMidline) {
Color.red
.frame(width: 32, height: 32)

Text("Lorem ipsum")
}

HStack(alignment: .firstTextMidline) {
Color.red
.frame(width: 32, height: 32)

Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import SwiftUI
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
extension AttributedString {

#if os(iOS) || os(tvOS) || os(watchOS)
#if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
public func toUIKit(
in environment: EnvironmentValues = EnvironmentValues()
) -> AttributedString {
Expand All @@ -33,7 +33,7 @@ extension AttributedString {
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
extension AttributeContainer {

#if os(iOS) || os(tvOS) || os(watchOS)
#if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
public func toUIKit(
in environment: EnvironmentValues = EnvironmentValues()
) -> AttributeContainer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extension Color {
}
}

#if os(iOS) || os(tvOS) || os(watchOS)
#if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
@available(iOS 14.0, tvOS 14.0, watchOS 7.0, *)
public func toUIColor() -> UIColor {
toPlatformValue()
Expand All @@ -31,10 +31,10 @@ extension Color {

#if os(macOS)
typealias PlatformRepresentable = NSColor
#elseif os(iOS) || os(tvOS) || os(watchOS)
#elseif os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
typealias PlatformRepresentable = UIColor
#endif
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
private func toPlatformValue() -> PlatformRepresentable {
func resolve(provider: Any) -> PlatformRepresentable {
Expand All @@ -59,7 +59,7 @@ extension Color {
return PlatformRepresentable(self)
}
let bundle = mirror.descendant("bundle") as? Bundle
#if os(iOS) || os(tvOS)
#if os(iOS) || os(tvOS) || os(visionOS)
return UIColor { traits in
UIColor(named: name, in: bundle, compatibleWith: traits) ?? UIColor(self)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ extension EnvironmentValues {
self["ImageScaleKey"]
}

#if os(iOS) || os(tvOS) || os(watchOS)
#if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
/// The value for the ``.textInputAutocapitalization(_)`` modifier
@available(iOS 15.0, tvOS 15.0, watchOS 8.0, *)
@available(macOS, unavailable)
Expand Down
4 changes: 2 additions & 2 deletions Sources/Turbocharger/Sources/Extensions/Font+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ extension Font {
#if os(macOS)
typealias PlatformRepresentable = NSFont
typealias PlatformRepresentableDescriptor = NSFontDescriptor
#elseif os(iOS) || os(tvOS) || os(watchOS)
#elseif os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
typealias PlatformRepresentable = UIFont
typealias PlatformRepresentableDescriptor = UIFontDescriptor
#endif

#if os(iOS) || os(tvOS) || os(watchOS)
#if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public func toUIFont() -> UIFont? {
toPlatformValue()
Expand Down
40 changes: 34 additions & 6 deletions Sources/Turbocharger/Sources/Extensions/Image+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ extension Image {

#if os(macOS)
typealias PlatformRepresentable = NSImage
#elseif os(iOS) || os(tvOS) || os(watchOS)
#elseif os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
typealias PlatformRepresentable = UIImage
#endif

#if os(iOS) || os(tvOS) || os(watchOS)
#if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
public func toUIImage(
in environment: EnvironmentValues = EnvironmentValues()
) -> UIImage? {
Expand Down Expand Up @@ -89,7 +89,7 @@ private enum ImageProvider {
func resolved(in environment: EnvironmentValues) -> Image.PlatformRepresentable? {
switch self {
case .system(let name):
#if os(iOS) || os(tvOS) || os(watchOS)
#if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
let scale: UIImage.SymbolScale = {
guard let scale = environment.imageScale else { return .unspecified }
switch scale {
Expand All @@ -112,12 +112,40 @@ private enum ImageProvider {
)
#elseif os(macOS)
if #available(macOS 11.0, *) {
return NSImage(systemSymbolName: name, accessibilityDescription: nil)
let scale: NSImage.SymbolScale? = {
switch environment.imageScale {
case .small: return .small
case .medium: return .medium
case .large: return .large
case .none: return nil
@unknown default:
return nil
}
}()
let config = environment.font?.toNSFont().map {
let attributes = $0.fontDescriptor.fontAttributes
let traits = attributes[.traits] as? [NSFontDescriptor.TraitKey: Any]
let weight = traits?[.weight] as? NSFont.Weight
if let scale {
return NSImage.SymbolConfiguration(
pointSize: $0.pointSize,
weight: weight ?? .regular,
scale: scale
)
} else {
return NSImage.SymbolConfiguration(
pointSize: $0.pointSize,
weight: weight ?? .regular
)
}
} ?? NSImage.SymbolConfiguration(scale: scale ?? .medium)
return NSImage(systemSymbolName: name, accessibilityDescription: nil)?
.withSymbolConfiguration(config)
}
return nil
#endif
case let .named(name, bundle):
#if os(iOS) || os(tvOS) || os(watchOS)
#if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
return UIImage(named: name, in: bundle, with: nil)
#elseif os(macOS)
if #available(macOS 14.0, *), let bundle {
Expand All @@ -128,7 +156,7 @@ private enum ImageProvider {
case let .image(image):
return image
case let .cg(image, scale, orientation):
#if os(iOS) || os(tvOS) || os(watchOS)
#if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
let orientation: UIImage.Orientation = {
switch orientation {
case .down: return .down
Expand Down
10 changes: 8 additions & 2 deletions Sources/Turbocharger/Sources/Extensions/Text+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ extension Text {
fallthrough
}
var attributedString = AttributedString(stringLiteral: " ")
#if os(iOS) || os(tvOS) || os(watchOS)
#if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
if let image = image.toUIImage() {
if #available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *),
let baselineOffset = environment.baselineOffset,
Expand All @@ -207,6 +207,12 @@ extension Text {
)
}
}
#elseif os(macOS)
if let image = image.toNSImage() {
let attachment = NSTextAttachment()
attachment.image = image
attributedString.attachment = attachment
}
#endif
return attributedString

Expand All @@ -219,7 +225,7 @@ extension Text {
}
}

#if os(iOS) || os(tvOS) || os(watchOS)
#if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS) || os(macOS)
#if hasAttribute(retroactive)
extension NSTextAttachment: @unchecked @retroactive Sendable { }
#else
Expand Down
69 changes: 46 additions & 23 deletions Sources/Turbocharger/Sources/View/CollectionView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,21 @@ extension CollectionView where Header == EmptyView, Footer == EmptyView {
{
self.init(layout, sections: [items], id: id, content: content, header: { _ in EmptyView() }, footer: { _ in EmptyView() })
}

public init<
Views: View
>(
_ layout: Layout,
@ViewBuilder views: () -> Views
) where
Content == MultiViewSubviewVisitor.Subview,
Data == Array<Array<MultiViewSubviewVisitor.Subview>>
{
var visitor = MultiViewSubviewVisitor()
let content = views()
content.visit(visitor: &visitor)
self.init(layout, items: visitor.subviews, content: { $0 })
}
}

#if os(iOS)
Expand Down Expand Up @@ -502,26 +517,42 @@ private func makeHostingConfiguration<
ID: Hashable,
Content: View
>(
id: ID?,
id: ID,
kind: HostingConfigurationKind = .cell,
@ViewBuilder content: () -> Content
) -> UIContentConfiguration {
if #available(iOS 16.0, *) {
return HostingConfiguration(kind: kind) {
return UIHostingConfiguration {
content()
.contentTransition(.identity)
.transition(.identity)
.id(id)
.modifier(HostingConfigurationModifier(id: id))
}
.margins(.all, 0)
} else {
return HostingConfiguration(kind: kind) {
return HostingConfigurationBackport(kind: kind) {
content()
.transition(.identity)
.id(id)
.modifier(HostingConfigurationModifier(id: id))
}
}
}

private struct HostingConfigurationModifier<ID: Hashable>: VersionedViewModifier {
var id: ID

@available(iOS 16.0, *)
func v4Body(content: Content) -> some View {
content
.contentTransition(.identity)
.transition(.identity)
.id(id)
}

func v1Body(content: Content) -> some View {
content
.transition(.identity)
.id(id)
}
}

@frozen
public enum HostingConfigurationKind {
case supplementary(String)
Expand All @@ -532,7 +563,7 @@ public enum HostingConfigurationKind {
@available(macOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
public struct HostingConfiguration<
public struct HostingConfigurationBackport<
Content: View
>: UIContentConfiguration {
public var kind: HostingConfigurationKind
Expand All @@ -547,35 +578,27 @@ public struct HostingConfiguration<
}

public func makeContentView() -> UIView & UIContentView {
if #available(iOS 16.0, *) {
let configuration = UIHostingConfiguration {
content
}
.margins(.all, 0)
return configuration.makeContentView()
} else {
return HostingConfigurationContentView(configuration: self)
}
return HostingConfigurationBackportContentView(configuration: self)
}

public func updated(for state: UIConfigurationState) -> HostingConfiguration<Content> {
public func updated(for state: UIConfigurationState) -> Self {
return self
}
}

@available(iOS 14.0, *)
private class HostingConfigurationContentView<
private class HostingConfigurationBackportContentView<
Content: View
>: HostingView<ModifiedContent<Content, SizeObserver>>, UIContentView {

var configuration: UIContentConfiguration {
didSet {
let configuration = configuration as! HostingConfiguration<Content>
let configuration = configuration as! HostingConfigurationBackport<Content>
content.content = configuration.content
}
}

init(configuration: HostingConfiguration<Content>) {
init(configuration: HostingConfigurationBackport<Content>) {
self.configuration = configuration
super.init(content: configuration.content.modifier(SizeObserver(onChange: { _ in })))
content.modifier.onChange = { [unowned self] newValue in
Expand All @@ -597,7 +620,7 @@ private class HostingConfigurationContentView<
return
}

let kind = (configuration as! HostingConfiguration<Content>).kind
let kind = (configuration as! HostingConfigurationBackport<Content>).kind
let ctx = UICollectionViewLayoutInvalidationContext()
switch kind {
case .supplementary(let kind):
Expand Down

0 comments on commit c504e85

Please sign in to comment.