0
2

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.

if文でmodifierを呼び分けてはいけない

Last updated at Posted at 2023-01-21

概要

を視聴していたら,36:31ぐらいからちょうどタイトルと同じような内容が紹介されていた。パッと理解することができなかったので,まとめてみます。

実例

以下の例を見てみる。

import SwiftUI

struct ContentView: View {
    @State private var isOpacity: Bool = false

    var body: some View {
        VStack {
            if isOpacity {
                ChildView()
                    .opacity(0.3)
            } else {
                ChildView()
            }
            Button("Change Opacity") {
                isOpacity.toggle()
            }
        }
    }
}

struct ChildView: View {
    @State private var isGood: Bool = false

    var body: some View {
        VStack {
            Text(isGood ? "Good" : "Bad")
            Button("Change Goodness") {
                isGood.toggle()
            }
        }
    }
}

ContentViewではopacityを変化させるisOpacityを管理しており,ChildViewでは文言"Good"/"Bad"を変化させるisGoodを管理している。ContentViewでは,opacityを変化させるためにif文を使用している。一見問題なさそうに見えるが,挙動を確かめてみる。

Untitled.gif

挙動が以下のようになっている。

  1. "Change Goodness"ボタンを押して,テキストを"Bad"から"Good"に変更した
  2. "Change Opacity"ボタンを押して,opacityを0.3に変更した
  3. 2でopacityのみ変更したが,テキストも"Good"から"Bad"に変更されている

原因

が非常に参考になった。

SwiftUI destroys and creates the views whenever the condition changes. This process deallocates the destroyed view’s state and uses animation to remove the destroyed view.

より,ContentViewisOpacityが変わった時,ChildViewが再生成されisGoodがデフォルトのfalseとなり,opacityだけではなく,文言も"Good"から"Bad"に変わってしまった。

解決方法

struct ContentView: View {
    @State private var isOpacity: Bool = false
    var body: some View {
        VStack {
            ChildView()
                .opacity(isOpacity ? 0.3 : 1)
            Button("Change Opacity") {
                isOpacity.toggle()
            }
        }
    }
}

上記のように,opacityで指定する値自体をisOpacityで出し分ければ良い。

There is no changes in the view tree when you set the padding to 0 or opacity to 1. SwiftUI understands that and doesn’t apply these view modifiers. That’s why we call them inert view modifiers. Try to use them as much as possible to improve the performance of your view and remove unwanted transitions.

とあるように,opacityで1を指定してもmodifierが適用されないそう。ちなみに inert = 不活性 だそう。

0
2
0

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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?