-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
566ace8
commit a50ccdb
Showing
19 changed files
with
429 additions
and
114 deletions.
There are no files selected for viewing
67 changes: 67 additions & 0 deletions
67
.swiftpm/xcode/xcshareddata/xcschemes/Turbocharger.xcscheme
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Scheme | ||
LastUpgradeVersion = "1410" | ||
version = "1.3"> | ||
<BuildAction | ||
parallelizeBuildables = "YES" | ||
buildImplicitDependencies = "YES"> | ||
<BuildActionEntries> | ||
<BuildActionEntry | ||
buildForTesting = "YES" | ||
buildForRunning = "YES" | ||
buildForProfiling = "YES" | ||
buildForArchiving = "YES" | ||
buildForAnalyzing = "YES"> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "Turbocharger" | ||
BuildableName = "Turbocharger" | ||
BlueprintName = "Turbocharger" | ||
ReferencedContainer = "container:"> | ||
</BuildableReference> | ||
</BuildActionEntry> | ||
</BuildActionEntries> | ||
</BuildAction> | ||
<TestAction | ||
buildConfiguration = "Debug" | ||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
shouldUseLaunchSchemeArgsEnv = "YES"> | ||
<Testables> | ||
</Testables> | ||
</TestAction> | ||
<LaunchAction | ||
buildConfiguration = "Debug" | ||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
launchStyle = "0" | ||
useCustomWorkingDirectory = "NO" | ||
ignoresPersistentStateOnLaunch = "NO" | ||
debugDocumentVersioning = "YES" | ||
debugServiceExtension = "internal" | ||
allowLocationSimulation = "YES"> | ||
</LaunchAction> | ||
<ProfileAction | ||
buildConfiguration = "Release" | ||
shouldUseLaunchSchemeArgsEnv = "YES" | ||
savedToolIdentifier = "" | ||
useCustomWorkingDirectory = "NO" | ||
debugDocumentVersioning = "YES"> | ||
<MacroExpansion> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "Turbocharger" | ||
BuildableName = "Turbocharger" | ||
BlueprintName = "Turbocharger" | ||
ReferencedContainer = "container:"> | ||
</BuildableReference> | ||
</MacroExpansion> | ||
</ProfileAction> | ||
<AnalyzeAction | ||
buildConfiguration = "Debug"> | ||
</AnalyzeAction> | ||
<ArchiveAction | ||
buildConfiguration = "Release" | ||
revealArchiveInOrganizer = "YES"> | ||
</ArchiveAction> | ||
</Scheme> |
103 changes: 103 additions & 0 deletions
103
Sources/Turbocharger/Sources/Alignment/VariadicAlignmentID.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// | ||
// Copyright (c) Nathan Tannar | ||
// | ||
|
||
import SwiftUI | ||
|
||
/// An `AlignmentID` that is resolved from multiple values | ||
/// | ||
/// > Tip: Use ``VariadicAlignmentID`` to create alignments | ||
/// similar to `.firstTextBaseline` | ||
public protocol VariadicAlignmentID: AlignmentID { | ||
static func reduce(value: inout CGFloat?, n: Int, nextValue: CGFloat) | ||
} | ||
|
||
private struct DefaultAlignmentID: AlignmentID { | ||
static func defaultValue(in context: ViewDimensions) -> CGFloat { 0 } | ||
} | ||
|
||
extension VariadicAlignmentID { | ||
public static func reduce(value: inout CGFloat?, n: Int, nextValue: CGFloat) { | ||
DefaultAlignmentID._combineExplicit(childValue: nextValue, n, into: &value) | ||
} | ||
|
||
public static func _combineExplicit( | ||
childValue: CGFloat, | ||
_ n: Int, | ||
into parentValue: inout CGFloat? | ||
) { | ||
reduce(value: &parentValue, n: n, nextValue: childValue) | ||
} | ||
} | ||
|
||
extension View { | ||
|
||
/// A modifier that transforms a vertical alignment to another | ||
@inlinable | ||
public func alignmentGuide( | ||
_ g: VerticalAlignment, | ||
value: VerticalAlignment | ||
) -> some View { | ||
alignmentGuide(g) { $0[value] } | ||
} | ||
|
||
/// A modifier that transforms a horizontal alignment to another | ||
@inlinable | ||
public func alignmentGuide( | ||
_ g: HorizontalAlignment, | ||
value: HorizontalAlignment | ||
) -> some View { | ||
alignmentGuide(g) { $0[value] } | ||
} | ||
} | ||
|
||
// MARK: - Previews | ||
|
||
struct SecondTextBaseline: VariadicAlignmentID { | ||
static func defaultValue(in context: ViewDimensions) -> CGFloat { | ||
context[.firstTextBaseline] | ||
} | ||
|
||
static func reduce(value: inout CGFloat?, n: Int, nextValue: CGFloat) { | ||
if n == 1 { | ||
value = nextValue | ||
} | ||
} | ||
} | ||
|
||
extension VerticalAlignment { | ||
static let secondTextBaseline = VerticalAlignment(SecondTextBaseline.self) | ||
} | ||
|
||
struct VariadicAlignmentID_Previews: PreviewProvider { | ||
static var previews: some View { | ||
VStack(spacing: 48) { | ||
HStack(alignment: .firstTextBaseline) { | ||
Text("Label") | ||
|
||
VStack(alignment: .trailing) { | ||
Text("One") | ||
Text("Two") | ||
Text("Three") | ||
} | ||
.font(.title) | ||
} | ||
|
||
HStack(alignment: .secondTextBaseline) { | ||
Text("Label") | ||
|
||
VStack(alignment: .trailing) { | ||
Group { | ||
Text("One") | ||
Text("Two") | ||
Text("Three") | ||
} | ||
.alignmentGuide(.secondTextBaseline) { d in | ||
d[VerticalAlignment.firstTextBaseline] | ||
} | ||
} | ||
.font(.title) | ||
} | ||
} | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
Sources/Turbocharger/Sources/DynamicProperty/OptionalObservedObject.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// | ||
// Copyright (c) Nathan Tannar | ||
// | ||
|
||
import SwiftUI | ||
import Combine | ||
|
||
/// A property wrapper that subscribes to an optional observable | ||
/// object and invalidates a view whenever the observable object changes. | ||
@propertyWrapper | ||
@frozen | ||
public struct OptionalObservedObject<ObjectType: ObservableObject>: DynamicProperty { | ||
|
||
@usableFromInline | ||
class Storage: ObservableObject { | ||
weak var value: ObjectType? { | ||
didSet { | ||
if oldValue !== value { | ||
value.map { bind(to: $0) } | ||
objectWillChange.send() | ||
} | ||
} | ||
} | ||
|
||
var cancellable: AnyCancellable? | ||
|
||
@usableFromInline | ||
init(value: ObjectType?) { | ||
self.value = value | ||
value.map { bind(to: $0) } | ||
} | ||
|
||
func bind(to object: ObjectType) { | ||
cancellable = object.objectWillChange | ||
.sink { [unowned self] _ in | ||
self.objectWillChange.send() | ||
} | ||
} | ||
} | ||
|
||
@usableFromInline | ||
var storage: ObservedObject<Storage> | ||
|
||
@inlinable | ||
public init(wrappedValue: ObjectType?) { | ||
storage = ObservedObject<Storage>(wrappedValue: Storage(value: wrappedValue)) | ||
} | ||
|
||
public var wrappedValue: ObjectType? { | ||
get { storage.wrappedValue.value } | ||
nonmutating set { storage.wrappedValue.value = newValue } | ||
} | ||
|
||
public var projectedValue: Binding<ObjectType?> { | ||
storage.projectedValue.value | ||
} | ||
} |
Oops, something went wrong.