ScrollView 打破 .sheet 表示

Posted

技术标签:

【中文标题】ScrollView 打破 .sheet 表示【英文标题】:ScrollView breaks .sheet representation 【发布时间】:2019-08-18 16:31:55 【问题描述】:

我正在尝试将工作表表示工作嵌套在 ScrollView 内的多个视图中。

没有ScrollView .sheet 修饰符可以正常工作,但是当我将所有内容包装在滚动视图中时,修饰符只会触发一次。所以在第一次点击时,工作表看起来很好,但在关闭它后我无法再次触发它。我不确定这是否是 SwiftUI 本身的错误,或者我是否在这里做某事。

注意:如果我将 .sheet 修饰符添加到 ScrollView 本身,则一切正常。但是对于我的用例,.sheet 修饰符被深深地嵌套在ScrollView 内的自定义视图中。

我正在使用 Xcode Beta 5

没有 ScrollView - 有效

struct SheetWorks: View 
    @State var showSheet = false

    var strings = [
      "Hello", "World", "!"
    ]

    var body: some View 
        HStack 
            ForEach(strings)  string in
                Button(action: self.showSheet.toggle()) 
                    Text(string)
                
                .sheet(isPresented: self.$showSheet) 
                    Text("Here is the sheet")
                
            
        
        .padding()
    

使用 ScrollView - 不起作用

struct SheetDoesntWork: View 
    @State var showSheet = false

    var strings = [
      "Hello", "World", "!"
    ]

    var body: some View 
        ScrollView(.horizontal) 
            HStack 
                ForEach(strings)  string in
                    Button(action: self.showSheet.toggle()) 
                        Text(string)
                    
                    .sheet(isPresented: self.$showSheet) 
                        Text("Here is the sheet")
                    
                
            
            .padding()
        
    

也许有人经历过类似的事情,或者可以为我指明正确的方向。我真的很感激任何帮助。

编辑:这个问题在 Beta 6 中仍然存在

【问题讨论】:

您看到的可能是一个错误。但我只想指出您的代码中的一个错误。由于您将 .sheet() 放入 ForEach 中,因此您有 3 个 .sheet()。这没什么错,除了它们都共享相同的 showSheet 变量。因此,当您将其切换为 true 时,您将同时呈现三张纸...... .sheet() 可以附加到任何东西。我将我的床单从可滚动中移出并将它们附加到隐藏的Text()。好吧,实际上每个隐藏的Text(),你不能有一张又一张的。 我认为这是一个错误。即使您将 Button 移到 ForEach 之外并手动创建三个按钮,问题仍然存在。即使您使用一组布尔值作为 State 而不是所有按钮的一个布尔值,问题仍然存在。 @kontiki 你是对的,我不应该在 ForEach 内附上工作表。 我还认为这是一个错误,因为工作表第一次工作,然后就坏了。希望这会得到解决 【参考方案1】:

在这里看看我的回答:https://***.com/a/57259687/554203

基本上,您应该在循环外只使用一个.sheet,并根据本地变量动态打开所需的视图。

var covers = coverData
var selectedTag = 0

Group 
   ForEach(covers)  item in
      Button(action:  
         self.selectedTag = item.tag
         self.isPresented.toggle() 
      ) 
        CoverAttributes(
           title: item.title,
           alternativeTitle: alternativeTitle,
           tapForMore: item.tapForMore,
           color: item.color,
           shadowColor: item.shadowColor)
      
   

.sheet(isPresented: self.$isPresented, content:  
    Text("Destination View \(self.selectedTag)") 
    // Here you could use a switch statement on selectedTag if you want
)

【讨论】:

您 100% 正确,我应该在 ForEach 之外应用我的 sheet 修饰符。但不幸的是,这并不能解决问题,并且该工作表仅呈现一次 如果您将.sheet“附加”到滚动外部的视图?它对我来说很好用。 没错,但由于工作表最初更多地嵌套在滚动视图中,在多个其他视图结构中,将工作表放在顶层视图中似乎很奇怪。这就是为什么我也认为这是一个错误 此外,工作表的演示第一次工作但失败后的事实对我来说似乎不是很可靠。如果在某种意义上它不是“允许”的,它也应该第一次失败【参考方案2】:

Xcode 11.1 GM Seed 开始,我可以确认.sheet 修饰符现在可以在ScrollView 中正常工作。此外,现在还可以正确渲染多行 Text

【讨论】:

看来我现在有这个错误 - XCode 12. ScrollView ForEach(items) View() 在视图中,我有一个与它关联的工作表的视图。如果我将 ScrollView 更改为 List 工作表呈现,否则不会。

以上是关于ScrollView 打破 .sheet 表示的主要内容,如果未能解决你的问题,请参考以下文章

滚动视图和 .sheet

ScrollView

scrollView 中scrollView 的水平滚动 - 小问题

ScrollView 滚动到底部问题

使用 Scrollview 滚动的背景

Harmony OS — ScrollView滑动视图