SwiftUIである円の円周上に別の円の中心を持ってきたい時はPreferenceKeyなしでも実装できそう

www.youtube.com

見た、良かった。自分もやっていかねばという気持ちになった。

本筋ではないが、スライドの36PでSwiftUIのViewの実装事例が紹介されている。

speakerdeck.com

PreferenceKeyと算数で実装したケースだったが、overlayのalignmentを.topTrailingから.centerに変えると、PreferenceKeyなしで実装できそうだった。

開発環境

$ xcodebuild -version
Xcode 14.3
Build version 14E222b

スクリーンショット

コード

import SwiftUI

struct ContentView: View {
    private let iconWidth: CGFloat = 100
    
    private var badgeOffset: CGFloat {
        let iconRadius: CGFloat = iconWidth / 2
        // y=x, x^2+y^2=r^2
        return sqrt(iconRadius * iconRadius / 2)
    }
    
    var body: some View {
        Circle()
            .fill(.red)
            .frame(width: iconWidth, height: iconWidth)
            .overlay(
                badge
                    .offset(x: badgeOffset, y: -badgeOffset),
                alignment: .center
            )
    }
    
    private var badge: some View {
        Text("3")
            .foregroundColor(.white)
            .padding(10)
            .background(
                Circle()
                    .fill(.blue)
            )
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        VStack(spacing: 36) {
            ContentView()
                .dynamicTypeSize(.xSmall)
            ContentView()
                .dynamicTypeSize(.medium)
            ContentView()
                .dynamicTypeSize(.xxxLarge)
        }
    }
}

もしかしたら何か要因があってalignmentを.topTrailingにせざるをえなかったのかもしれない。SwiftUIの練習になって良かった。