Post

Replies

Boosts

Views

Activity

How do I animate a Swift line mark chart
I have a view that displays a chart based on an array. Each element in the array is all of the attributes associated with a core data entity. The data is properly displayed. I would like to animate the rendering of the charts data but cannot seem to figure out how to do it. If someone could point me in the right direction it would be appreciated. Below is the code. struct ClosingValuesChart: View { @State private var selectedDate: Date? = nil @State private var selectedClose: Float? = nil @State private var xAxisLabels: [Date] = [] var closingValues: [TradingDayClose] = [] var heading: String = "" init(fundName: String, numYears: Int, closingValues: [TradingDayClose]) { self.heading = fundName + String(" - \(numYears) Year") self.closingValues = closingValues } var body: some View { GroupBox (heading) { let xMin = closingValues.first?.timeStamp let xMax = closingValues.last?.timeStamp let yMin = closingValues.map { $0.close }.min()! let yMax = closingValues.map { $0.close }.max()! let xAxisLabels: [Date] = GetXAxisLabels(xMin: xMin!, xMax: xMax!) var yAxisLabels: [Float] { stride(from: yMin, to: yMax + ((yMax - yMin)/7), by: (yMax - yMin) / 7).map { $0 } } Chart { ForEach(closingValues) { value in LineMark( x: .value("Time", value.timeStamp!), y: .value("Closing Value", value.close) ) .foregroundStyle(Color.blue) .lineStyle(StrokeStyle(lineWidth: 1.25)) } } .chartXScale(domain: xMin!...xMax!) .chartXAxisLabel(position: .bottom, alignment: .center, spacing: 25) { Text("Date") .textFormatting(fontSize: 14) } .chartXAxis { AxisMarks(position: .bottom, values: xAxisLabels) { value in AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1)) AxisValueLabel(anchor: .top) { if value.as(Date.self) != nil { Text("") } } } } .chartYScale(domain: yMin...yMax) .chartYAxisLabel(position: .leading, alignment: .center, spacing: 25) { Text("Closing Value") .font(Font.custom("Arial", size: 14)) .foregroundColor(.black) } .chartYAxis { AxisMarks(position: .leading, values: yAxisLabels) { value in AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1)) AxisValueLabel() { if let labelValue = value.as(Double.self) { Text(String(format: "$ %.2f", labelValue)) .textFormatting(fontSize: 12) } } } } .chartOverlay { proxy in GeometryReader { geometry in ChartOverlayRectangle(selectedDate: $selectedDate, selectedClose: $selectedClose, proxy: proxy, geometry: geometry, xMin: xMin!, xMax: xMax!, closingValues: closingValues) } } .overlay { XAxisDates(dateLabels: xAxisLabels) } .overlay { DateAndClosingValue(selectedDate: selectedDate ?? Date(), selectedClose: selectedClose ?? 0.0) } } .groupBoxStyle(ChartGroupBoxStyle()) } }
4
0
3k
Jun ’23
SQLite - Select statement to extract 1 year of data
I have an SQLite table that holds a fund name, as a string, a time stamp, as an iso8601 string, and a close, as a double. SQLite appears to call strings text and a double a real. In the function below, I query this table with a select statement to return the last year of data based on the latest date in the table. To get the latest date I have a separate function that finds the latest date, converts if from a string to a date, subtracts 1 year from the date then converts it back to an iso8601 date string. It is this date string that is being passed into the function below as the variable startingDate. The function below works just fine and is relatively fast. What I am trying to determine is there a way to modify the select statement in the function below such that it does everything and I will no longer have to separately calculate the starting date and pass it in? func QuerySQLiteData(db: OpaquePointer?, fundName: String, startingDate: String) -> [TradingDay] { var queryResults: [TradingDay] = [] let timeStampFormatter = ISO8601DateFormatter() let queryTradingDaysStatement = """ Select FundName, TimeStamp, Close FROM TradingDays WHERE FundName = '\(fundName)' AND TimeStamp >= '\(startingDate)' ORDER By TimeStamp ASC ; """ var queryTradingDaysCPtr: OpaquePointer? var tradingDay: TradingDay = TradingDay(fundName: "", timeStamp: Date(), close: 0.0) 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!) let timeStampAsDate = timeStampFormatter.date(from: timeStampAsString)! tradingDay.fundName = fundNameAsString tradingDay.timeStamp = timeStampAsDate tradingDay.close = close queryResults.append(tradingDay) } // end while loop } else { let errorMessage = String(cString: sqlite3_errmsg(db)) print("\nQuery is not prepared \(errorMessage)") } sqlite3_finalize(queryTradingDaysCPtr) return queryResults }
5
0
801
Jul ’23
NSTableView - How do I remove the horizontal gap between table cells
I am creating my own NSTableView for macOS. I can display formatted data and provide scrolling by embedding it in a ScrollView. When the table is displayed there is a horizontal gap between adjacent cells. The same gap occurs between the ScrollView header cells. I do not know how to. solve this problem. There is one other issue, I do not know how to set the vertical height of the ScrollView header cells. I would like to make them taller. Below is my code along with the test data. struct ClosingValue: Identifiable { var id: UUID var name: String var date: String var close: Float static var closingValues = [ ClosingValue(id: UUID(), name: "Stock1", date: "Nov 01, 2009", close: 1.10), ClosingValue(id: UUID(), name: "Stock1", date: "Nov 02, 2009", close: 2.10), ClosingValue(id: UUID(), name: "Stock1", date: "Nov 03, 2009", close: 3.10), ClosingValue(id: UUID(), name: "Stock1", date: "Nov 04, 2009", close: 4.10), ClosingValue(id: UUID(), name: "Stock1", date: "Nov 05, 2009", close: 5.10) ] } struct BetterTableView: NSViewRepresentable { class Coordinator: NSObject, NSTableViewDelegate, NSTableViewDataSource { @State var closingValues: [ClosingValue] = ClosingValue.closingValues func numberOfRows(in tableView: NSTableView) -> Int { closingValues.count } func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { var nsView = NSView() let tableColumnWidth: CGFloat = 135 let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = .center let attributes1: [NSAttributedString.Key: Any] = [ .foregroundColor: NSColor.blue, .paragraphStyle: paragraphStyle, .font: NSFont(name: "Arial", size: 14.0) as Any ] switch tableColumn { case tableView.tableColumns[0]: tableColumn?.width = tableColumnWidth let attributedString = NSAttributedString(string: closingValues[row].name, attributes: attributes1) let tempNSView = NSTextField() tempNSView.backgroundColor = NSColor.white tempNSView.isBordered = true tempNSView.isEditable = false tempNSView.attributedStringValue = attributedString nsView = tempNSView case tableView.tableColumns[1]: tableColumn?.width = tableColumnWidth let attributedString = NSAttributedString(string: closingValues[row].date, attributes: attributes1) let tempNSView = NSTextField() tempNSView.backgroundColor = NSColor.white tempNSView.isBordered = true tempNSView.isEditable = false tempNSView.attributedStringValue = attributedString nsView = tempNSView case tableView.tableColumns[2]: tableColumn?.width = tableColumnWidth let closeAsString = String(format: "$%.2f", closingValues[row].close) let attributedString = NSAttributedString(string: closeAsString, attributes: attributes1) let tempNSView = NSTextField() tempNSView.backgroundColor = NSColor.white tempNSView.isBordered = true tempNSView.isEditable = false tempNSView.attributedStringValue = attributedString nsView = tempNSView default: print("problem in table view switch statement") } return nsView } } func makeCoordinator() -> Coordinator { Coordinator() } func makeNSView(context: Context) -> NSScrollView { let tableView = NSTableView() tableView.delegate = context.coordinator tableView.dataSource = context.coordinator tableView.addTableColumn(NSTableColumn()) tableView.addTableColumn(NSTableColumn()) tableView.addTableColumn(NSTableColumn()) let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = .center let attributes: [NSAttributedString.Key: Any] = [ .foregroundColor: NSColor.black, .paragraphStyle: paragraphStyle, .font: NSFont.systemFont(ofSize: 14) ] let column0AttributedString = NSAttributedString(string: "Stock", attributes: attributes) let column0Header = tableView.tableColumns[0] column0Header.headerCell.drawsBackground = true column0Header.headerCell.backgroundColor = NSColor.systemMint column0Header.headerCell.alignment = .center column0Header.headerCell.attributedStringValue = column0AttributedString let column1AttributedString = NSAttributedString(string: "Date", attributes: attributes) let column1Header = tableView.tableColumns[1] column1Header.headerCell.drawsBackground = true column1Header.headerCell.backgroundColor = NSColor.systemMint column1Header.headerCell.alignment = .center column1Header.headerCell.attributedStringValue = column1AttributedString let column2AttributedString = NSAttributedString(string: "Closing Value", attributes: attributes) let column2Header = tableView.tableColumns[2] column2Header.headerCell.drawsBackground = true column2Header.headerCell.backgroundColor = NSColor.systemMint column2Header.headerCell.alignment = .center column2Header.headerCell.attributedStringValue = column2AttributedString let scrollView = NSScrollView() scrollView.documentView = tableView return scrollView } func updateNSView(_ nsView: NSScrollView, context: Context) { let tableView = (nsView.documentView as! NSTableView) // work on this section } }
5
0
1.1k
Aug ’23
Set Content View size/position upon retuning from navigation stack destination view
I have a program that utilizes a Navigation Stack. I want each view to be centered on the screen and be a specific size. I accomplished this with some position logic which sets the views frame size and origin. There is unique position logic for each of the 3 view sizes, the Content View and 2 navigation destination views. When the Content View is first displayed the associated position logic code runs and the view is the correct size and centered. The same is true every time one of the 2 navigation destination views is displayed. Unfortunately, when I return to the Content View from a navigation destination view the position logic does not run again and the Content View is now the same size and position as the previous navigation destination view. How do I resolve this problem? Below is the position logic code associated with the Content View and how it is called. @main struct TableViewTestApp: App { var body: some Scene { WindowGroup { ContentView() .hostingWindowPositionHome( screen: .main ) } } } extension View { func hostingWindowPositionHome( screen: NSScreen? = nil ) -> some View { modifier( WindowPositionModifierHome( screen: screen ) ) } } private struct WindowPositionModifierHome: ViewModifier { let screen: NSScreen? func body(content: Content) -> some View { content.background( HostingWindowFinderHome { $0?.setPositionHome(in: screen) } ) } } private struct HostingWindowFinderHome: NSViewRepresentable { var callback: (NSWindow?) -> () func makeNSView(context: Self.Context) -> NSView { let view = NSView() DispatchQueue.main.async { self.callback(view.window) } return view } func updateNSView(_ nsView: NSView, context: Context) { DispatchQueue.main.async { self.callback(nsView.window) } } } extension NSWindow { func setPositionHome(in screen: NSScreen?) { let nsRectangle: NSRect = NSRect(x: 1055.0, y: 370.0, width: 450, height: 700) setFrame(nsRectangle, display: true) } }
5
0
1.2k
Oct ’23
Swift + OS X + Xcode : Change NavigationLink destination and text programtically
Hello, I am trying to learn Swift. I have the code below. With a button click I can move to a new view. What I would like to do is once the new view is displayed have the navigation link destination changed to "CurrentView" and the button text to "Previous View". Any insight on how to resolve this issue would be appreciated. Regards, Chris import SwiftUI struct ContentView: View {     var body: some View {         NavigationView {             NavigationLink(destination: NextContentView()){                 Text("Next View")             }         }     } }
6
0
1k
Aug ’21