SwiftUI 列表行布局
Posted
技术标签:
【中文标题】SwiftUI 列表行布局【英文标题】:SwiftUI list row layout 【发布时间】: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 的指针,我需要几天才能找到它! 【参考方案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 项限制时尝试对元素进行分组,但没有帮助。将相应地编辑我的问题...以上是关于SwiftUI 列表行布局的主要内容,如果未能解决你的问题,请参考以下文章