Open8

【SwiftUI】light/darkモードそれぞれの色を表示してくれるViewを作る

MM

じゃあShapeで直角三角形を作る。
直角部分の位置を変えられるように実装した。

struct RightTriangle: Shape {

    enum RightAngle: CaseIterable {
        case topLeft, topRight, bottomLeft, bottomRight

        var transform: CGAffineTransform {
            switch self {
            case .topLeft: return .identity
            case .topRight: return .init(scaleX: -1, y: 1)
            case .bottomLeft: return .init(scaleX: 1, y: -1)
            case .bottomRight: return .init(scaleX: -1, y: -1)
            }
        }

        func offset(from rect: CGRect) -> CGPoint {
            let size = rect.size
            switch self {
            case .topLeft: return .zero
            case .topRight: return .init(x: -size.width, y: 0)
            case .bottomLeft: return .init(x: 0, y: -size.height)
            case .bottomRight: return .init(x: -size.width, y: -size.height)
            }
        }
    }

    var rightAngle: RightAngle = .topLeft

    func path(in rect: CGRect) -> Path {
        var path = CGMutablePath()
        path.move(to: .zero)
        path.addLine(to: .init(x: rect.maxX, y: 0))
        path.addLine(to: .init(x: 0, y: rect.maxY))
        path.addLine(to: .zero)

        let offset = rightAngle.offset(from: rect)
        var transform = rightAngle.transform
            .translatedBy(x: offset.x, y: offset.y)

        if let flippedPath = path.mutableCopy(using: &transform) {
            path = flippedPath
        }

        return Path(path)
    }
}
MM

transformで反転する処理をしているが、これはSwiftUIのPathでは出来なさそうだったので、CGPathを経由して定義している。

MM

これを利用して目的の色表示部分を作る。

ZStack {
    colors
        .clipShape(RightTriangle(rightAngle: .topLeft))
        .colorScheme(.light)
    colors
        .clipShape(RightTriangle(rightAngle: .bottomRight))
        .colorScheme(.dark)
}
.frame(width: 140)
MM

clipShape で直角三角形の形を適用している。

MM

colorSchemeで、light/darkモードのどちらの色を使用するか指定している。
これはdeprecatedになっていて、新しくpreferredColorSchemeというAPIが用意されているのだが、こちらを使用すると、全体に指定したlight/darkモードが適用されてしまい、うまく動かなかった.
(Bugかも?)

MM

SwiftUIのデフォルトで定義されているColorって、少なすぎるよね。
かといってUIColor/NSColorからの変換をしてると、せっかくマルチプラットフォームで使えるSwiftUIなのになんか嫌。

そんなあなたに
https://github.com/p-x9/SwiftUIColor

UIColor/NSColorに定義されている色をSwiftUI.Colorでも使用できるようにしました。
OSは関係なくmacOSからiOSの色を参照することもできます。

今回の記事は、↑の作成中に生まれました。
スター好きです。