Как мне зафиксировать нажатие на пользовательский вид карты в ZStack? - PullRequest
0 голосов
/ 16 февраля 2020

Я очень стараюсь воссоздать что-то вроде представления Кошелька, но не могу понять это. Я жестко запрограммировал смещения в своем ZStack, но, конечно, я тоже хочу этого избежать. Похоже, что смещения вообще не позволяют регистрировать отводы. Вот мой код, касание карты должно изменить цвет ее заголовка с белого на желтый.

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

Я использовал это видео в качестве базы, но на самом деле это не go, насколько мне хотелось бы:

https://nsscreencast.com/episodes/399-swiftui-transforms-and-animations

import SwiftUI

struct BetterCards: View {
    var body: some View {

        ScrollView (.vertical) {
                ZStack {
                    CardView(title: "adidas", color: .blue, offset: 0.0)
                    CardView(title: "Le Crueset", color: .pink, offset: 90.0)
                    CardView(title: " Card", color: .black, offset: 180.0)
                    CardView(title: "Sandusk", color: .orange, offset: 270.0)
            }
        }
    }
}


struct CardView: View {

    @State var isYellow: Bool = false

    let title: String
    let color: Color
    let offset: CGFloat

    var body: some View {


        Button(action: {
            self.isYellow.toggle()
        }) {
            ZStack {
                 Rectangle()
                    .fill(color)
                    .cornerRadius(10)
                    .frame(width: 320, height: 210)
                VStack {
                    Text(title)
                        .font(.largeTitle)
                        .bold()
                        .foregroundColor(isYellow ? .yellow : .white)
                        .padding()
                    Spacer()
                }

            }.shadow(radius: 2.0)
            .offset(x: 0, y: offset)

            }.onTapGesture {
            print("Tapped: \(self.title)")
        }
    }
}

struct BetterCards_Previews: PreviewProvider {
    static var previews: some View {
        BetterCards()
    }
}

Ответы [ 3 ]

1 голос
/ 17 февраля 2020

Не думаю, что вам нужны и Button, и onTapGesture в одном представлении. Ваш CardView уже является кнопкой, поэтому он будет регистрировать жесты. Для того, чтобы он функционировал должным образом, я предлагаю вам переместить смещение на самой кнопке. Также похоже, что он будет регистрировать нажатия на все виды, только если он имеет достаточную высоту, поэтому я установил рамку на кнопке после установки смещения. В целом код будет выглядеть примерно так:

import SwiftUI

struct BetterCards: View {
    var body: some View {

        ScrollView (.vertical) {
            ZStack(alignment: .top) {
                CardView(title: "adidas", color: .blue, offset: 0.0)
                CardView(title: "Le Crueset", color: .pink, offset: 90.0)
                CardView(title: " Card", color: .black, offset: 180.0)
                CardView(title: "Sandusk", color: .orange, offset: 270.0)
            }
        .padding()
        }
    }
}


struct CardView: View {

    @State var isYellow: Bool = false

    let title: String
    let color: Color
    let offset: CGFloat

    var body: some View {


        Button(action: {
            self.isYellow.toggle()
            print("Tapped: \(self.title)")
        }) {
            ZStack {
                Rectangle()
                    .fill(color)
                    .cornerRadius(10)
                    .frame(width: 320, height: 210)
                VStack {
                    Text(title)
                        .font(.largeTitle)
                        .bold()
                        .foregroundColor(isYellow ? .yellow : .white)
                        .padding()
                    Spacer()
                }
                .frame(width: 320, height: 210)

            }
            .shadow(radius: 2.0)

        }
        .offset(x: 0, y: offset)
        .frame(width: 320, height: 210 + offset, alignment: .top)
    }

}

Вы можете поиграть с выравниванием и отступами на разных видах, чтобы получить то, что вам нужно.

1 голос
/ 16 февраля 2020

struct ContentView: View {
    var body: some View {

        ScrollView (.vertical) {
            ZStack(alignment: .top) {
                CardView(title: "adidas", color: .blue, paddingOffset: 0)
                CardView(title: "Le Crueset", color: .pink, paddingOffset: 90)
                CardView(title: " Card", color: .black, paddingOffset: 180)
                CardView(title: "Sandusk", color: .orange, paddingOffset: 270)
            }
        }
    }
}


struct CardView: View {

    @State var isYellow: Bool = false

    let title: String
    let color: Color
    var paddingOffset: CGFloat

    var body: some View {
        ZStack {
            Rectangle()
                .fill(color)
            VStack {
                Text(title)
                    .font(.largeTitle)
                    .bold()
                    .foregroundColor(isYellow ? .yellow : .white)
                    .padding()
                Spacer()
            }

        }.shadow(radius: 2.0)
            .cornerRadius(10)
            .frame(width: 320, height: 210)
            .padding(.top, paddingOffset)
            .onTapGesture {
                self.isYellow.toggle()
                print("Tapped: \(self.title)")
        }
    }
}

0 голосов
/ 17 февраля 2020

Спасибо вам обоим, Наталья и Mac3n

Это заставило меня задуматься, и я закончил тем, что использовал VStack

Рад слышать любые комментарии. Я не уверен, что это лучший подход.

Я покончил со смещениями и использовал два кадра в виде карты - один для прямоугольника и один для ZStack. Я все еще пытаюсь выяснить математику для .frame на VStack как бы то ни было. Кажется, это кратное число карт + реальная высота карты плюс некоторая переменная, которую я не могу определить.

import SwiftUI

struct BetterCards: View {

    let multiplier:CGFloat = 6

    var body: some View {

        ScrollView {
            Text("HEADER").background(Color(.blue))
            VStack {
                CardView(title: " Card", color: .black)
                CardView(title: "adidas", color: .blue)
                CardView(title: "Puma", color: .green)
                CardView(title: "Le Crueset", color: .yellow)
//                CardView(title: "adidas", color: .blue)
//                CardView(title: "OnlyLyon", color: .green)
//                CardView(title: "Le Crueset", color: .yellow)
                CardView(title: "adidas", color: .blue)
                CardView(title: "Sandusk", color: .orange)
//                CardView(title: "Le Crueset", color: .pink)
                }
            .frame(width: 400, height: multiplier * 60 + (430 - ( 52 )))
            .padding()
            .background(Color.gray)
            Text("FOOTER").background(Color(.blue))
        }
        .background(Color.yellow)
    }
}

struct CardView: View {

    @State var isYellow: Bool = false

    let title: String
    let color: Color

    var body: some View {
        ZStack {
             Rectangle()
                .fill(color)
                .cornerRadius(10)
                .frame(width: 370, height: 430)
            VStack {
                Text(title)
                    .font(.largeTitle)
                    .bold()
                    .foregroundColor(isYellow ? .yellow : .white)
                    .padding()
                Spacer()
                }
        }
        .frame(width: 370, height: 60)
        .onTapGesture {
                self.isYellow.toggle()
                print("Tapped: \(self.title)")
        }
        .shadow(radius: 2.0)
    }
}

struct BetterCards_Previews: PreviewProvider {
    static var previews: some View {
        BetterCards()
    }
}
...