23
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ビューを非表示にする方法の使い分け(SwiftUI)

Last updated at Posted at 2024-02-20

はじめに

ビューを非表示にする方法はいくつかあり、どれを採用すればいいかの判断に迷うことがあったのでまとめました。

環境

  • OS: macOS Sonoma 14.2.1 (23C71)
  • Swift: 5.9.2

結論

先に結論です。

  • トルツメ 1ifswitch
  • トルママ 2
    • 常に非表示(レイアウトのためだけに配置する) → hidden()
    • 条件によって表示/非表示を切り換える → opacity(condition ? 1 : 0)

検証

簡単なコードで検証しました。

ContentView.swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack(spacing: 16) {
            Text("1")

            if false {
                Text("2") // 非表示
            }

            if true {
                Text("3")
            }

            Text("4")
                .hidden() // 非表示

            Text("5")
                .opacity(true ? 1: 0)

            Text("6")
                .opacity(true ? 0 : 1) // 非表示

            Text("7")
        }
    }
}

上記のコードの実行結果です。

結論に記載した通り、 if で非表示にしたビューはトルツメされ、 hidden()opacity() を付けて非表示にしたビューはトルママされました。

理由

このような結論を出した理由を記載します。

基本的にはすべて hidden() の公式ドキュメントに記載されている通りなので、ぜひご参照ください。

トルツメ

まずトルツメですが、モディファイアでは実現できなさそうなので if で行っています。
frame(height:)0 を指定することも思いつきましたが、非表示にはなりませんでした。

ContentView.swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack(spacing: 16) {
            Text("1")
                .border(.red)

            Text("2")
                .frame(height: true ? 0 : 100)
                .border(.green)

            Text("3")
                .border(.blue)
        }
    }
}

使える場面は限られますが、 let content: (() -> View)? のようにビューを返すオプショナルのクロージャを用意し、 content?() を実行してもトルツメが実現できます。
詳細は以下の記事をご参照ください。

トルママ

次にトルママですが、 hidden() のドキュメントに従っています。
ただ hidden() は表示/非表示を切り替えられないため、 opacity() を使うケースのほうが圧倒的に多いと思います。
私は hidden() を使ったことがありません。

opacity(0) のときはボタンをタップできないので、 hidden()opacity(0) は同様の動作になると思います。

ContentView.swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack(spacing: 16) {
            Text("1")

            Button {
                print("Foo") // `opacity(0)` だとタップしても出力されない
            } label: {
                Text("2")
            }
            .opacity(0)

            Text("3")
        }
    }
}

Button に対する opacity() の値をいろいろ変えて検証した結果をまとめました。

opacity 説明
1 少しでもボタンにかすればタップ判定になる
0.90.1 だんだんタップ領域が狭くなるが、タップがボタンの中央にかすればタップ判定になる
0.01 かするだけではタップ判定にならない。タップの中心がボタンのフレームに入るとタップ判定になる
0.0010 ボタンが完全に見えなくなり、タップもできなくなる

透過度によってタップ領域が変わるのは学びでした。

おわりに

ビューを非表示にする方法の使い分けでした。

個人的には opacity() より hidden() のほうが非表示だとわかりやすいので、表示フラグを渡せる hidden() が欲しいです笑

  1. 取って詰めること。

  2. 取っても詰めずにそのままとすること。

23
15
2

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
23
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?