swift - 如何在父滚动视图之外为视图设置动画
问题描述
我想增加圆角矩形的大小以在点击时填充屏幕,但它位于滚动视图内部。
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:
我已经成功地解决了如何只缩放一个矩形。我通过在测试数据中制作id
anInt
并排序评级来做到这一点,如下所示:
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() }
我不确定是否有更好的方法来做到这一点,但它工作得很好。
仍然不起作用的是矩形仍然只在滚动视图中扩展,看起来像这样:
如何在滚动视图之外扩展屏幕?
解决方案
每个矩形都独立于它们的抽头。但是您isZoomed
对所有矩形都使用了 State var。因此,每当您点击一个矩形时,都会isZoomed
切换并且isZoomed
所有矩形都使用它,因此它们会相应地更改其框架。解决方案是您需要保留一个isZoomed
State 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
边界线的矩形。
推荐阅读
- java - 对象被覆盖
- javascript - Marionette CollectionViews 有 templateContext 吗?
- excel - 为什么条件格式匹配在工作表中不起作用?
- c++ - 如何在不解码每个键事件的情况下从嵌入式 linux 中的键盘获取文本?
- angular - Ionic v5/Angular 8:HttpClient.get().subscribe() 返回 TypeError:无法读取未定义的属性“句柄”
- php - PHP preg_replace 模式不以“.zip”或“.pdf”或“.txt”结尾
- python - Django:获取所有正在运行的命令列表的方法?
- angular - Angular Table Lazy 从前端加载数据
- c - 收到一条错误消息,指出“运行时检查失败 #2 - 变量 'rejected' 周围的堆栈已损坏。(Visual Studio)
- javascript - 从数据库中删除时如何从文件夹中删除多张照片?