首页 > 解决方案 > 如何在父滚动视图之外为视图设置动画

问题描述

我想增加圆角矩形的大小以在点击时填充屏幕,但它位于滚动视图内部。

struct ReviewView : View {
    var ratings: [Rating] = []
    @State var isZoomed = false

    var body: some View {
        return ScrollView {
            HStack {
                ForEach(ratings) { rating in
                    ZStack(alignment: .topLeading) {
                        RoundedRectangle(cornerRadius: 10)
                            .foregroundColor(Color.gray.opacity(0.5))
                            .frame(width: self.isZoomed ? UIScreen.main.bounds.width : 200)
                            .animation(.spring())
                        VStack(alignment: .leading) {
                            Text(String(repeating: "☆", count: 5-rating.rating) + String(repeating: "★", count: rating.rating))
                                .font(.body)
                                .frame(minWidth: 0, maxWidth: 150, maxHeight: 40, alignment: .topLeading)
                                .padding(.top, 5)
                            Text(rating.ratingTitle)
                                .font(.callout).bold()
                                .lineLimit(2)
                                .multilineTextAlignment(.leading)
                                .frame(minWidth: 0, maxWidth: 150, minHeight: 0, maxHeight: 45, alignment: .topLeading)
                            Text(rating.ratingDescription)
                                .font(.footnote)
                                .lineLimit(3)
                                .multilineTextAlignment(.leading)
                                .frame(minWidth: 0, maxWidth: 150, alignment: .topLeading)

                        }.padding(.leading, 10)
                         .padding(.top, 5)
                         .tapAction { self.isZoomed.toggle() }
                    }
                }
                PresentationButton(destination: RatingsView()) {
                    ZStack {
                        RoundedRectangle(cornerRadius: 10)
                            .foregroundColor(Color.gray.opacity(0.5))
                            .frame(width: 100, height: 150)
                        Text("View More")
                    }
                }
            }.padding()
        }
    }
}

我的代码的问题是所有矩形都扩展了。我应该如何获得特定的矩形并将其扩展到滚动视图之外的视图大小?


编辑:

我尝试isZoomed在我的评级结构中添加一个属性,所以它看起来像这样:

struct Rating : Identifiable {
    let id = UUID()
    let ratingTitle, ratingDescription: String
    let rating: Int
    var isZoomed: Bool = false
}

然后我有一系列这样的评级:

let ratingsExample = [Rating(ratingTitle: "Great!", ratingDescription: "example", rating: 4), Rating(ratingTitle: "Bad!", ratingDescription: "example", rating: 1)]

使用上面的数组调用视图:

ReviewView(ratings: ratingsExample)

如何更改isZoomed结构属性的值并使其在更改时再次呈现视图,就像状态一样?这可能吗?


编辑2:

我已经成功地解决了如何只缩放一个矩形。我通过在测试数据中制作idanInt并排序评级来做到这一点,如下所示:

struct Rating : Identifiable {
    let id: Int
    let ratingTitle, ratingDescription: String
    let rating: Int
}

let ratingsExample = [Rating(id: 0, ratingTitle: "Good", ratingDescription: "good example", rating: 5), Rating(id: 1, ratingTitle: "bad", ratingDescription: "bad example", rating: 1)]

在视图中添加了一个状态变量作为布尔数组:

@State var isZoomed: [Bool]

添加了计算当前评分数的函数,将它们添加到Bool数组中false

func isZoomedList(ratings: [Rating]) -> [Bool] {
    var isZoomed: [Bool] = []
    for _ in ratings {
        isZoomed.append(false)
    }
    return isZoomed
}

使用函数调用视图并将其指定为@State可以在视图中更改的视图:

ReviewView(ratings: ratingsExample, isZoomed: isZoomedList(ratings: ratingsExample))

现在.tapAction唯一通过指定更改特定矩形id

.tapAction { self.isZoomed[rating.id].toggle() }

我不确定是否有更好的方法来做到这一点,但它工作得很好。

仍然不起作用的是矩形仍然只在滚动视图中扩展,看起来像这样:

扩展滚动视图

如何在滚动视图之外扩展屏幕?

标签: swiftswiftui

解决方案


每个矩形都独立于它们的抽头。但是您isZoomed对所有矩形都使用了 State var。因此,每当您点击一个矩形时,都会isZoomed切换并且isZoomed所有矩形都使用它,因此它们会相应地更改其框架。解决方案是您需要保留一个isZoomedState var 数组,并更新被点击的特定矩形。这足以扩展唯一的特定矩形。

var ratings: [Int] = [0, 1, 2, 3]
    @State var isZoomed: [Bool] = [false, false, false, false]
    var body: some View {
        ScrollView {
            HStack {
                ForEach(ratings) { rating in
                    ZStack(alignment: .topLeading) {
                        RoundedRectangle(cornerRadius: 10)
                            .foregroundColor(Color.green)
                            .frame(width: self.isZoomed[rating] ? UIScreen.main.bounds.width : 200, height: self.isZoomed[rating] ? UIScreen.main.bounds.height : 150)
                            .edgesIgnoringSafeArea(.all)
                            .animation(.spring())
                        }.tapAction { self.isZoomed[rating].toggle() }
                }
            }.padding()
        }

关于第二个查询,据我所知(如果我错了请纠正我),默认情况下scrollView的框架设置为UIScreen.main.bounds(不忽略安全区域)。您正在扩展作为scrollView frameUIScreen.main.bounds边界线的矩形。


推荐阅读