Hi DevForum team, I'm struggling with some code around designing with proper frame size for Text which give issues with different iPhone size,
below full code working perfectly on iPhone 15-14, but not iPhone 14Pro & Xr crash happen ( when I try to understand the crash ... try lol , read between lines) it's all about frame and size so I believe it's about the phone size and the pixel taken from the .frame of the Text
one more weird thing happen when I look at the code I share below directly thru preview of TimekeyinList the rendering is very nice,
but when I look at it from the contentViewtab View I get this ****** finish any idea why ?
import SwiftUI
struct TimeKeyinList: View {
@Environment(ModelData.self) var modelData
let projects = ModelData().projects
@State var isSet: [Bool] = [false, false, false, false, false,false,false,false]
var filteredNonTECOProjects: [Project] {
// removeTECO project
modelData.projects.filter { project in
!project.isTeco
}}
var body: some View {
VStack {
HStack {
Text("TIME KEY_IN")
.font(.title)
.multilineTextAlignment(.leading)
.bold()
Spacer()
Text("8h")
.font(.title)
.multilineTextAlignment(.leading)
.bold()
}.padding()
Spacer()
VStack(spacing: 5){
HStack(alignment: .top) {
Text(" Project Name")
.multilineTextAlignment(.leading)
.lineLimit(2)
.frame(width: 120.0) // <<-- To get proper alignment
Text(".5h")
Text("1h")
Text("2h")
Text("3h")
Text("4h")
Text("8h")
Text("Time Left")
.multilineTextAlignment(.trailing)
.lineLimit(2)
.frame(width: 50)
}
VStack(spacing: 20) {
BlankKeyInRow()
ForEach(Array(filteredNonTECOProjects.enumerated()), id: \.offset) { (row, project) in
if project .isSpecific {
BlankKeyInRow()
BlankKeyInRow()
TimeKeyInRow(id: project.shortname, project: project, isSet: $isSet[row])
} else {
TimeKeyInRow(id: project.shortname, project: project, isSet: $isSet[row])
}
}
}
.listStyle(.inset)
DatePicker(selection: /*@START_MENU_TOKEN@*/.constant(Date())/*@END_MENU_TOKEN@*/, label: { /*@START_MENU_TOKEN@*/Text("Date")/*@END_MENU_TOKEN@*/ })
}
.environment(\.sizeCategory, .extraExtraExtraLarge)
.labelsHidden()
Spacer()
.onAppear() {
// <<-- Added
for (row, project) in filteredNonTECOProjects.enumerated() {
isSet[row] = !project.isTeco
}
}
Spacer()
}
}
}
struct TimeKeyinList_Previews2: PreviewProvider {
static var previews: some View {
//#Preview
TimeKeyinList().environment(ModelData())
}
}
second file
import SwiftUI
struct TimeKeyInRow: View,Identifiable {
var id: String
var project: Project
@Binding var isSet: Bool
let listOfPossibleHours: [Double] = [0.5,1,2,3,4,8]
var body: some View {
HStack {
Text(project.shortname.paddedToWidth(10)) // Text(projects[1].shortname)
.font(.custom("Menlo", size: 16))
.frame(width: 120.0) // <<-- To get proper alignment
Spacer()
ForEach(listOfPossibleHours, id: \.self) { hour in
HourButton(id: "\(project.shortname)", isSet: isSet, value: hour)
}
Text("\(project.leftPMtime)")
.font(.custom("Menlo", size: 16))
.multilineTextAlignment(.leading)
.frame(width: 45) // <<-- To get proper alignment
}
}
}
struct TimeKeyInRow_Previews: PreviewProvider {
static var previews: some View {
//#Preview {
let projects = ModelData().projects
TimeKeyInRow(id: "test", project: projects[2], isSet: .constant(true))
}
}
extension String { // To align text
func paddedToWidth(_ width: Int) -> String {
let length = self.count
guard length < width else {
return self
}
let spaces = Array<Character>.init(repeating: " ", count: width - length)
return self + spaces
}
}
struct BlankKeyInRow: View {
var body: some View {
HStack {
Text("") // Text(projects[1].shortname)
}
}
}
and the starting button point
import SwiftUI
struct HourButton: View,Identifiable {
var id: String = "hour"
@State var isSet: Bool
var value: Double
var body: some View {
HStack {
Button {
isSet.toggle()
print("clic on Project : \(id) an turn to : \(isSet) for \(value)h")
if isSet == true {
print("true is \(isSet)")
} else {
print("false is\(isSet)")
}
} label: {
Label("8h", systemImage: isSet ? "circle.fill" : "circle")
.labelStyle(.iconOnly)
.foregroundStyle(isSet ? .blue : .gray)
}.id(id)
}
}
}
struct HourButton_Previews: PreviewProvider {
static var previews: some View {
//#Preview {
HourButton(id: "MORN", isSet: true, value: 3)
}
}