【SwiftUI】ScrollView や List を snap する


作ってみると、何かがきもい選択肢リストの挙動。

上下の padding 付近が気になります。

 

🧑🏻‍💻 snap する

スクロールしたときの

選択肢のアイテムを

きりのいいところで止まるようにします。

ScrollView を使ったリストの実装に、

.scrollTargetLayout()

.scrollTargetBehavior(.viewAligned)

の2行を追加するだけできっちり止まるようになります。

👉 ScrollTargetBehavior | Apple Developer Documentation hatena-bookmark



計算とかしなくていいです。

便利。

ページングもできるとかすげえ。

👉 [WWDC2023] iOS17におけるScrollViewの新機能  その1 hatena-bookmark
👉 UICollectionView with Snapping and Scaling in Swift | by Satsuki Hashiba | Medium hatena-bookmark

 

🧑🏻‍💻 結果

ScrollView 上下のきわきわがすっきりしました !

しかし、「snap」て難しい英単語ですね。

👉 snapの意味・使い方・読み方|英辞郎 on the WEB hatena-bookmark

「スナップエンドウ」てやつ、

前から気にはなってました。


【SwiftUI】shadow() が内側まで効いて困る - compositingGroup()

こんな表示。


VStack {
  Text("こちらへ")
  Text("▶")
}
.padding()
.background(.yellow)

看板ぽく影を付けます。

.shadow() ですね !

簡単ですね !


VStack {
  Text("こちらへ")
  Text("▶")
}
.padding()
.background(.yellow)
.shadow(color: .black, radius: 2, x: 5, y: 5) // *

...

なんでや !?

VStack だけ効けばいいのに、

内側の文字まで効いてますが。

 

👩🏼‍💻 対応方法

.shadow() の前で、

.compositingGroup()

が良さげです。

Wraps this view in a compositing group.

👉 compositingGroup() | Apple Developer Documentation hatena-bookmark


VStack {
  Text("こちらへ")
  Text("▶")
}
.padding()
.background(.yellow)
.compositingGroup() // *
.shadow(color: .black, radius: 2, x: 5, y: 5)

compositingGroup() の代わりに、

.clipShape(.rect)

.clipped()

でも、内側 Text() への .shadow() の影響を

切り離すことができるようです。

しかし、

なんで .shadow() だけなんやろな。

他は、この方法で影響を切り離すことはできない模様。



そもそもは、文字がなぜかぼやけてる? てのがきっかけでした。


【Xcode】Indexing | Processing files could not complete

これ。

Preview やDerivered data を削除しても、

Build folder をクリーンしても、

Xcode を再起動しても

Index Procccessing Files のまま固まって

Preview のビルドができなくなった場合の対応手順。

1. Open your Project Folder.
2. Find ProjectName.xcodeproj file.
3. Right-Click Copy and Paste to Safe Place.
4. Right-Click Show Package Contents.
5. Find project.xcworkspace file and delete that file.
5. Reopen Your Project and clean and Rebuild.

👉 Xcode stuck on Indexing - Stack Overflow hatena-bookmark

覚えておくのは、

「プロジェクト名」.xcodeproj ファイルを

右クリックから開いて、

project.xcworkspace を捨てる。

とりあえず、これで復旧できます。

スタックの原因自体は、

特定のコードのバグのようなので、

おおまかに位置を特定したら、

最初にコメントアウトしておかないと、

また固まっちゃうので注意です。


【SwiftUI】四角の角を丸くする方法あれこれ

「あれこれ」などと整理できてる感じでタイトル付けてしましましたが。

どう書くべきなんですかね。

いきなり書いてみると、

こんなかんじに私は書きました。


// 1. clipShape()

Text("🐶 Dog")
  .padding()
  .background(.yellow)
  .clipShape(.rect(cornerRadius: 24)) // *
  .padding()
  .background(.white)
  .clipShape(.rect(cornerRadius: 24)) // *

内側と外側の角の違いが気持ちが悪いので

書き換えます。


// 2. containerShape + background()

Text("🐶 Dog")
  .padding()
  .background(.yellow)
  .padding()
  .containerShape(.rect(cornerRadius: 24)) // *
  .background { // *
    RoundedRectangle(cornerRadius: 24)
      .fill(.background)
  }

少しはよくなったか。

あれ、もしかしたら

もっと短くなるか。


// 3. containerShape()

Text("🐶 Dog")
  .padding()
  .background(.yellow)
  .padding()
  .background(.white)
  .containerShape(.rect(cornerRadius: 24)) // *

ん、もしかしたら、

外側のみの記述で入れ子内側にも

角丸を影響できる?


// 4. containerShape() + newsted views

VStack {
  Text("🐱 Cat")
    .padding()
    .background(.orange)
    .padding()
    .background(.white)
  Text("🐭 Mouse")
    .padding()
    .background(.cyan)
    .padding()
    .background(.white)
}
.padding()
.background(.green)
.containerShape(.rect(cornerRadius: 40))

見た目が同じでも、

いろいろ書き方あるようなのですが、

逆に混乱してしまいます。



どう書くべきなんでしょうか。

どう書いていますか。

他にもいろいろありそうです。


【SwiftUI】withAnimation() ↔ .animation()

特に、ざっくり

「あればいいかな」

くらいにアニメーションつけてました。


@State var animate1 = false

Text("😬")
  .font(.system(size: 200))
  .scaleEffect(animate1 ? 0.5 : 1.5)
  .rotationEffect(.degrees(animate1 ? 0 : 360))

  .onAppear {
    withAnimation(.default.repeatForever()) {
      animate1.toggle()
    }
  }

👉 withAnimation(_:_:) | Apple Developer Documentation hatena-bookmark

一方で、よく見かける似たような記述。


@State var animate2 = false

Text("😬")
  .font(.system(size: 200))
  .scaleEffect(animate2 ? 0.5 : 1.5)
  .rotationEffect(.degrees(animate2 ? 0 : 360))

  .animation(
    .default.repeatForever(),
    value: animate2
  )
  .onAppear {
    animate2.toggle()
  }

👉 animation(_:value:) | Apple Developer Documentation hatena-bookmark

どう違うのか並べてみましたが。

一緒ですね。

後者のほうが細かく使えそうな気がしますが、

前者のほうが簡潔です。

 

😃 参考

👉 【SwiftUI】アニメーションの書き方 hatena-bookmark