LoginSignup
2
2

More than 1 year has passed since last update.

SwiftUI:Viewの.clipped()領域外はタップできなくする方法(とてもシンプル!)

Last updated at Posted at 2022-12-10

SwiftUIでViewの表示領域を限定する際に、.clipped()モディファイアはとても便利である.
しかし....clipped()を使って画像のドラッグ移動などを実装する時、例えば.offset()などで画像表示位置を変更した場合、下記の図の様にclippedで非表示領域もタップが有効なままなので、下層のView(ボタンとか)がタップできなくなくなってしまう.
別に気にならないケースもあるでしょうけど、この例みたいに別のタップしたいアクションがあるとちょっと困るのだ.
aboutClipped.jpg

そこで、シンプルな解決法がこれ.

.contentShape(Rectangle()) 

このモディファイアを1行追加するだけで問題は解消するのである.
例)画像をドラッグ移動するサンプル↓

Sample_for_contentShape
import SwiftUI

struct ContentView: View {
    @State var offset:CGSize = .zero      // drag value
    @State var lastOffset: CGSize = .zero // hold last drag value
    
    var dragGesture: some Gesture { // Gesture for Drag to move
        DragGesture()
            .onChanged {
                offset = CGSize(width: lastOffset.width + $0.translation.width, height: lastOffset.height + $0.translation.height) }
            .onEnded{ _ in
                lastOffset = offset }
    }
    
    var body: some View {
        VStack {
            Button(action: { // Reset drag
                offset = .zero
                lastOffset = .zero
            }){ Text("Reset") }
            
            Image("bluesky") // 背景の青空画像
                .resizable()
                .scaledToFit()
                .overlay(
                    Image("strawberry") // 苺の画像:切り抜きで背景透過
                        .resizable()
                        .scaledToFit()
                        .offset(offset)
                        .gesture(dragGesture)
                )
                .frame(width: 300)
                .clipped()
                .contentShape(Rectangle()) // *** これを追加すれば解決! ***
        }
    }
}

この解法はネット検索しても意外に僅かしか出てこなかったので、ここに掲載.

環境情報:
Xcode 14.3, Swift 5.8

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