【问题标题】:How to make a dynamic LazyVGrid of custom WebViews with SwiftUI (macOS)?如何使用 SwiftUI (macOS) 制作自定义 WebView 的动态 LazyVGrid?
【发布时间】:2021-10-27 10:13:24
【问题描述】:

我目前正在开发一个应用程序,该应用程序在单个列中显示不同 SwiftUI 文件的代码。我正在使用多个 WKWebView 实例来显示每个文件(以便于托管 + 内置语法突出显示支持)。 WebView 的大小适合带有填充的容器:

对于一些较大的项目——包含大量文件——我正在尝试实现一个LazyVGrid,它可以并排显示较小的支持文件:

问题

但是,当窗口变小时,我无法让网格调整为单列(如果用户使用的是超宽显示器,我什至无法调整为 3 列;不过,这太多了优先级较低)。 LazyVGrid 是解决此问题的最佳方法,还是我应该采取不同的方法?我觉得我很接近。

GridLayout.swift

struct GridLayout: View {
  let data: [String]
  enum dataType { case title; case url }
  let columns = [GridItem(.flexible()), GridItem(.flexible())]
  
  func get(_ forType: dataType, _ string: String) -> String {
    if forType == .title { return string.components(separatedBy: "*")[0] }
    if forType == .url { return string.components(separatedBy: "*")[1] }
    return ""
  }
  
  var body: some View {
    VStack {
      LazyVGrid(columns: columns) {
        ForEach(data, id: \.self) { i in
          CodeView(title: get(.title, i), height: 500, url: get(.url, i))
          .frame(minWidth: 300, idealWidth: 400, maxWidth: .infinity, alignment: .center)
        }
      }
    }
  }
}

【问题讨论】:

    标签: ios swift macos swiftui wkwebview


    【解决方案1】:

    使用GeometryReader 有多种方法可以做到这一点。这里我使用.flexible() 网格项,但根据父视图的整体宽度改变列数:如果宽度低于 800 像素,则做 1 列;如果宽度在 800 到 1200px 之间,则做 2 列;否则做 3 列。

    var body: some View {
        GeometryReader { geometry in
            let gridItem = GridItem(.flexible())
            var columnCount: Int = {
                switch geometry.size.width {
                case 0..<800:
                    return 1
                case 800..<1200:
                    return 2
                default:
                    return 3
                }
            }()
            
            LazyVGrid(columns: Array(repeating: gridItem,
                                     count: columnCount)) {
                ForEach(1..<5) { _ in
                    Rectangle()
                        .fill(Color.gray)
                        .frame(height: 500)
                }
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      我能够使用来自 r/SwiftUI 的 this reference 使动态 LazyVGrid 正常工作。我无法将网格限制为两列;但是,我已经通过对代码的以下修改获得了动态网格:

      struct DoubleLayout: View {
        ...
      
        private let size: CGFloat = 300  // min width
        
        private var columns: [GridItem] {
          return [
            .init(.adaptive(minimum: size, maximum: .infinity))
          ]
        }
        
        var body: some View {
            LazyVGrid(columns: columns) {
              ForEach(data, id: \.self) { i in
                CodeView(title: get(.title, i), height: 500, url: get(.url, i))
                  .frame(minWidth: 300, idealWidth: 400, maxWidth: .infinity, alignment: .center)
              }
            }
          }
        }
      }
      

      我仍然对如何将布局限制为 2 列感兴趣。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-09
        • 1970-01-01
        • 1970-01-01
        • 2020-10-13
        • 1970-01-01
        • 2022-06-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多