Thank You so much!
Post
Replies
Boosts
Views
Activity
The code is very long so i hope this edit is sufficient to read.
Where do you use relativeRiskPickerIndex31? - there are 31 "questions" in this part of the app,. each app has 2 sets of answers for users to choose from. #1 Slope Angle (they choose answer from picker one) and picker two in the relativeRiskPickerIndex.. basically there are from 1 until 31 risk picker indexes using this:
let relativeRiskChoices = ["Select", "Negligible", "Minor", "Moderate", "Significant", "Major"]
let relativeRiskScores = ["-","A", "B", "C", "D", "E"]
//the code above this line is from another swift file that just gets called to the file to the code below.
The state var values are all zero.
There is no error message inside the code lines but when I run the simulator and try to run and "pick" answers from the "questions" and answers inside the simulator, it Freezes and stops working. so i have to force quit it again to try to run it again.
however, if i do not use the pickers and just directly try to export pdf, it works.
The last time I tried this popped up on the debug area:
2023-07-03 22:28:42.363228+0900 LRAT[1382:14173] [Query] Error for queryMetaDataSync: 2
Swift/ContiguousArrayBuffer.swift:600: Fatal error: Index out of range
2023-07-03 22:32:08.544395+0900 LRAT[1382:12856] Swift/ContiguousArrayBuffer.swift:600: Fatal error: Index out of range
(lldb)
I hope i shortened this code properly:
import SwiftUI
import UIKit
import PDFKit
struct NaturalSlopeFormView: View {
@Environment(.presentationMode) var presentationMode
//this part has 30 more state var of different names
@State private var slopeAnglePickerIndex = 0
//this part has 1-31
@State private var relativeRiskPickerIndex1 = 0
var body: some View {
NavigationView {
Form {
//this part has 7 groups with at most 5 sections each
Group {
Section(header: Text("Slope Angle").font(.title3).bold() ) {
Picker("Criteria", selection: $slopeAnglePickerIndex, content: {
ForEach(0..<QuestionData().slopeAngleChoices.count, id: .self) { index in
Text(QuestionData().slopeAngleChoices[index])
}
})
.pickerStyle(MenuPickerStyle())
Picker("Relative Risk", selection: $relativeRiskPickerIndex1, content: {
ForEach(0..<QuestionData().relativeRiskChoices.count, id: .self) { index in
Text(QuestionData().relativeRiskChoices[index])
}
})
.pickerStyle(MenuPickerStyle())
Text("Score: \(QuestionData().slopeAngleScores[slopeAnglePickerIndex]), \(QuestionData().relativeRiskScores[relativeRiskPickerIndex1])")
}
}
.navigationBarItems(leading:
HStack{ . . . } //this is for a button to export to PDF
trailing: Button(action: exportToPDF){ . . . }
func addEvaluator() { . . . }
func saveForm(){ . . . }
func generateReferenceNumber() -> String{ . . . }
func formattedDate() -> String { . . . }
func formattedEvaluators() -> String{ . . . }
func exportToPDF(){ . . . }
func createPDF() -> Data{ . . . }
let pdfMetaData = [ . . . ]
//continuation for formatting of the pdf
let pdf = PDFDocument()
let page = PDFPage()
pdf.insert(page, at: 0)
// Define the column widths
let columnWidths: [CGFloat] = [400, 100, 100]
// Define the row height and padding
let rowHeight: CGFloat = 15
let padding: CGFloat = 5
// Define the starting position for drawing
var currentPosition = CGPoint(x: 20, y: 170)
// Define the data for the table
let relativeRiskOptions = ["A", "B", "C", "D", "E"]
// Define the data for the table
let tableData: [(String, Int, String)] = [
("Slope Angle", slopeAnglePickerIndex, relativeRiskOptions[relativeRiskPickerIndex1]),
("Slope Height", slopeHeightPickerIndex, relativeRiskOptions[relativeRiskPickerIndex2]),
("Slope Aspect", slopeAspectPickerIndex, relativeRiskOptions[relativeRiskPickerIndex3]),
("Slope Elevation", slopeElevationPickerIndex, relativeRiskOptions[relativeRiskPickerIndex4]),
//this part goes until relativeRiskPickerIndex31
for (index, rowData) in tableData.enumerated() {
let column1Text = NSAttributedString(string: "(rowData.0)", attributes: textAttributes)
let column2Text = NSAttributedString(string: "(rowData.1)", attributes: textAttributes)
let column3Text = NSAttributedString(string: "(rowData.2)", attributes: textAttributes)
let column1X = currentPosition.x
let column2X = currentPosition.x + columnWidths[0]
let column3X = currentPosition.x + columnWidths[0] + columnWidths[1]
let column1Rect = CGRect(x: column1X, y: currentPosition.y, width: columnWidths[0], height: rowHeight)
let column2Rect = CGRect(x: column2X, y: currentPosition.y + (rowHeight - column2Text.size().height) / 2, width: columnWidths[1], height: rowHeight)
let column3Rect = CGRect(x: column3X, y: currentPosition.y + (rowHeight - column3Text.size().height) / 2, width: columnWidths[2], height: rowHeight)
column1Text.draw(in: column1Rect)
column2Text.draw(in: column2Rect)
column3Text.draw(in: column3Rect)
currentPosition.y += rowHeight + padding
return data
}
}
struct NaturalSlopeFormView_Previews: PreviewProvider { . . . }
struct DatePickerSheet: View { . . . }
Thank you!
Hi, I was able to make it work. I decided to start from scratch.
instead of doing this:
let tableData: [(String, Int, String)] = [
("Slope Angle", slopeAnglePickerIndex, relativeRiskOptions[relativeRiskPickerIndex1]),
("Slope Height", slopeHeightPickerIndex, relativeRiskOptions[relativeRiskPickerIndex2])
i did this instead:
let tableData: [(String, String, String)] = [
("Slope Angle", QuestionData().slopeAngleChoices[slopeAnglePickerIndex], QuestionData().relativeRiskChoices[relativeRiskPickerIndex1]),
("Slope Height", QuestionData().slopeHeightChoices[slopeHeightPickerIndex], QuestionData().relativeRiskChoices[relativeRiskPickerIndex2]),
the matrix I want to make actually is part of the main output in this app. It is basically a risk matrix, where the x-axis is the severity and the y-axis is the likelihood.
i need it to be 5x5 because it corresponds to:
X-axis = level of severity (Negligible (1), Minor(2) , Moderate(3), Significant(4) and Major(5)
Y-axis = levels of likelihood (1, 2, 3, 4, 5)
now these values are chosen by the users from a set of answers.
So let's say one question is:
Q: Estimate uncertainty
A1 (severity) : users choose an answer between negligible to major)
A2 (likelihood): users choose an answer between 1-5
there are at least 21 questions all must be answered by likelihood and severity
now these answers should correspond as a coordinate into the matrix.
so if they answer
Q1: (1,3)
Q2: (1,5)
Q3: (1,5)
Q4: (1,1)
and so on..
so there may be coordinates in the matrix that have more than 1 value
so if there are 2 of the same coordinates, it should show 2 in the matrix view.
this is the output of the app. the answers as well as the matrix will be placed into a pdf to be exported as a document.
i hope this clears the purpose of the matrix
import SwiftUI
import UIKit
class MatrixViewController: UIViewController {
let matrix = [
["A5", "B5", "C5", "D5", "E5"],
["A4", "B4", "C4", "D4", "E4"],
["A3", "B3", "C3", "D3", "E3"],
["A2", "B2", "C2", "D2", "E2"],
["A1", "B1", "C1", "D1", "E1"],
]
let matrixLabelSize: CGFloat = 30.0
override func viewDidLoad() {
super.viewDidLoad()
setupMatrixView()
}
func setupMatrixView() {
let matrixView = UIView()
matrixView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(matrixView)
let matrixViewWidth = CGFloat(matrix[0].count) * matrixLabelSize
let matrixViewHeight = CGFloat(matrix.count) * matrixLabelSize
NSLayoutConstraint.activate([
matrixView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
matrixView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
matrixView.widthAnchor.constraint(equalToConstant: matrixViewWidth),
matrixView.heightAnchor.constraint(equalToConstant: matrixViewHeight)
])
var positionCounts: [String: Int] = [:]
//counting the number of occurences - - - - - - this part
for coordinate in coordinates {
let row = coordinate.row
let column = coordinate.column
// Update the count for the position
let key = "\(row)\(column)"
positionCounts[key, default: 0] += 1
}
for rowIndex in 0..<matrix.count {
for colIndex in 0..<matrix[rowIndex].count {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.textAlignment = .center
label.backgroundColor = .white
label.layer.borderColor = UIColor.black.cgColor
label.layer.borderWidth = 1.0
// Get the count from the dictionary based on the position
let key = "\(rowIndex + 1)\(colIndex + 1)"
let count = positionCounts[key, default: 0]
label.text = "\(count)"
matrixView.addSubview(label)
NSLayoutConstraint.activate([
label.leadingAnchor.constraint(equalTo: matrixView.leadingAnchor, constant: CGFloat(colIndex) * matrixLabelSize),
label.topAnchor.constraint(equalTo: matrixView.topAnchor, constant: CGFloat(rowIndex) * matrixLabelSize),
label.widthAnchor.constraint(equalToConstant: matrixLabelSize),
label.heightAnchor.constraint(equalToConstant: matrixLabelSize)
])
}
}
}
struct Coordinate {
let row: Int
let column: Int
let value: String
}
// Define the coordinate values - - - - - THESE COORDINATE VALUES. i want this values to come from the users input
@State var coordinates = [
Coordinate(row: 1, column: 1, value: "A"),
Coordinate(row: 1, column: 1, value: "B"),
Coordinate(row: 1, column: 4, value: "C"),
Coordinate(row: 2, column: 4, value: "D"),
Coordinate(row: 4, column: 4, value: "E"),
Coordinate(row: 3, column: 4, value: "A"),
Coordinate(row: 3, column: 3, value: "B"),
Coordinate(row: 4, column: 3, value: "C"),
Coordinate(row: 4, column: 4, value: "D"),
Coordinate(row: 4, column: 4, value: "E"),
Coordinate(row: 1, column: 4, value: "A"),
Coordinate(row: 2, column: 1, value: "B"),
Coordinate(row: 2, column: 2, value: "C"),
Coordinate(row: 1, column: 2, value: "D"),
Coordinate(row: 1, column: 3, value: "E"),
Coordinate(row: 5, column: 2, value: "A"),
Coordinate(row: 1, column: 5, value: "B"),
Coordinate(row: 1, column: 5, value: "C"),
Coordinate(row: 5, column: 3, value: "D"),
Coordinate(row: 1, column: 4, value: "E"),
Coordinate(row: 5, column: 2, value: "A"),
]
@available(iOS 13.0, *)
struct MatrixViewControllerPreview: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
return MatrixViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
}
}
@available(iOS 13.0, *)
struct MatrixViewController_Previews: PreviewProvider {
static var previews: some View {
MatrixViewControllerPreview().previewDevice("iPhone 12")
}
}
}
for anyone who might have the same question/problem. here's the sample that works as I wanted.
import SwiftUI
struct ContentView: View {
let numberOfRows = 5
let numberOfColumns = 5
@State var matrix: [[Int]] = Array(repeating: Array(repeating: 0, count: 5), count: 5)
@State var selectedRow1 = 0
@State var selectedColumn1 = 0
@State var selectedRow2 = 0
@State var selectedColumn2 = 0
@State var selectedRow3 = 0
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
Form {
Section(header: Text("Question 1")) {
Picker("Select a row:", selection: $selectedRow1) {
ForEach(1...numberOfRows, id: \.self) { row in
Text("\(row)")
}
}
.pickerStyle(SegmentedPickerStyle())
Picker("Select a column:", selection: $selectedColumn1) {
ForEach(1...numberOfColumns, id: \.self) { column in
Text("\(column)")
}
}
.pickerStyle(SegmentedPickerStyle())
}
Section(header: Text("Question 2")) {
Picker("Select a row:", selection: $selectedRow2) {
ForEach(1...numberOfRows, id: \.self) { row in
Text("\(row)")
}
}
.pickerStyle(SegmentedPickerStyle())
Picker("Select a column:", selection: $selectedColumn2) {
ForEach(1...numberOfColumns, id: \.self) { column in
Text("\(column)")
}
}
.pickerStyle(SegmentedPickerStyle())
}
Section(header: Text("Question 3")) {
Picker("Select a row:", selection: $selectedRow3) {
ForEach(1...numberOfRows, id: \.self) { row in
Text("\(row)")
}
}
.pickerStyle(SegmentedPickerStyle())
Picker("Select a column:", selection: $selectedColumn3) {
ForEach(1...numberOfColumns, id: \.self) { column in
Text("\(column)")
}
}
.pickerStyle(SegmentedPickerStyle())
}
}
Button(action: {
resetMatrix()
matrix[selectedRow1 - 1][selectedColumn1 - 1] += 1
matrix[selectedRow2 - 1][selectedColumn2 - 1] += 1
matrix[selectedRow3 - 1][selectedColumn3 - 1] += 1
let selectedValue1 = matrix[selectedRow1 - 1][selectedColumn1 - 1]
let selectedValue2 = matrix[selectedRow2 - 1][selectedColumn2 - 1]
let selectedValue3 = matrix[selectedRow3 - 1][selectedColumn3 - 1]
print("Selected Coordinate (Question 1): (\(selectedRow1), \(selectedColumn1))")
print("Value at Coordinate (Question 1): \(selectedValue1)")
print("Selected Coordinate (Question 2): (\(selectedRow2), \(selectedColumn2))")
print("Value at Coordinate (Question 2): \(selectedValue2)")
print("Selected Coordinate (Question 3): (\(selectedRow3), \(selectedColumn3))")
print("Value at Coordinate (Question 3): \(selectedValue3)")
}) {
Text("Show Selected Coordinates")
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
.padding()
VStack {
ForEach(0..<numberOfRows, id: \.self) { row in
HStack {
ForEach(0..<numberOfColumns, id: \.self) { column in
let value = matrix[row][column]
Text("\(value)")
.frame(width: 50, height: 50)
.border(Color.gray)
.id("\(row)-\(column)")
}
}
}
}
}
.padding()
}
func resetMatrix() {
matrix = Array(repeating: Array(repeating: 0, count: numberOfColumns), count: numberOfRows)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}