@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)
で非表示にしてからHStack
とColor.clear.frame
でずらしています
3. Reframe
fixedSize
でサイズを固定した後にframe
を使ってずらしています
色をつけてやるとちょっとわかりやすくなりそうです
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は書いていて楽しいので、皆様もぜひ挑戦してみてください