Закрыть жест с эффектом масштаба

Когда я добавляю жест перетаскивания, чтобы отклонить мой «большой вид», он масштабируется до размера жеста, но если он отклоняется, вид переходит к своему исходному масштабу и анимирует вид до «маленького вида».

Вот мой пример кода:`struct TestView: View {@State var showBigView = false

      @Namespace private var animationNameSpace

@State var gestureOffset: CGSize = .zero

var body: some View {
    ZStack {
        if !showBigView {
            Image(systemName: "tshirt")
                .resizable()
                .scaledToFit()
                .foregroundColor(.red)
                .matchedGeometryEffect(id: "circel", in: animationNameSpace)
                .transition(.scale(scale: 1))
                .frame(width: 100, height: 100)
                .onTapGesture {
                    withAnimation {
                        showBigView = true
                    }
                }
        } else {
            Image(systemName: "tshirt")
                .resizable()
                .scaledToFit()
                .foregroundColor(.red)
                .matchedGeometryEffect(id: "circel", in: animationNameSpace)
                .transition(.scale(scale: 1))
                .frame(width: 300, height: 300)
                .scaleEffect(abs(gestureOffset.height / 1000 - 1))
                .gesture(DragGesture().onChanged {
                    guard $0.translation.height > 0 else { return }
                    self.gestureOffset = $0.translation

                    if abs($0.translation.height) > 150 {
                        withAnimation {
                            showBigView = false
                            gestureOffset = .zero
                        }
                    }
                })
        }
    }
}

} `

Он не должен прыгать, когда представление закрывается с определенным масштабным эффектом.

1 ответ

Я считаю, что вы пытаетесь:

  • Покажите изображение футболки в кадре 100 на 100.
  • При нажатии он увеличивается до 300 на 300 кадров с анимацией.
  • Перетаскивание вниз уменьшает изображение. Когда высота перетаскивания превышает 150 точек, изображение сжимается до исходного размера 100 на 100 кадров с анимацией.

Этот подход работает:

      struct TestView: View {
    @State private var isBig = false
    @State private var frame = TestView.smallFrame
    @State private var scale = 1.0
    static private let smallFrame = 100.0
    static private let bigFrame = 300.0
    
    var body: some View {
        Image(systemName: "tshirt")
            .resizable()
            .scaledToFit()
            .frame(width: frame, height: frame)
            .scaleEffect(scale)
            .foregroundColor(.red)
            .onTapGesture {
                if !isBig {
                    withAnimation {
                        frame = TestView.bigFrame
                    }
                    isBig = true
                }
            }
            .gesture(DragGesture().onChanged {
                let dragHeight = $0.translation.height
                if isBig && dragHeight > 0 {
                    if dragHeight >= 150 {
                        frame = TestView.bigFrame * scale
                        scale = 1
                        withAnimation {
                            frame = TestView.smallFrame
                        }
                        isBig = false
                    } else {
                        scale = 1 - (dragHeight / 1000)
                    }
                }
            }.onEnded { _ in
                withAnimation {
                    scale = 1
                }
            })
    }
}

Нет необходимости создавать два отдельных образа и синхронизировать их сmatchedGeometryEffect. Вместо этого вы можете использовать свой@Stateboolean, чтобы контролировать, имеют ли жесты какой-либо эффект.

Другие вопросы по тегам