Last active
March 22, 2023 13:47
-
-
Save tatsuz0u/219afa301f54e0d4722d243c34412185 to your computer and use it in GitHub Desktop.
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
// | |
// DividerGroup.swift | |
// BitRemote | |
// | |
// Created by 荒木辰造 on R 5/03/10. | |
// | |
import SwiftUI | |
struct DividerGroup<Content: View>: View { | |
var direction = Direction.horizontal | |
@DividerResultBuilder<Divider> var content: () -> Content | |
var body: some View { | |
switch direction { | |
case .vertical: | |
VStack(content: content) | |
case .horizontal: | |
HStack(content: content) | |
} | |
} | |
} | |
extension DividerGroup { | |
enum Direction { | |
case vertical, horizontal | |
} | |
} | |
extension DividerGroup { | |
@ViewBuilder | |
static func spacer( | |
direction: Direction = .horizontal, | |
@DividerResultBuilder<Spacer> _ content: () -> Content | |
) -> some View { | |
switch direction { | |
case .vertical: | |
VStack(content: content) | |
case .horizontal: | |
HStack(content: content) | |
} | |
} | |
} | |
protocol EmptyInitializable { init() } | |
protocol AppDivider: View, EmptyInitializable {} | |
extension Divider: AppDivider {} | |
extension Spacer: AppDivider { | |
init() { self.init(minLength: nil) } | |
} | |
@resultBuilder | |
struct DividerResultBuilder<Divider: AppDivider> { | |
static func buildOptional<Content: View>(_ content: Content?) -> Content? { content } | |
static func buildPartialBlock<Content: View>(first content: Content) -> Content { content } | |
static func buildPartialBlock<C0: View, C1: View>(accumulated: C0, next: C1) -> TupleView<(C0, Divider, C1)> { | |
.init((accumulated, Divider(), next)) | |
} | |
@ViewBuilder | |
static func buildPartialBlock<C0: View, C1: View>(accumulated: C0, next: C1?) -> some View { | |
if let next { | |
TupleView((accumulated, Divider(), next)) | |
} else { | |
accumulated | |
} | |
} | |
static func buildEither<TrueContent: View, FalseContent: View>(first content: TrueContent) | |
-> ConditionalContent<TrueContent, FalseContent> { .init(content: .first(content)) } | |
static func buildEither<TrueContent: View, FalseContent: View>(second content: FalseContent) | |
-> ConditionalContent<TrueContent, FalseContent> { .init(content: .second(content)) } | |
} | |
enum Either<First, Second> { | |
case first(First), second(Second) | |
} | |
struct ConditionalContent<TrueContent: View, FalseContent: View>: View { | |
let content: Either<TrueContent, FalseContent> | |
var body: some View { | |
switch content { | |
case .first(let first): | |
first | |
case .second(let second): | |
second | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment