Post

Replies

Boosts

Views

Activity

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
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
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
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
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 '() -&gt; ContentView' } } // end navigation stack } // end v stack } } struct GenericTableView&lt;Content:View&gt;: View { let content: Content init(@ViewBuilder content: () -&gt; Content) { self.content = content() } var body: some View { content } }
1
0
731
Oct ’23