滚动视图和 .sheet

Posted

技术标签:

【中文标题】滚动视图和 .sheet【英文标题】:ScrollView and .sheet 【发布时间】:2020-12-16 02:11:53 【问题描述】:

我有一个带有 ForEach 循环的 ScrollView,每个循环都呈现一个视图。在视图中,我有以下 ActionItem 的 3 个渲染(一个显示工作表的按钮)。 工作表不显示在 ScrollView 中,但显示在 List 中。我通常会将 .sheet 附加到 ScrollView 层,但是,每个按钮呈现不同的视图似乎更适合嵌套它。

我怎样才能让它与 ScrollView 一起工作?我正在使用 Xcode 12

struct ActionItem<Content>: View where Content : View 
    public var text: String
    public var icon: String
    public var content: Content
    @State var isPresented = false
    
    init(text: String, icon: String, @ViewBuilder content: () -> Content) 
        self.text = text
        self.icon = icon
        self.content = content()
    
    
    var body: some View 
        Button (action: 
           DispatchQueue.main.async 
             withAnimation 
               self.isPresented = true
             
            
        ) 
            HStack(spacing: 2) 
                Image(systemName: icon).font(.system(size: 14, weight: .semibold))
                Text(text).fontWeight(.semibold)
                
            .padding([.top, .bottom], Dimensions.spacing)
            .padding([.leading, .trailing], Dimensions.spacingMedium)
        .foregroundColor(Color.gray).font(.subheadline).background(Color.grayWhiteTer)
        .cornerRadius(Dimensions.spacing)
        .sheet(isPresented: $isPresented) 
            self.content
        
    

在视图中,我将渲染 ActionItem,例如 Text,如果视图被忽略并且 ActionItem 直接位于 ForEach 中,也会发生这种情况。同样的问题,工作表没有出现。

ActionItem(text: "", icon: "pencil") 
  Text("ok")

列表如下所示

import SwiftUI

struct ItemsList: View 
  @ObservedObject var itemModel: ItemModel
    
  var body: some View 
    VStack(alignment: .center, spacing: 0) 
      ScrollView 
        VStack 
            ForEach(itemModel.items, id: \.self)  item in
              ItemView(item: item)
            
        .frame(maxWidth: .infinity, maxHeight: .infinity)

建议的回调更新

struct ActionItem<Content>: View where Content : View 
    public var text: String
    public var icon: String
    public var content: () -> Content
    @State var isPresented = false
    
    init(text: String, icon: String, @ViewBuilder content: @escaping () -> Content) 
        self.text = text
        self.icon = icon
        self.content = content
    
    
    var body: some View 
        Button (action: 
            DispatchQueue.main.async 
               withAnimation 
                self.isPresented = true
               
            
            
        ) 
            HStack(spacing: 2) 
                Image(systemName: icon).font(.system(size: 14, weight: .semibold))
                    Text(text).fontWeight(.semibold)
                
            .padding([.top, .bottom], Dimensions.spacing)
            .padding([.leading, .trailing], Dimensions.spacingMedium)
        .foregroundColor(Color.gray).font(.subheadline).background(Color.grayWhiteTer)
        .cornerRadius(Dimensions.spacing)
        .sheet(isPresented: $isPresented) 
            self.content()
        
    

【问题讨论】:

【参考方案1】:

尝试将内容保存为回调(即 () -> 内容)并在 sheet 方法中调用它,而不是在初始化程序中调用它。这将在创建视图时更改。

【讨论】:

感谢您回复@BJB。好像这样不行。我添加了它并将代码放在上面的问题中。我也使用 400 而不是 .infinity 因为 .infinity 导致了一个新错误Thread 1: "CALayer position contains NaN: [nan nan]. Layer: &lt;CALayer:0x60000... 很抱歉,这应该是最大高度和宽度。现在试试吧。 一切都好,刚刚尝试了 maxWidth/maxHeight(清除了上述评论错误)以及异步动画,似乎这些也不起作用。更新了我上面的代码以反映您的建议 也试过了,好像也不行,我把上面的代码放在问题的底部 太棒了!很高兴你明白了.. 如有疑问,请务必检查层次结构!

以上是关于滚动视图和 .sheet的主要内容,如果未能解决你的问题,请参考以下文章

滚动其他滚动视图时滚动视图重置

使用静态和滚动子视图实现视图

滚动视图中不可滚动的表视图

在调整滚动视图大小时滚动到滚动视图页面

视图中的滚动视图和滚动视图中的表格视图;我如何引用它?

滚动视图不在自动布局中滚动子视图