эффект swiftui matchedgeometry не является гладким

У меня есть два представления, одно представление имеет отображение списка представлений, каждое из которых содержит изображение и текст. При нажатии на один вид отображается подробный вид, который будет содержать изображение и текст выбранного вида.

Проблема в том,matchedgeometryeffectкажется, исчезает при переходе между представлениями. Я попробовал другое решение здесь, в stackoverflow, например, используя.zIndex()и.transition(.scale(scale: 1))но у меня ничего не получалось.

Вот поведение, которое я получаю в симуляторе: видео

Вот код:

      struct Test: View {
    var body: some View {
    
    VStack {
        if let selectedCard = selectedCard {
            VStack {
                cardView(card: selectedCard)
                    .onTapGesture {
                        withAnimation() {
                            self.selectedCard = nil
                        }
                    }
            }
        } else {
            ScrollView(.horizontal, showsIndicators: false) {
                HStack {
                    ForEach(topCardsAsTemplates) { topCardAsTemplate in
                        TopTemplatesCardView(card: topCardAsTemplate)
                            .padding()
                            .onTapGesture {
                                withAnimation() {
                                    selectedCard = topCardAsTemplate
                                }
                            }
                    }
                }
            }
        }
    }
}

@ViewBuilder
func TopTemplatesCardView(card: Card) -> some View {
    
    if card.uuid != selectedCard?.uuid {
        VStack {
            Image(systemName: "person.circle")
                .resizable()
                .matchedGeometryEffect(id: card.uuid.uuidString + "image", in: namespace)
                .scaledToFit()
                .frame(width: 80)
            
            Text(card.backgroundType.rawValue)
                .matchedGeometryEffect(id: card.uuid.uuidString + "text", in: namespace, properties: .position)
                .foregroundColor(.black)
 //                    .matchedGeometryEffect(id: card.uuid.uuidString + "text", in: namespace)
                                
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 20, style: .continuous)
                .matchedGeometryEffect(id: card.uuid.uuidString + "back", in: namespace)
                .frame(width: cardSize + 50, height: cardSize + 50)
                .background(.clear)
                .foregroundColor(.gray)
        )
        
    } else {
        
        Color.clear.frame(width: cardSize, height: cardSize)
    }
}

    @ViewBuilder
func cardView(card: Card) -> some View {
    
    VStack {
        Image(systemName: "person.circle")
            .resizable()
            .matchedGeometryEffect(id: card.uuid.uuidString + "image", in: namespace)
            .scaledToFit()
            .frame(width: 120)
        
        Text(card.backgroundType.rawValue)
            // .matchedGeometryEffect(id: card.uuid.uuidString + "text", in: namespace)
            .matchedGeometryEffect(id: card.uuid.uuidString + "text", in: namespace, properties: .position)
            .foregroundColor(.black)
    }
    .padding()
    .background(
        RoundedRectangle(cornerRadius: 20, style: .continuous)
            .matchedGeometryEffect(id: card.uuid.uuidString + "back", in: namespace)
            .frame(width: cardSize + 200 , height: cardSize + 200)
            .background(.clear)
            .foregroundColor(.gray)
    )
}
}

Как сделать переход более плавным, чтобы не было видно затухания и появления? Любые предложения, пожалуйста?

Изменить: после долгих проб и ошибок добавление.frame(maxWidth: .infinity, maxHeight: .infinity)кажется, решить проблему для меня. Вот какHStackвыглядит сейчас:

      ScrollView(.horizontal, showsIndicators: false) {
            HStack {
                ForEach(topCardsAsTemplates) { topCardAsTemplate in
                    TopTemplatesCardView(card: topCardAsTemplate)
                        .padding()
                        .onTapGesture {
                            print("display card uuid: \(topCardAsTemplate.uuid.uuidString)")
                            withAnimation(.spring()) {
                                selectedCard = topCardAsTemplate
                            }
                        }
                }
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
        }

Надеюсь, это поможет другим людям.

0 ответов

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