SwiftUI:如何在动态列表或 LazyVStack 中获取视图框架

Posted

技术标签:

【中文标题】SwiftUI:如何在动态列表或 LazyVStack 中获取视图框架【英文标题】:SwiftUI: How can I get the frame of a view in a dynamic List or LazyVStack 【发布时间】:2021-04-24 11:06:09 【问题描述】:

我想在 LazyVStack 中获取视图的框架。嵌入在 ScrollView 中的 LazyVStack 显示聊天消息(文本和图像)。

由于内容是动态大小的,我无法使用 GeometryReader 代理。将 GeometryReader 放入我的 LazyVStack 会破坏布局。 (我假设是因为动态大小。)。

还有其他方法可以获取 LazyVStack 中的视图框架吗?

下面是我想要做的简单表示。理想情况下,我希望在 MessageView 中有一个 GeometryReader,但这会弄乱垂直间距。

struct ChatView: View 
    var body: some View 
        GeometryReader  geometry in
            ScrollView 
                LazyVStack 
                    ForEach(messages, id: \.id)  message in
                        MessageView(message: message)
                    
                
            
        
    


struct MessageView: View 
    
    var message: Message
    
    var body: some View 
        // GeometryReader here is not possible with dynamic row heights
        if message.text != nil 
            Text(message.text!)
         else if message.imageData != nil 
            Image(uiImage: UIImage(data: message.imageData!))  // <-- Get frame of this Image
        
    

将 MessageView 合并到 ChatView 是不可取的,因为 MessageView 涉及很多视图,需要是一个独立的结构。

【问题讨论】:

【参考方案1】:

您需要在要测量的框架的视图背景中使用GeometryReader,例如

var body: some View 
    if message.text != nil 
        Text(message.text!)
     else if message.imageData != nil 
        Image(uiImage: UIImage(data: message.imageData!))
          .background(GeometryReader  gp in
             // gp.frame(in: .global)   // << eg. frame in global coordinates
          )
    

另见https://***.com/a/62466397/12299030

【讨论】:

我正在尝试使用这个框架,但我得到 Type '()' cannot conform to 'View';当我尝试在闭包中保存或打印框架时,只有 struct/enum/class 类型可以符合协议。这是有希望的,但是当我说我点击图像时,如何从闭包中分配该帧 我最终在背景块中放置了一个 Color.clear 视图,并在其上附加了一个 .onReceive,它接收按钮推送并将框架保存到 viewModel。谢谢。

以上是关于SwiftUI:如何在动态列表或 LazyVStack 中获取视图框架的主要内容,如果未能解决你的问题,请参考以下文章

@FetchRequest 中的 SwiftUI 和动态 NSSortDescriptors

如何在 SwiftUI 或无限列表视图中实现列表分页?

如何在 SwiftUI 中动态推送视图或呈现视图?

SwiftUI:如何更新由一组静态数据驱动的列表并从另一组动态数据中提取信息位?

在 SwiftUI 中动态更新列表?

如何让 SwiftUI 列表删除按钮工作? (或消失)