Post

Replies

Boosts

Views

Activity

Problem with alignment guides
I am creating a user interface for a working program. I am able to lay things out with offsets but am trying as a learning experience to do the same with alignment guides. For the section heading labeled "Group 1" I am able to get the layout I want. What I cannot get to work are alignment guides for the associated rounded rectangle. It appears that the alignment guides with the rounded rectangle only affect the contents i.e. the text "Data Table". Below is a picture of the code output and the code. How, using alignment guides, can move the top rounded rectangle? To keep the picture small I just copied the left side of the output window. The top rounded rectangle is approximately centered in this window. struct ContentView: View { var body: some View { NavigationStack { Text("Group1") .font(Font.custom("Arial", size: 16)) .alignmentGuide(HorizontalAlignment.center, computeValue: { d in print("\(d[HorizontalAlignment.leading])") // print leading = 0.0 // print center = 27 // print trailing = 54 return d[HorizontalAlignment.leading] + 255 }) ZStack (alignment: Alignment(horizontal: .center, vertical: .center)) { RoundedRectangle(cornerRadius: 10) .fill(.white) .alignmentGuide(HorizontalAlignment.center, computeValue: { d in return d[HorizontalAlignment.leading] + 45 }) VStack (alignment: HorizontalAlignment.leading) { NavigationLink(value: "Table1") { Text("Data Table") } .font(Font.custom("Arial", size: 14)) .buttonStyle(.link) .underline() .focusable(false) } // end vstack } // end zStack .frame(width: 200, height: 60) Text("Group2") .font(Font.custom("Arial", size: 16)) .frame(width: 600, height: 20, alignment: .leading) .padding(.leading, 35) .padding(.top, 20) .offset(x: 30) ZStack { RoundedRectangle(cornerSize: CGSize(width: 200, height: 60)) .stroke(Color(.clear), lineWidth: 1) .frame(width: 200, height: 60, alignment: .leading) .background(.white) .cornerRadius(10) .offset(x: -160) VStack () { NavigationLink(value: "Table2") { Text("Data Table") } .font(Font.custom("Arial", size: 14)) .buttonStyle(.link) .underline() .padding(.leading, 8) .frame(width: 200, height: 20, alignment: .leading) .offset(x: -160) .focusable(false) } } Text("Group3") .font(Font.custom("Arial", size: 16)) .frame(width: 600, height: 20, alignment: .leading) .padding(.leading, 35) .padding(.top, 20) .offset(x: 30) ZStack { RoundedRectangle(cornerSize: CGSize(width: 200, height: 60)) .stroke(Color(.clear), lineWidth: 1) .frame(width: 200, height: 60, alignment: .leading) .background(.white) .cornerRadius(10) .offset(x: -160) VStack () { NavigationLink(value: "Table3") { Text("Data Table") } .font(Font.custom("Arial", size: 14)) .buttonStyle(.link) .underline() .padding(.leading, 8) .frame(width: 200, height: 20, alignment: .leading) .offset(x: -160) .focusable(false) } } .padding(.bottom, 20) .navigationDestination(for: String.self) { command in switch command { case "Table1": HStack { CustomTableView(fundName: "Table1", numYears: 1) .frame(width: 320, height: 345, alignment: .center) .padding(.leading, 120) .padding(.trailing, 160) } case "Table2": HStack { CustomTableView(fundName: "Table2", numYears: 1) .frame(width: 320, height: 345, alignment: .center) .padding(.leading, 120) .padding(.trailing, 160) } case "Table3": HStack { CustomTableView(fundName: "Table3", numYears: 1) .frame(width: 320, height: 345, alignment: .center) .padding(.leading, 120) .padding(.trailing, 160) } default: let _ = print("problem in main view switch statement") } // end switch } // end navigation destination } .frame(width: 600, height: 400, alignment: .trailing) } }
1
0
1.1k
Sep ’23
Is it possible to call openWindow() in a navigationDestination in a NavigationStack?
I have a program that uses 3 different windows, each in their own window group. In a button I can use openWindow() to call another window and it works perfectly. I watched the video at the link below and now am trying to convert my program to use a navigation stack instead of buttons. I got things to work using the code listed at the link with a few changes but am unable to get the navigation destination to use openWindow. I attempted to create a view builder but could not get it to work. After some additional research I am starting to think that the navigation destination expects to use the same window as the root view not a separate window/view and therefore, navigation destination wants just a view. But I am unsure. If someone could provide some guidance it would be appreciated. https://developer.apple.com/videos/play/wwdc2022/10054/ struct ContentView: View { @Environment (\.openWindow) private var openWindow @StateObject private var dataModel = DataModel() var body: some View { VStack(alignment: .center) { NavigationStack() { List(Sections.allCases) { section in Section(section.localizedName) { ForEach(dataModel.stocks(in: section)) { stock in NavigationLink(stock.listingName, value: stock) .font(Font.custom("Arial", size: 16)) } } // end section } // end list .scrollContentBackground(.hidden) .background(Color.mint) .navigationTitle("Stocks") .navigationDestination(for: StockData.self) { stock in Text("\(stock.listingName) - \(stock.name)") // GenericTableView(content: openWindow(id: "table", value: stock.name)) // Cannot convert value of type '()' to expected argument type '() -> ContentView' } } // end navigation stack } // end v stack } } struct GenericTableView<Content:View>: View { let content: Content init(@ViewBuilder content: () -> Content) { self.content = content() } var body: some View { content } }
1
0
730
Oct ’23
Create Spreadsheet Like Grid with SwiftUI
I have some test code in which I am attempting to create a spreadsheet style grid with data. The code creates a grid but I am unable to get the bottom border of one row to overlap the top border of the row below it but I can get it to work left to right with padding using a negative trailing border. Any assistance would be appreciated. Below is the code: import SwiftUI struct DateAndClose { let date: Date let close: Double } func BuildArray() -> [DateAndClose] { var dataArray: [DateAndClose] = [] dataArray.append(DateAndClose(date: Date(), close: 123.4)) dataArray.append(DateAndClose(date: Date() + 10, close: 245.8)) dataArray.append(DateAndClose(date: Date() + 30, close: 329.3)) dataArray.append(DateAndClose(date: Date() + 45, close: 438.9)) return dataArray } struct Test: View { let heading: String var body: some View { let moArray: [DateAndClose] = BuildArray() Text("") Text(heading) .font(.system(size: 18, weight: .bold, design: .default)) .foregroundColor(.blue) .padding(.trailing, 24) Text("") List(moArray, id: \.date) { element in ListRow1(element: element) } .frame(width: 250) .background(Color.gray) Spacer() } } struct ListRow1: View { let element: DateAndClose var body: some View { let theDate = dateToStringFormatter.string(from: element.date) let theClose = String(format: "$%.2f", element.close ) let frameWidth: CGFloat = 100 let frameHeight: CGFloat = 25 let trailingPadding: CGFloat = -8.55 let bottomPadding: CGFloat = -4.8 HStack(){ Spacer() Text(theDate) .font(.system(size: 14, weight: .regular, design: .default)) .background(.white) .frame(width: frameWidth, height: frameHeight, alignment: .center) .border(.black, width: 1) .padding(.trailing, trailingPadding) .padding(.bottom, bottomPadding) Text(theClose) .font(.system(size: 14, weight: .regular, design: .default)) .background(.white) .frame(width: frameWidth, height: frameHeight, alignment: .center) .border(.black, width: 1) .padding(.bottom, bottomPadding) Spacer() } } } let dateToStringFormatter: DateFormatter = { let result = DateFormatter() result.dateFormat = "MM/dd/yy" result.timeZone = TimeZone(secondsFromGMT: 0) return result }()
2
0
2.6k
Oct ’22
Charts: How do I position x axis value labels below the associated grid lines
I am working with the new Charts Framework. The axis value labels for the x axis are dates (mm/dd/yy). I have 5 vertical grid lines and am trying to get the dates to be centered below the associated grid line with no success. One additional problem is that the values are in an array that contains 5 dates but only the first 4 get displayed. Any solutions will be appreciated. Below is the code. struct LineChart: View { private var localArray: [TradingDayPrices] init(passedInArray: [TradingDayPrices]) { self.localArray = passedInArray } var body: some View { let minCloseValue: Double = localArray.map { $0.close }.min()! let maxCloseValue: Double = localArray.map { $0.close }.max()! let minDate: Date = localArray[0].timeStamp! let itemCount: Int = localArray.count - 1 let maxDate: Date = localArray[itemCount].timeStamp! Spacer() GroupBox (label: Text("VOO Closing Values For The Past Year") .font(.system(size: 20)) .fontWeight(.bold) .frame(width: 700, height: 50, alignment: .center)) { Chart { ForEach(localArray) { item in LineMark ( x: .value("TimeStamp", item.timeStamp!), y: .value("Close", item.close) ) .foregroundStyle(Color.blue) .lineStyle(StrokeStyle(lineWidth: 1.25)) } // end for each } // end chart .padding(50) .chartBackground { item in Color.white } .chartXAxisLabel(position: .bottom, alignment: .center) { Text("Date") .font(.system(size: 14)) .foregroundColor(Color.black) .frame(width: 50, height: 35, alignment: .bottom) } .chartYAxisLabel(position: .leading, alignment: .center, spacing: 0) { Text("Closing Values") .font(.system(size: 14)) .foregroundColor(Color.black) } .chartXAxis { AxisMarks (values: GetXAxisLabels(min: minDate, max: maxDate)) { value in AxisGridLine(stroke: StrokeStyle(lineWidth: 0.5)) .foregroundStyle(Color.gray) AxisValueLabel() { if let localDate = value.as(Date.self) { let formattedDate = dateToStringFormatter.string(from: localDate) Text(formattedDate) .font(.system(size: 12)) .foregroundColor(Color.black) } } // end axis value label } // end axis marks } // end chart x axis .chartYAxis { AxisMarks (position: .leading, values: GetYAxisLabels(min: minCloseValue, max: maxCloseValue)) { value in AxisGridLine(stroke: StrokeStyle(lineWidth: 0.5)) .foregroundStyle(Color.gray) AxisValueLabel() { if let localValue = value.as(Double.self) { let formattedValue = String(format: "$%.2f", localValue) Text(formattedValue) .font(.system(size: 12)) .foregroundColor(Color.black) } } } // end axis marks } // end chart y axis .chartXScale(domain: minDate...maxDate) .chartYScale(domain: minCloseValue...maxCloseValue) .frame(width: 700, height: 700, alignment: .center) } // end group box } // end of body } // end of structure func GetXAxisLabels(min: Date, max: Date) -> [Date] { var xLabels: [Date] = [] let increment: Int = 90 for i in 0...3 { let value = Calendar.current.date(byAdding: DateComponents(day: (i * increment)), to: min)! xLabels.append(value) } xLabels.append(max) print("\(xLabels)") return xLabels } func GetYAxisLabels(min: Double, max: Double) -> [Double] { var yLabels: [Double] = [] let increment: Double = (max - min) / 4 for i in 0...3 { let value = min + (Double(i) * increment) yLabels.append(value) } yLabels.append(max) return yLabels } let dateToStringFormatter: DateFormatter = { let result = DateFormatter() result.dateFormat = "MM/dd/yy" return result }()
2
1
3.9k
Jan ’23
SwiftUI - Accessing StateObject's Object Without Being Installed on a View
I have a core data program. I run my fetch request in a class i.e. a view model and assign it to a StateObject in the ContentView. When I attempt to use the fetch request results from the view model in a selected view, the DataTable, I get this message: Accessing StateObject's object without being installed on a View. This will create a new instance each time. Not sure what to do. Below is my code: struct ContentView: View { @Environment(\.managedObjectContext) var moc @State var selection: DataDisplayed? = nil @StateObject var dataViewModel: FetchCoreData = FetchCoreData() var body: some View { NavigationSplitView{ sidebarContent .navigationSplitViewColumnWidth(min: 200, ideal: 200, max: 200) } detail: { detailContent } .navigationSplitViewStyle(.balanced) .navigationTitle("Testing") .frame(width: 1000, height: 800) } } extension ContentView { @ViewBuilder var detailContent: some View { if let selection = selection { detailContent(for: selection) .buttonStyle(.bordered) } else { Text("Make A Selection") } } @ViewBuilder func detailContent(for screen: DataDisplayed) -> some View { switch screen { case .VOODT: DataTable(dataModel: dataViewModel.fetchRequest) case .NWDT: Text("Start") case .VOOG1: Text("VOO Graph 1 Year") default: Text("Not yet implemented") } } } class FetchCoreData: ObservableObject { @FetchRequest var fetchRequest: FetchedResults<TradingDayPrices> init() { _fetchRequest = FetchRequest<TradingDayPrices>(sortDescriptors: [NSSortDescriptor(key: "timeStamp", ascending: true)], predicate: NSPredicate(format: "net > %d", 0.0)) } } struct DataTable: View { var dataModel: FetchedResults<TradingDayPrices> init(dataModel: FetchedResults<TradingDayPrices>) { self.dataModel = dataModel } var body: some View {. // fails on this line ######################## List(dataModel.fetchRequest, id: \.self) { item in Text("\(dateToStringFormatter.string(from: item.timeStamp!)) - ") + Text("\(item.vooClose) ") } } }
2
0
2.0k
Apr ’23
Swift - Map two elements from an array to a new array
I have an array of core data entities, named TradingDayPrices, with 1 date and 4 double attributes. I would like to be able to copy the date value and 1 specific double into a new array. I have not been able to determine the correct syntax. With the code below I get the error "cannot assign value of type [[Any]] to type [Date:Double]" var allClosingValues: [TradingDayPrices] var closingValues: [Date:Double] var selection: DataDisplayed init(selection: DataDisplayed, allClosingValues: [TradingDayPrices]) { self.selection = selection self.allClosingValues = allClosingValues switch selection { case .VOODT: closingValues = allClosingValues.map { [$0.timeStamp! , $0.vooClose] } default: let _ = print("Error in Data Table Structure") } }
2
0
1.9k
Apr ’23
How do I initialize a view models variables in a view
I have a view that displays core data values (passed in as closingValues) in a data table. To make the view generic, so I can pass in arrays of different lengths (all are from the same entity and thus attributes) and account for the view having already been called with a different set of values, I need to initialize the showData array contained in the associated view model. I attempt to do so in the init of the view but I get an error message "publishing changes from within a view updates is not allowed. This will cause undefined behavior". It should be noted that in the view model showData is Published and initialized = []. I attempted to do the initialization in the views onappear but the tables rows: ForEach runs before onappear and I get an index out of range on the first call to the view. I tried adding @MainActor to the view models class, which also failed to solve the problem. I am clearly not understanding a concept. Below is the code for the view. struct DataTable: View { @ObservedObject var vm: ButtonsViewModel = ButtonsViewModel.shared var closingValues: [TradingDayClose] var heading: String = "" init(fundName: String, closingValues: [TradingDayClose]) { self.heading = fundName self.closingValues = closingValues vm.showData = [] vm.showData = Array(repeating: false, count: closingValues.count) // Publishing changes from within view updates is not allowed, this will cause undefined behavior. } var body: some View { HStack { Spacer() .frame(width: 150) GroupBox(heading) { Table (of: TradingDayClose.self) { TableColumn("") { closingValue in Text(dateToStringFormatter.string(from: closingValue.timeStamp!)) .id(closingValue.timeStamp!) .textFormatting(fontSize: 14) .frame(width: 100, alignment: .center) } // end table column TableColumn("") { closingValue in Text(String(format: "$ %.2f", closingValue.close)) .textFormatting(fontSize: 14) .frame(width: 100, alignment: .center) } // end table column } rows: { ForEach((closingValues.indices), id: \.self) { index in if vm.showData[index] == true { TableRow(closingValues[index]) } } } .onAppear { vm.InitializeIndexes() vm.InitializeButtons() for i in vm.startIndex...vm.endIndex { DispatchQueue.main.asyncAfter(deadline: .now() + vm.renderRate * Double(i)) { vm.showData[i] = true } // end dispatch queue main async } } .frame(width: 250) .overlay { let tempValue1: String = "Date" let tempValue2: String = "Closing Value" Text(tempValue1).position(x: 63, y: 15) .textFormatting(fontSize: 16) Text(tempValue2).position(x: 180, y: 15) .textFormatting(fontSize: 16) } } // end group box .groupBoxStyle(Table2GroupBoxStyle()) Spacer() .frame(width: 50) VStack { Spacer() .frame(height: 100) ButtonUp25(closingValuesCount: closingValues.count) ButtonUp200(closingValuesCount: closingValues.count) Spacer() .frame(height: 20) ButtonDown25(closingValuesCount: closingValues.count) ButtonDown200(closingValuesCount: closingValues.count) Spacer() .frame(height: 100) } // end v stack Spacer() .frame(width: 50) } // end h stack } // end body } // end struct
2
0
993
Jun ’23
How do I extract HTML table data from a string with regex builder
I am attempting to learn regex builder. I scape data from a web site, pull out just the table rows and table data and place them into a string. I have attempted to extract table data with regex builder with no success. For testing I placed 3 scrapped table rows into a multi line string and apply my regex pattern in a for loop. It does not appear to find any matches. I am clearly overlooking something. Below is my code: func GetHTMLTableData() { let stringData = """ <tr class=BdT Bdc($seperatorColor) Ta(end) Fz(s) Whs(nw)><td class=Py(10px) Ta(start) Pend(10px)><span>Jun 30, 2023</span></td><td class=Py(10px) Pstart(10px)><span>405.40</span></td><td class=Py(10px) Pstart(10px)><span>408.22</span></td><td class=Py(10px) Pstart(10px)><span>405.29</span></td><td class=Py(10px) Pstart(10px)><span>407.28</span></td><td class=Py(10px) Pstart(10px)><span>407.28</span></td><td class=Py(10px) Pstart(10px)><span>5,160,100</span></td></tr> <tr class=BdT Bdc($seperatorColor) Ta(end) Fz(s) Whs(nw)><td class=Py(10px) Ta(start) Pend(10px)><span>Jun 29, 2023</span></td><td class=Py(10px) Pstart(10px)><span>400.60</span></td><td class=Py(10px) Pstart(10px)><span>402.67</span></td><td class=Py(10px) Pstart(10px)><span>400.19</span></td><td class=Py(10px) Pstart(10px)><span>402.51</span></td><td class=Py(10px) Pstart(10px)><span>402.51</span></td><td class=Py(10px) Pstart(10px)><span>3,914,800</span></td></tr> <tr class=BdT Bdc($seperatorColor) Ta(end) Fz(s) Whs(nw)><td class=Py(10px) Ta(start) Pend(10px)><span>Jun 28, 2023</span></td><td class=Py(10px) Pstart(10px)><span>401.35</span></td><td class=Py(10px) Pstart(10px)><span>403.49</span></td><td class=Py(10px) Pstart(10px)><span>400.71</span></td><td class=Py(10px) Pstart(10px)><span>402.55</span></td><td class=Py(10px) Pstart(10px)><span>400.97</span></td><td class=Py(10px) Pstart(10px)><span>4,320,700</span></td></tr> """ let tradingDayPattern = Regex { "<tr class=BdT Bdc($seperatorColor) Ta(end) Fz(s) Whs(nw)>" "<td class=Py(10px) Ta(start) Pend(10px)><span>" Capture(.date(format: "\(month: .abbreviated) \(day: .twoDigits), \(year: .extended(minimumLength: 4))", locale: Locale(identifier: "en_US_POSIX") , timeZone: .gmt)) "</span></td><td class=Py(10px) Pstart(10px)><span>" TryCapture { OneOrMore(.digit) "." Repeat(.digit, count: 2) } transform: { Double($0) } "</span></td><td class=Py(10px) Pstart(10px)><span>" TryCapture { OneOrMore(.digit) "." Repeat(.digit, count: 2) } transform: { Double($0) } "</span></td><td class=Py(10px) Pstart(10px)><span>" TryCapture { OneOrMore(.digit) "." Repeat(.digit, count: 2) } transform: { Double($0) } "</span></td><td class=Py(10px) Pstart(10px)><span>" TryCapture { OneOrMore(.digit) "." Repeat(.digit, count: 2) } transform: { Double($0) } "</span></td><td class=Py(10px) Pstart(10px)><span>" TryCapture { OneOrMore(.digit) "." Repeat(.digit, count: 2) } transform: { Double($0) } "</span></td><td class=Py(10px) Pstart(10px)><span>" TryCapture { OneOrMore(.digit) "," Repeat(.digit, count: 3) "," Repeat(.digit, count: 3) } transform: { Int($0) } "</span></td></tr>" } for match in stringData.matches(of: tradingDayPattern) { let (line, date, open, high, low, close, adjClose, volume ) = match.output print("\(date) - \(close)") } }
2
0
812
Jul ’23
CoreData Failure During Entity Creation in the ViewContext
I have a program that reads in 3 json files and updates CoreData if one or more of the JSON files contains new data. It runs successfully 9 times out of 10. The failure occurs during the creation of an entity in the managed object context. The failure occurs in the function AddRecordsToCoreData. I have placed the error messages below the offending line of code. Further, it appears to only fail during the third call to UpdateCoreDataRecoreds which in turn calls AddRecordsToCoreData. Setting up the calls to run in series I thought I could eliminate any problems but clearly not the case. What error am I making in the code? Or is there some other approach I should utilize? Below is the code in question. class UpdateCoreData: ObservableObject { let persistentContainer = CoreDataStack.shared.persistentContainer @Published var loadingData: Bool = true @Published var updateStatus: String = "" init() { Task { async let fund1Complete: Bool = UpdateCoreDataRecords(fundName: "Fund1", moc: persistentContainer.viewContext) let _ = await (fund1Complete) async let fund2Complete: Bool = UpdateCoreDataRecords(fundName: "Fund2", moc: persistentContainer.viewContext) let _ = await (fund2Complete) async let fund3Complete: Bool = UpdateCoreDataRecords(fundName: "Fund3", moc: persistentContainer.viewContext) let _ = await (fund3Complete) persistentContainer.viewContext.vacuum() let persistentStore = persistentContainer.persistentStoreCoordinator.persistentStores.first do { try persistentContainer.persistentStoreCoordinator.remove(persistentStore!) } catch { print("Unable to remove store -> \(error)") } DispatchQueue.main.async { self.loadingData = false self.updateStatus = "Core Date is Updated" } } } } func UpdateCoreDataRecords(fundName: String, moc: NSManagedObjectContext) async -> Bool { var latestDate: Date = Date() var decodedJSON: TradingDays = TradingDays.init(tradingday: []) latestDate = await LatestCoreDataDate(fundName: fundName, moc: moc) decodedJSON = await DecodeJSONFile(fileName: fundName) await AddRecordsToCoreData(jsonData: decodedJSON, fundName: fundName, latestDate: latestDate, moc: moc) return true } func LatestCoreDataDate(fundName: String, moc: NSManagedObjectContext) async -> Date { var coreDataValues: [TradingDayClose] = [] var latestDate: Date = Date() let fetchRequest: NSFetchRequest<TradingDayClose> = TradingDayClose.fetchRequest() fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timeStamp", ascending: false)] fetchRequest.predicate = NSPredicate(format: "fundName = %@", fundName) fetchRequest.fetchLimit = 1 do { coreDataValues = try moc.fetch(fetchRequest) } catch let error { print("Error fetching max date. \(error.localizedDescription)") } if coreDataValues.isEmpty { latestDate = Calendar.current.date(byAdding: DateComponents(year: -6), to: latestDate)! } else { latestDate = coreDataValues[0].timeStamp! } return latestDate } func AddRecordsToCoreData(jsonData: TradingDays, fundName: String, latestDate: Date, moc: NSManagedObjectContext) async { print("\(fundName)") for item in jsonData.tradingday { if item.timeStamp > latestDate { let newRecord = TradingDayClose(context: moc) // Thread 4: EXC_BAD_ACCESS (code=1, address=0x8) // thread 3 signal Sigbrt // Thread 2: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) newRecord.fundName = fundName newRecord.id = UUID() newRecord.timeStamp = item.timeStamp newRecord.close = (item.close) as NSDecimalNumber } else { break } } if moc.hasChanges { do { print("Saving moc") try moc.save() } catch { print("Errors attempting to save moc") } } }
2
0
947
Jul ’23
Convert SQLite Julian date to a specific date string format for display
I have a function that queries an SQLite database and returns names, dates and values. In SQLite the dates are in Julian format. I convert the dates in the SQLite query to a date time string which give me "2022-08-01 00:00:00". I want to display this date as the date string "Aug 1, 2022". The only way I have been able to achieve this is to convert the first date string to a date via a date formatter then convert this date to the desired date string via a second date formatter. Is there a more direct way to do this? func AccessSQLiteDB(db: OpaquePointer?) { let queryTradingDaysStatement = """ WITH TempTable1 AS ( SELECT max(TimeStamp) - 365.25 as StartingDate FROM TradingDays WHERE FundName = 'Fund1' ), TempTable2 AS ( SELECT main.FundName, datetime(main.TimeStamp) as SQLDateString, main.Close FROM TradingDays main, TempTable1 as temp WHERE main.FundName = 'Fund1' AND main.TimeStamp >= temp.StartingDate ) SELECT FundName, SQLDateString, Close FROM TempTable2 ORDER By SQLDateString ASC ; """ let sqlDateStringFormatter = DateFormatter() sqlDateStringFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" sqlDateStringFormatter.timeZone = .gmt var queryTradingDaysCPtr: OpaquePointer? if sqlite3_prepare_v2(db, queryTradingDaysStatement, -1, &queryTradingDaysCPtr, nil) == SQLITE_OK { while (sqlite3_step(queryTradingDaysCPtr) == SQLITE_ROW) { let fundName = sqlite3_column_text(queryTradingDaysCPtr, 0) let timeStamp = sqlite3_column_text(queryTradingDaysCPtr, 1) let close = sqlite3_column_double(queryTradingDaysCPtr, 2) let fundNameAsString = String(cString: fundName!) let timeStampAsString = String(cString: timeStamp!) print(timeStampAsString) // returns this format 2022-08-01 00:00:00 let timeStampAsDate: Date = sqlDateStringFormatter.date(from: timeStampAsString)! print("\(timeStampAsDate)") // returns this format 2022-08-01 00:00:00 +0000 let mediumDataFormatter = DateFormatter() mediumDataFormatter.dateStyle = .medium mediumDataFormatter.timeZone = .gmt let dateString = mediumDataFormatter.string(from: timeStampAsDate) print(dateString) // returns this format Aug 1, 2022 let closeAsString = String(format: "$%.2f", close) print(fundNameAsString + " - " + dateString + " - " + closeAsString) } // end while loop } else { let errorMessage = String(cString: sqlite3_errmsg(db)) print("\nQuery is not prepared \(errorMessage)") } sqlite3_finalize(queryTradingDaysCPtr) }
2
0
1k
Aug ’23
When creating an instance of a custom NSTableCellView how do pass in a value
I have a program that creates a custom table view. In the delegate that populates the cells with data I create an instance of a custom NSTableCellView. It works. What I would like to be able to do is pass in a value when making an instance so that I can set the width of the frame (var rectWidth in the custom NSTableCellView). I am currently using two different custom NSTableCellViews, each with a different value for var rectWidth. Below is my delegate and custom NSTableCellView code. func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { if (tableColumn?.identifier)!.rawValue == "fund" { let dataCell = CustomTableCellView() dataCell.textField?.stringValue = closingValues[row].fundName return dataCell } else if (tableColumn?.identifier)!.rawValue == "date" { let dataCell = CustomTableCellViewDate() dataCell.textField?.stringValue = SQLDateFormatter.string(from: closingValues[row].timeStamp) return dataCell } else { let dataCell = CustomTableCellView() dataCell.textField?.stringValue = String(format: "$%.2f", closingValues[row].close) return dataCell } } class CustomTableCellView: NSTableCellView { override init(frame frameRect: NSRect) { super.init(frame: frameRect) let rectWidth: CGFloat = 100 self.autoresizingMask = .width let nsRectangle = NSMakeRect(0, 0, rectWidth, 24) let customTextField: NSTextField = CustomTextField(frame: nsRectangle) self.textField = customTextField self.addSubview(customTextField) } required init?(coder decoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
2
0
829
Aug ’23
Chart - Last (right most) x axis label not being displayed
I have a swift program that displays a chart using Chart. The code includes an X Axis Scale parameter but for some reason the last value (right most) on the x axis does not display. It should display Aug 2023. In checking the array used for the x axis labels I find that the last value is Aug 2023. I do not know how to overcome this obstacle. Any assistance will be appreciated. Below is a picture of the bottom of the chart and the code. struct CustomChartView: View { let vm: SQLDataVM = SQLDataVM.shared let closingValues: [TradingDay] let fundName: String let numYears: Int let maxCloseStruct: TradingDay let maxClose: Double let minCloseStruct: TradingDay let minClose: Double let yIncrment: Double let yAxisValues: [Double] let minTimeStampStruct: TradingDay let minTimeStamp: Date var dateComponent = DateComponents() let maxTimeStampStruct: TradingDay let maxTimeStamp: Date var xAxisValues: [Date] = [] init (fundName: String, numYears: Int) { self.fundName = fundName self.numYears = numYears closingValues = self.vm.QueryDatabase(fundName: fundName, numYears: numYears) maxCloseStruct = self.closingValues.max(by: { (tradingDay1, tradingDay2) -> Bool in return tradingDay1.close < tradingDay2.close })! maxClose = maxCloseStruct.close minCloseStruct = closingValues.min(by: { (tradingDay1, tradingDay2) -> Bool in return tradingDay1.close < tradingDay2.close })! minClose = minCloseStruct.close yIncrment = (maxClose - minClose)/4 yAxisValues = [ minClose, minClose + (1 * yIncrment), minClose + (2 * yIncrment), minClose + (3 * yIncrment), maxClose ] minTimeStampStruct = closingValues.min(by: { (tradingDay1, tradingDay2) -> Bool in return tradingDay1.timeStamp < tradingDay2.timeStamp })! minTimeStamp = minTimeStampStruct.timeStamp maxTimeStampStruct = closingValues.max(by: { (tradingDay1, tradingDay2) -> Bool in return tradingDay1.timeStamp < tradingDay2.timeStamp })! maxTimeStamp = maxTimeStampStruct.timeStamp xAxisValues.append(minTimeStamp) for i in 1...11 { dateComponent.month = i let nextMonth = Calendar.current.date(byAdding: dateComponent, to: minTimeStamp) xAxisValues.append(nextMonth!) } xAxisValues.append(maxTimeStamp) print("\(xAxisValues[12])") // prints 2023-08-04 00:00:00 +0000 } // end init var body: some View { HStack(alignment: .center) { VStack(alignment: .center) { Chart(closingValues, id:\.id) { LineMark( x: .value("Date", $0.timeStamp, unit: .day), y: .value("Closing", $0.close) ) .foregroundStyle(.blue) } // end chart .frame(width: 1000, height: 700, alignment: .center) .chartXAxisLabel(position: .bottom, alignment: .center, spacing: 15) { Text("Date") .font(.custom("Arial", size: 20)) } .chartYAxisLabel(position: .leading, alignment: .center, spacing: 20) { Text("Closing Value") .font(.custom("Arial", size: 20)) } .chartXAxis { AxisMarks(values: xAxisValues) { value in if let date = value.as(Date.self) { AxisValueLabel(horizontalSpacing: -14, verticalSpacing: 10) { VStack(alignment: .leading) { Text(ChartMonthFormatter.string(from: date)) .font(.custom("Arial", size: 14)) Text(ChartYearFormatter.string(from: date)) .font(.custom("Arial", size: 14)) } // end v stack } // end axis label } // end if statement AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1)) .foregroundStyle(Color.black) AxisTick(centered: true, length: 0, stroke: .none) } } // end chart x axis .chartXScale(domain: [xAxisValues[0], xAxisValues[12]]) .chartYAxis { AxisMarks(position: .leading, values: yAxisValues) { value in AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1)) .foregroundStyle(Color.black) AxisTick(centered: true, length: 0, stroke: .none) AxisValueLabel(horizontalSpacing: 10) { if let yAxisValue = value.as(Double.self) { let stringValue = String(format: "$%.02f", yAxisValue) Text(stringValue) .font(.custom("Arial", size: 14)) } } } } .chartYScale(domain: [minClose, maxClose]) .chartPlotStyle { plotArea in plotArea.background(.white.opacity(0.9)) .border(.black, width: 1) } // end chart plot style } // end v stack .frame(width: 1200, height: 900, alignment: .center) } // end h stack } // end some view }
2
0
2.6k
Sep ’23
OS X + Swift + Xcode : Programmatically transition from one view controller to another
Hello, I have a swift program that allows me to transition from a primary view controller to a secondary view controller. To complete this task I create a segue between a button on the primary view controller and the secondary view controller by dragging from the button to the secondary view controller then assigning an identifier to this seque. The balance is handled programatically. What I would like to do is eliminate the creation of the segue via dragging and handle transitioning to the secondary view controller 100% in code. I have given the secondary view controller a storyboard id so it seems logical to me that I should be able to locate the secondary view controller via this identifier and use this to transition to it. Is there a way to do this? Regards, Chris
3
0
689
Aug ’21
Remove gap between lazyvgrids in vstack
Hello, I have the code below which creates a view. Unfortunately it puts a small gap between the two LazyVGrids that I would like to eliminate. Any suggestions would be appreciated. Below is my code. Chris import SwiftUI struct SecondView: View {          var columns = [         GridItem(.fixed(100), spacing: 0.1),         GridItem(.fixed(100), spacing: 0.1),         GridItem(.fixed(100), spacing: 0.1),         GridItem(.fixed(100), spacing: 0.1),         GridItem(.fixed(100), spacing: 0.1)     ]     let principalData: convertCSVtoArray          var body: some View {         let numArrays = principalData.cvsData.count         let numElementsPerArray = principalData.cvsData[0].count                      VStack{             Text("")             Text("Historical Data")                 .font(.title)                 .padding(5)             Divider()             LazyVGrid(                 columns: columns,                 alignment: .center,                 spacing: 0)             {                 ForEach(0..<1) {row in                     ForEach(0..<numElementsPerArray) {col in                         Rectangle()                             .foregroundColor(.white)                             .overlay (Text(principalData.cvsData[row][col]).bold())                             .frame(height: 30)                             .border(Color.gray, width: 2)                     }                 }             }             ScrollView{                 LazyVGrid(                     columns: columns,                     alignment: .center,                     spacing: 0)                     {                         ForEach(1..<numArrays) {row in                             ForEach(0..<numElementsPerArray) {col in                                 Rectangle()                                     .foregroundColor(.white)                                     .overlay (Text(principalData.cvsData[row][col]))                                     .frame(height: 30)                                     .border(Color.gray, width: 0.5)                             }                         }                     }                 ForEach(0..<30){index in                     Text("")                 }             }// end scrollview         }     } }
3
0
2.7k
Sep ’21
How do I disable a button while it has focus
I have a view that shows a table and 4 buttons. Each button allows the user to step forward and backwards through the data. Buttons are enabled and disabled based on where you are in the data. If you are less than 200 values to the end of the data for example, the "Page Down - 200" button is disabled. Everything works fine if the mouse is used to run the code associated with each button. But in this case I think the buttons never get focus. Focus I think remains with the sidebar content item that brought up the table view (am using a navigation split view). If I tab over to the page down 200 button and use the space bar to run its associated code I get the error "AttributeGraph: cycle detected through attribute 864480". I think the problem lies with attempting to disable the button while it has focus but am not 100% sure. I have tried to change the focus prior to disabling the button but I get the same error. I think there is some fundamental that I am missing. Below is my table view along with the page down 200 button view. struct DataTable: View { @FocusState var buttonWithFocus: Field? @ObservedObject var vm: ButtonsViewModel = ButtonsViewModel.shared @State private var hasAppeared = false var closingValues: [TradingDayClose] var heading: String = "" init(fundName: String, closingValues: [TradingDayClose]) { self.heading = fundName self.closingValues = closingValues } var body: some View { HStack { Spacer() .frame(width: 150) GroupBox(heading) { if hasAppeared { Table (of: TradingDayClose.self) { TableColumn("") { closingValue in Text(dateToStringFormatter.string(from: closingValue.timeStamp!)) .id(closingValue.timeStamp!) .textFormatting(fontSize: 14) .frame(width: 100, alignment: .center) } // end table column TableColumn("") { closingValue in Text(String(format: "$ %.2f", closingValue.close)) .textFormatting(fontSize: 14) .frame(width: 100, alignment: .center) } // end table column } rows: { ForEach((closingValues.indices), id: \.self) { index in if vm.showData[index] == true { TableRow(closingValues[index]) } } } .focusable(false) .frame(width: 250) .overlay { let tempValue1: String = "Date" let tempValue2: String = "Closing Value" Text(tempValue1).position(x: 63, y: 15) .textFormatting(fontSize: 16) Text(tempValue2).position(x: 180, y: 15) .textFormatting(fontSize: 16) } } // end has appeared } // end group box .groupBoxStyle(Table2GroupBoxStyle()) Spacer() .frame(width: 50) VStack { Spacer() .frame(height: 100) Form { Section { ButtonUp25(closingValuesCount: closingValues.count) .focused($buttonWithFocus, equals: .btnUp25) ButtonUp200(closingValuesCount: closingValues.count) .focused($buttonWithFocus, equals: .btnUp200) } header: { Text("Page Up") } Spacer() .frame(height: 20) Section { ButtonDown25(closingValuesCount: closingValues.count) .focused($buttonWithFocus, equals: .btnDn25) ButtonDown200(buttonWithFocus: $buttonWithFocus, closingValuesCount: closingValues.count) .focused($buttonWithFocus, equals: .btnDn200) } header: { Text("Page Down") } } // end form .navigationTitle("Data Table") Spacer() .frame(height: 100) } // end v stack Spacer() .frame(width: 50) } // end h stack .onAppear { vm.InitializeShowData(closingValueCount: closingValues.count) vm.InitializeIndexes() vm.InitializeButtons() for i in vm.startIndex...vm.endIndex { DispatchQueue.main.asyncAfter(deadline: .now() + vm.renderRate * Double(i)) { vm.showData[i] = true } // end dispatch queue main async } hasAppeared = true } } // end body } // end struct struct ButtonDown200: View { var buttonWithFocus: FocusState<Field?>.Binding @ObservedObject var vm: ButtonsViewModel = ButtonsViewModel.shared var closingValuesCount: Int var body: some View { Button("Page Down - 200") { for i in vm.startIndex...vm.endIndex { vm.showData[i] = false } vm.startIndex = vm.startIndex + 200 vm.endIndex = vm.startIndex + 24 var j: Int = 0 for i in vm.startIndex...vm.endIndex { DispatchQueue.main.asyncAfter(deadline: .now() + vm.renderRate * Double(j)) { vm.showData[i] = true } j = j + 1 } if (closingValuesCount - 1) - (vm.startIndex + 200) < 25 { // buttonWithFocus.wrappedValue = .btnDn25 vm.pageDownDisabled200 = true } if vm.startIndex > 24 { vm.pageUpDisabled25 = false } if vm.startIndex - 200 >= 0 { vm.pageUpDisabled200 = false } } .controlSize(.large) .buttonStyle(.borderedProminent) .disabled(vm.pageDownDisabled200) } }
3
0
1.6k
Jun ’23