26
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SwiftUI完全に理解した

Last updated at Posted at 2022-11-14

@Yametaro さんメインで定期開催していた #ゆめみからの挑戦状 ですが、今回は私から SwiftUI に関連する問題として出題させていただきました。

問題

import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            Text("SwiftUI\n完全に理解した")
                /* ここに解答を書いてください */
        }
    }
}

どこかで見たような話ですが、SwiftUIの可能性に挑む問題として出題しました。

解答例

顧客が説明した要件

import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            Text("SwiftUI\n完全に理解した")
                // 回答
                .padding()
                .offset(x: 50, y: 0)
                .overlay(
                    RoundedRectangle(cornerRadius: 16)
                        .stroke(Color.black, lineWidth: 2)
                )
        }
    }
}

解説

角丸の枠線

みんな大好き、角丸の枠線です

cornerRadius

枠線(border)に角丸(cornerRadius)をつければいいんだろ、と思ってやってみると失敗します

import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            Text("SwiftUI\n完全に理解した")
                .padding()
                .border(.black, width: 2)
                .cornerRadius(16)
        }
    }
}

プロジェクトリーダーの理解

cornerRadius はviewをclipしますので、枠線をつけたviewが角丸でclipされてしまいます

Clips this view to its bounding frame, with the specified corner radius.

cornerRadiusを使って角丸枠線を書く事もできます

アナリストのデザイン

import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            Text("SwiftUI\n完全に理解した")
                .padding()
                .background(.white)
                .cornerRadius(12)
                .padding(4)
                .background(.black)
                .cornerRadius(16)
        }
    }
}

しかし、この方法で完全に理解してしまうと、はみ出した部分がClipされてしまいますね

実装された運用

overlay

overlay を使うとViewの上に別のViewを重ねる事ができます

今回は組み込み図形の中から RoundedRectangle をのせました

また、 stroke で Shape の輪郭のみ描画をしています

完全に理解する

位置の指定は offset を使います

ちょっと右に寄せてと言われたのでしょうか、その場合はoffsetを付ける位置を変えるとよさそうです

顧客が本当に必要だったもの

import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            Text("SwiftUI\n完全に理解した")
                .padding()
                .overlay(alignment: .trailing) {
                    RoundedRectangle(cornerRadius: 16)
                        .stroke(Color.black, lineWidth: 2)
                }
                .offset(x: 40, y: 0)
        }
    }
}

みんなの解答

正統派

数字に多少ばらつきはありますが、正解ですね

ベジェ曲線

角丸枠線をベジェ曲線で描いてくれました
Pathを使う事で複雑な図形も対応できますね

流行りにのったこちらの解答もいただいています

アニメーション

手作りのアニメーションをつけてくれました

番外編

1. Fake

base64Encodeで画像を読み込んで表示しています

2. Replace

一度、opacity(0)で非表示にしてからHStackColor.clear.frameでずらしています

3. Reframe

fixedSizeでサイズを固定した後にframeを使ってずらしています

色をつけてやるとちょっとわかりやすくなりそうです

image.png

import SwiftUI

@main
struct MyApp: App {

    var body: some Scene {
        WindowGroup {
            Text("SwiftUI\n完全に理解した")
                .fixedSize()
                .background(Color.yellow.opacity(0.7))
                .frame(width: 32)
                .border(Color.red)
                .frame(width: 111, alignment: .trailing)
                .background(Color.blue.opacity(0.7))
                .padding()
                .overlay(alignment: .trailing) {
                    RoundedRectangle(cornerRadius: 16)
                        .stroke(Color.black, lineWidth: 2)
                }
        }
    }
}

4. Realign

alignmentGuideを使って、centerをずらしています

感想

解答ありがとうございました
軽い気持ちで出したお題でしたが、さまざまな解答をいただきました

SwiftUIの自由さや、表現力の高さ、読みやすさなどを感じてもらえたら幸いです
SwiftUIは書いていて楽しいので、皆様もぜひ挑戦してみてください

26
22
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?