【问题标题】:SwiftUI list row layoutSwiftUI 列表行布局
【发布时间】:2020-05-16 08:16:44
【问题描述】:

回到几个 SwiftUI 布局问题:

我正在尝试将 2 个列表与自定义单元格并排显示。 我创建了单元格视图 (EventRow.swift) 并将它们显示在我的内容视图中。

为了更好的可见性,我在列表中添加了边框。

从下图可以看出,结果惨不忍睹:

我希望将渐变效果应用于整个单元格,包括宽度和高度。
我尝试设置 EventRow 的框架(使用 .infinity 作为宽度和高度),但这会使应用程序崩溃。
由于 EventRow 的大小是推断出来的,我也不知道如何调整行单元格的高度以适应它的大小:您可以看到水平分隔条不适合我的自定义 EventRow...

如果有人对此有一些建议,将不胜感激。

示例项目可以在here找到

但我也在下面发布了我的代码:

内容视图:

import SwiftUI

struct ContentView: View {

    struct listsSetup: ViewModifier {
      func body(content: Content) -> some View {
        return content
        .frame(maxHeight: UIScreen.main.bounds.size.height/3)
        .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.blue, lineWidth: 1))
            .padding([.top, .bottom])
        }
    }

    var body: some View {

        VStack {
                HStack {
                    VStack { // 1 list Vstack
                        VStack {
                        Text("List 1")
                            .padding(.top)
                        List {
                            EventRow()
                            EventRow()
                        } // END of 1st List
                        }
                            .modifier(listsSetup())
                    } // END of 1st list VStack

                    VStack { // 2nd Vstack
                        VStack {
                        Text("List 2")
                            .padding(.top)
                        List {
                            EventRow()
                            EventRow()
                        } // END of Landings List
                        }
                        .modifier(listsSetup())
                    } // End of 2nd List VStack
                } // End of 1st & 2nd lists HStack
                    .padding(.top)
                Spacer()
        } // END of VStack
    } // END of body

}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
    ContentView()
    }
}

事件行:

import SwiftUI

struct EventRow: View {

    var body: some View {
        LinearGradient(gradient: Gradient(colors: [Color.white, Color.blue]), startPoint: .top, endPoint: .bottom)
        .edgesIgnoringSafeArea(.all)
        .overlay(
            VStack{
            HStack {
            Text("Text one")
                Spacer()
            Text("Text two")
            }
                HStack {
                    Spacer()
                    Image(systemName: "flame")
                    .font(.body)
                    Spacer()
                } // END of second HStack
                    .padding(.top, -14)
            } //END of Vstack
        )
    }
}

struct EventRow_Previews: PreviewProvider {
    static var previews: some View {
       EventRow().previewLayout(.fixed(width: 300, height: 60))

    }
}

尝试 Asperi 的解决方案后进行编辑:
我实际的 EventRow 代码如下,listRowBackground 修饰符似乎没有任何作用:

import SwiftUI
import CoreData

struct EventRow: View {

    var event: Events

    var dateFormatter: DateFormatter {
     let formatter = DateFormatter()
    // formatter.dateStyle = .long
     formatter.dateFormat = "dd MMM yy"
     return formatter
     }

    var body: some View {
    VStack{
            HStack {
            Text(event.airportName ?? "")
                .font(.headline)
                Spacer()
            Text(self.dateFormatter.string(from: event.eventDate!))
                .font(.body)
            }
                HStack {
                    Text(event.flightNumber ?? "")
                        .font(.body)
                    Spacer()
                    if event.isSimulator {
                        Image(systemName: "s.circle")
                            .font(.body)
                    } else {
                        Image(systemName: "airplane")
                        .font(.body
                        )
                    }
                    Spacer()
                    if event.aircraftType == 0 {
                        Text("")
                        .font(.body)
                    } else if event.aircraftType == 1 {
                        Text("330")
                        .font(.body)
                    } else if event.aircraftType == 2 {
                        Text("350")
                        .font(.body)
                    }
                } // END of second HStack
                    .padding(.top, -14)

        } //END of Vstack
                .listRowBackground(LinearGradient(gradient: Gradient(colors: [Color.white, Color.blue]), startPoint: .top, endPoint: .bottom))

    }
}

struct EventRow_Previews: PreviewProvider {
    static var previews: some View {
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

                let newEvent = Events(context: context)
                newEvent.eventDate = Date()
                newEvent.aircraftType = 1
                newEvent.airportName = "LDG tst"
                newEvent.flightNumber = "AF TEST"
                newEvent.id = UUID()
                newEvent.isLanding = true
                newEvent.isSimulator = false

        return EventRow(event: newEvent).environment(\.managedObjectContext, context)
        .previewLayout(.fixed(width: 300, height: 60))

    }
}

【问题讨论】:

  • 按照假设回答后更改问题是不好的做法。一问一答。错误不会改变行为,它是另一个错误 - 另一个故事。
  • 对那个 Asperi 感到抱歉,但这是我发现发布更多代码的唯一方法。评论部分似乎不适合这样做。由于这个问题与我之前的问题密切相关,我认为跟进比提出新问题要好。
  • 好的,在 ForEach 循环填充我的列表之后,通过应用 .listRowBackround 修饰符 ContentView 使其工作。似乎当列表由循环填充时,将修饰符应用于 EventRow 视图本身不起作用。感谢指向该修饰符@Asari 的指针,我需要几天才能找到它!

标签: swiftui


【解决方案1】:

这是一个使渐变行宽的解决方案

struct EventRow: View {

    var body: some View {
        VStack{
            HStack {
                Text("Text one")
                Spacer()
                Text("Text two")
            }
            HStack {
                Spacer()
                Image(systemName: "flame")
                    .font(.body)
                Spacer()
            } // END of second HStack
                .padding(.top, -14)
        } //END of Vstack
        .listRowBackground(LinearGradient(gradient: Gradient(colors: [Color.white, Color.blue]), startPoint: .top, endPoint: .bottom)
        )
    }
}

【讨论】:

  • Asperi 再次来救援!谢谢,就像一个魅力。有趣的是,contentView 预览仍然显示我的旧布局,但在 sim 或设备上,结果是完美的。
  • 尝试将此应用到我的实际项目中,但它似乎不起作用。我的实际 EventRow 文件从核心数据实体中提取其信息,但我怀疑这是问题所在。当我接近 10 项限制时尝试对元素进行分组,但没有帮助。将相应地编辑我的问题...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-13
  • 1970-01-01
  • 2021-06-03
  • 1970-01-01
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
相关资源
最近更新 更多