I am a beginner programmer and doing some SwiftUI. This is a Task Management/todo list app I'm working on for macOS. Each task in the task list relies on a TaskView to display itself, and this TaskView is made up of a HStack with various elements. The text/textfield part does not wrap to the next line, and instead is sort of cut off by dots whenever I drag the window borders in (this is the problem which I want to fix)
The code:
var body: some View {
HStack {
Image(systemName: task.isCompleted ? "checkmark.square.fill" : "stop")
.onTapGesture {
task.isCompleted.toggle()
}
VStack(alignment: .leading) {
if isStrikethrough {
Text(task.title)
.fixedSize(horizontal: false, vertical: true)
.strikethrough(task.isCompleted)
.onTapGesture {
isStrikethrough.toggle()
}
} else {
TextField("New Task", text: $task.title)
.fixedSize(horizontal: false, vertical: true)
.textFieldStyle(.plain)
.strikethrough(task.isCompleted)
}
}
Spacer()
Text("\(dueDateFormatted)")
.foregroundColor(.gray)
.font(.caption)
Button(action: {
// Action for showing popover for editing due date
isEditingDueDate.toggle()
}) {
Image(systemName: "calendar")
}
.popover(isPresented: $isEditingDueDate) {
CalendarPopover(task: $task, isEditingDueDate: $isEditingDueDate)
.frame(width: 250, height: 50) // Set popover size as needed
}
.buttonStyle(PlainButtonStyle())
}
}
private var dueDateFormatted: String {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
return dateFormatter.string(from: task.dueDate)
}
}
The isStrikethrough conditional checks if isStrikethrough is on to enable a strikethrough effect on tasks that are checked, or have an isCompleted feature set to true. I separated it with the conditional as the strikethrough effect doesn't work on textfields, but I need them for editing, so I made it so that a task is text when not being edited/renamed and a textfield when it is.
The above code already includes some modifications I added in hopes of solving the problem, such as .fixedSize(horizontal: false, vertical: true)
and wrapping the text in a VStack as I thought that the HStack could be stopping it from wrapping to the next line.
To clarify, this is what I want to happen when the window borders are dragged in:
And yet, something like this happens instead:
The first image depicts the correct text wrapping, which happens in a separate view called the StaticTaskListView, where the calendar button and due date text are excluded from the HStack. This StaticTaskListView looks like this:
var body: some View {
List {
ForEach(tasks) { task in
VStack(alignment: .leading) {
HStack {
Image(systemName: task.isCompleted ? "checkmark.square.fill" : "stop")
.onTapGesture {
toggleAction(task)
}
Text(task.title)
.strikethrough(task.isCompleted && isStrikethrough)
}
}
}
.onDelete { indexSet in
deleteAction(indexSet)
}
}
In conclusion, I want the text to wrap correctly, as it does in the StaticTaskListView provided above and the first image, while maintaining the extra elements of the HStack in the first code I provided, which is part of the TaskView, depicted in the second image.
This is my first ever post, and I am a beginner programmer. I am sorry if this post made anything unclear or is too long and hard to understand, or if I missed out on any StackOverflow etiquette. Any replies would be very helpful and greatly appreciated.
I think it's the TextField
that is not wrapping.
To make it scrollable (multi-line), just add an axis
parameter:
TextField("New Task", text: $task.title, axis: .vertical)