我對 Swift 完全陌生。我需要遍歷一個陣列,并根據資料是什么,構建一個自定義的樹結構。我會分享我的代碼,但它太笨重,太可怕了,不能在公共場合看到。它甚至不接近作業。所以這里有一些偽代碼:
pass in an array of ScheduleCell models (data for a scheduled tv program) to a SwiftUI View.
Each ScheduleCell contains:
Date of broadcast
Channel
Starttime
Program title, subtitle, etc
in the view body, loop over each ScheduleCell
if ScheduleCell is new day then
display new date
go down one line
end
if ScheduleCell is new channel then
display ScheduleCell.channel but do NOT drop down a line
end
display ScheduleCell.title, also on same line as channel
Keep going on the same horizontal line till you hit the next channel
end
最終效果應該是這樣的:
11-16-2021
CNN News Program 1 News Program 2 News Program 3 Etc.
NBC Late Show Infomercial Barney Miller Rerun. Etc.
11-17-2021
CNN News Program 1 News Program 2 News Program 3 Etc.
NBC Late Show Infomercial Barney Miller Rerun. Etc.
這樣做似乎應該很簡單。我試過設定樹結構,但我在使用 SwiftUI View 協議時遇到了問題。我曾嘗試在視圖主體之外的函式中構建樹結構,但我無法弄清楚如何將該結構放入視圖主體中。
或者,我已經放棄了所有這些,只是試圖通過跟蹤陣列索引在視圖中通過蠻力使其作業,如下所示:
struct ScheduleDisplayView: View {
var schedule: [SchedSlot]
let dfdo = DateFormatter.dateOnly
let dfto = DateFormatter.timeOnly
let chanwidth: CGFloat = 45.0
let fontsize: CGFloat = 10.0
var body: some View {
List {
ForEach(schedule.indices,id:\.self) { idx in
let ssDay: String = dfdo.string(from: schedule[idx].startTime!)
let ssChan: Int32 = schedule[idx].channel!.channelID
if idx == 0 ||
ssDay != dfdo.string(from: schedule[idx-1].startTime!)
{
VStack {
Text(ssDay)
.frame(maxWidth: 200 chanwidth, alignment: .leading)
}
}
HStack {
if idx == 0 ||
ssChan != schedule[idx-1].channel!.channelID
{
VStack {
Text(String(schedule[idx].channel!.channelID))
.frame(maxWidth: chanwidth, alignment: .center)
//.font(.system(size: fontsize))
Text(schedule[idx].channel!.callSign!)
.frame(maxWidth: chanwidth, alignment: .center)
//.font(.system(size: fontsize))
}
}
Text(schedule[idx].program!.title!)
.frame(maxWidth: 200, alignment: .leading)
.border(Color.black)
}
}
}
}
}
But the above approach isn't working because the HStack can't keep the program titles on the same line.
Thanks in advance for any input.
Additional material:
Here's a few random slices of the CoreData entities this is based on:
SchedCell
stationID starttime programID duration endtime isUsed channel program
34916 2021-09-29 19:09:00.000 EP000045050088 PT00H09M 2021-09-29 19:18:00.000 0
12131 2021-09-29 19:15:00.000 EP022222100024 PT00H15M 2021-09-29 19:30:00.000 0
34916 2021-09-29 19:18:00.000 EP000045050208 PT00H09M 2021-09-29 19:27:00.000 0
Program
series programID title subtitle fulldescription genre isUsed
EP00000066 EP000000660001 A Pup Named Scooby-Doo Night of the Living Burger After a quarrel, a burgerlike creature haunts Shaggy and Scooby. Children 0
EP00000066 EP000000660002 A Pup Named Scooby-Doo For Letter or Worse The ghost of a long-dead gangster haunts a TV studio. Children 0
EP00000066 EP000000660003 A Pup Named Scooby-Doo A Bicycle Built for Boo! A green monster steals Shaggy's bike. Children 0
EP00000066 EP000000660004 A Pup Named Scooby-Doo The Baby Sitter From Beyond The baby sitter for Shaggy's little sister appears to be a monster. Children 0
Channel
stationID callSign fullName channelID isUsed
15722 WCIX WCIX 2 0
11345 WCIA WCIA 3 0
11278 WAND WAND 4 0
10685 KSDK KSDK 5 0
10269 HSN Home Shopping Network 6 0
11824 WRSP WRSP 7 0
11069 QVC QVC 8 0
As for code samples of my attempts to build the tree structure outside of the view, I have no working code. It's all just fragments that produced a variety of error messages. Here are the node structures. I'm still working out a routine to assemble them into a working tree, will post that as soon as I have something worth looking at:
class RootNode {
var children: [DayNode] = []
func add(child: DayNode) {
children.append(child)
child.parent = self
}
}
class DayNode {
var parent: RootNode
var date: String
var children: [ChannelNode] = []
init(date: String) {
self.date = date
}
func add(child: ChannelNode) {
children.append(child)
child.parent = self
}
}
class ChannelNode {
var parent: DayNode
var channel: String
var children: [SchedSlot] = []
init(channel: String) {
self.channel = channel
}
func add(child: SchedSlot) {
children.append(child)
//child.parent = self
}
}
uj5u.com熱心網友回復:
正如我在評論中提到的,我認為這更像是一個資料組織/排序問題,而不是 SwiftUI 布局問題。如果您對資料進行了正確的分組和排序,則布局將變得更加簡單(例如,您不必嘗試決定是否因為新通道而斷線)。
在以下示例中,我將大部分代碼用于對資料進行分組和排序。然后,布局本身就比較簡單。
重要的是要注意,為了簡潔起見,我在這里做了一些不安全的事情,比如first!在實際代碼中使用您想要測驗或有意外情況的事情。
struct SchedCell {
var stationID: Int
var startTime: Date
var programID: String
var channel: String
}
func generateSampleCells() -> [SchedCell] {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS"
return [
("2021-09-29 19:09:00.000",34916,"EP000045050088","PT00H09M"),
("2021-09-29 19:09:00.000",34917,"EP000045050088","PT00H09M"),
("2021-09-29 19:15:00.000",12131,"EP022222100024","PT00H15M"),
("2021-09-29 19:18:00.000",34916,"EP000045050208","PT00H09M"),
("2021-09-30 19:09:00.000",34916,"EP000045050088","PT00H09M"),
("2021-09-30 19:15:00.000",12131,"EP022222100024","PT00H15M"),
("2021-09-30 19:18:00.000",34916,"EP000045050208","PT00H09M"),
("2021-09-30 19:15:00.000",12132,"EP022222100024","PT00H15M"),
("2021-09-29 19:09:00.000",4916,"EP000045050088","PT00H09M"),
("2021-09-29 19:09:00.000",4917,"EP000045050088","PT00H09M"),
("2021-09-29 19:15:00.000",2131,"EP022222100024","PT00H15M"),
].map {
SchedCell(stationID: $0.1, startTime: formatter.date(from: $0.0)!, programID: $0.2, channel: $0.3)
}
}
struct ContentView: View {
private var data = generateSampleCells()
private var formatter = DateFormatter()
struct ScheduleDay {
var dateStamp: String
var date : Date
var channels: [ChannelLineup]
}
struct ChannelLineup {
var channelName: String
var programs: [SchedCell]
}
struct DateStampedSchedCell {
var dateStamp: String
var cell: SchedCell
}
var sortedData : [ScheduleDay] {
formatter.dateFormat = "MM-dd-yyyy"
let dateStamped = data
.map { item -> DateStampedSchedCell in
DateStampedSchedCell(dateStamp: formatter.string(from: item.startTime), cell: item)
}
let days = Dictionary(grouping: dateStamped, by: { $0.dateStamp} ).values
let channelMappedDays = days.map { day in
ScheduleDay(dateStamp: day.first!.dateStamp,
date: day.first!.cell.startTime,
channels: Dictionary(grouping: day, by: { $0.cell.channel }).map { ChannelLineup(channelName: $0.key, programs: $0.value.map(\.cell))}
)
}.sorted(by: {a,b in a.date < b.date})
return channelMappedDays
}
var body: some View {
ScrollView(.horizontal) {
ForEach(sortedData, id: \.dateStamp) { day in
VStack(alignment: .leading) {
Text("Day: \(day.dateStamp)")
.bold()
ForEach(day.channels, id: \.channelName) { channel in
HStack {
Text("Channel: \(channel.channelName)")
.foregroundColor(.red)
ForEach(channel.programs, id: \.programID) { program in
Text(program.programID)
}
}
}
}.frame(maxWidth: .infinity, alignment: .leading)
}
}
}
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/359222.html
標籤:arrays swift tree vstack hstack
