swiftui - 为什么初始化列表的滚动位置?
问题描述
单击按钮时,将出现半透明视图。
但是,此时,存在列表的滚动位置被初始化的问题。
下面是我的 SwiftUI 代码。
import SwiftUI
struct ContentView: View {
@State var isButtonClicked: Bool = false
var body: some View {
ZStack {
// Layer 0
TabView {
tableView()
.tabItem { Text("Tab Label 1") }
.tag(1)
Text("Tab Content 2")
.tabItem { Text("Tab Label 2") }
.tag(2)
}
// Layer 1
VStack {
Spacer()
HStack {
Spacer()
Button(action: {
isButtonClicked.toggle()
}, label: {
Text("Button")
})
}
.padding(.trailing, 20.0)
}
.padding(.bottom, 60.0)
// Layer 2
TranslucentView(opacity: 0.6)
.opacity(isButtonClicked ? 1.0 : 0)
.onTapGesture {
isButtonClicked.toggle()
}
.animation(.linear(duration: 0.3))
}
}
}
struct TranslucentView: View {
let opacity: Double
var body: some View {
ZStack {
Color.black
.opacity(opacity)
}
.edgesIgnoringSafeArea(.all)
}
}
struct tableView: View {
let items = [
Item(name: "Apple", counts: 1),
Item(name: "Apple", counts: 3),
Item(name: "Apple", counts: 5),
Item(name: "Apple", counts: 2),
Item(name: "Apple", counts: 9),
Item(name: "Apple", counts: 4),
Item(name: "Apple", counts: 7),
Item(name: "Apple", counts: 2),
Item(name: "Apple", counts: 1),
Item(name: "Apple", counts: 3),
Item(name: "Apple", counts: 8),
Item(name: "Apple", counts: 1),
]
var body: some View {
List(items) { item in
VStack {
Text(item.name)
Text(String(item.counts))
}
}
}
}
class Item: Identifiable {
let id = UUID()
let name: String
let counts: Int
init(name: String, counts: Int) {
self.name = name
self.counts = counts
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我该如何解决这个问题?
*透明视图必须覆盖整个屏幕,包括标签栏。
解决方案
在状态改变时body
重建,所以tableView
重新创建,所以重新初始化。为了避免最后我们需要使视图相等,因此渲染引擎不会在外部更改时重新创建它。
这是一个解决方案(使用 Xcode 12.1 / iOS 14.1 测试)
TabView {
EquatableView(content: tableView()) // << here !!
.tabItem { Text("Tab Label 1") }
.tag(1)
Text("Tab Content 2")
.tabItem { Text("Tab Label 2") }
.tag(2)
}
tableView
并符合Equatable
如下
struct tableView: View, Equatable {
static func == (lhs: tableView, rhs: tableView) -> Bool {
true
}
let items = [
// ... other code
推荐阅读
- php - 由于提供的动态值,我无法从数据库中获取数据
- java - 如何使用命令“ant run”解决“[javac] 错误:无效目标版本:12.0.1”
- android - 如何在空活动中添加工具栏?
- spring-boot - 如何将 Google Cloud Starters 添加到 JHipster?
- vb.net - 滚动时 vb.net 图表烛台被切成两半
- html - 如果我的个人 MediaWiki 网站中不存在此类文章,则将用户重定向到希伯来语维基百科
- java - Hamcrest:异常信息不清楚?
- jquery - event.preventDefault() 在点击时不起作用
- java - 如何为返回 IOException 的 ObjectMapper.writeValueAsString(object) 编写单元测试
- python - 创建一个识别对象类型并根据对象类型传递表单的函数