struct ImageTest: View {
@State private var selectedPhotos: [PhotosPickerItem] = []
@State private var photosData: [Data] = []
@State private var text: String = ""
var body: some View {
NavigationStack{
Form {
Section {
HStack {
PhotosPicker(selection: $selectedPhotos,
maxSelectionCount: 10,
matching: .images,
photoLibrary: .shared()) {
AddPhotoIcon(numOfImages: photosData.count)
}
.task(id: selectedPhotos) {
for selectedPhoto in selectedPhotos {
if let data = try? await selectedPhoto.loadTransferable(type: Data.self) {
self.photosData.append(data)
}
}
self.selectedPhotos = []
}
if !photosData.isEmpty {
ScrollView(.horizontal) {
HStack {
ForEach(photosData, id: \.self) { data in
if let image = UIImage(data: data) {
Image(uiImage: image)
.resizable()
.scaledToFill()
.frame(width: 50, height: 50)
}
}
}
}
}
Spacer()
}
}
Section {
TextField("Any", text: $text)
}
}
}
}
}
Here with SwiftData I'm making the model that contains images and title.
There is a delay when entering just ten-character text after selecting photos for like 2~3 seconds.
In the debug the memory usage it soars to 700MB.
How can I improve it?
Post
Replies
Boosts
Views
Activity
struct View1: View {
var category: String
var body: some View {
NavigationStack {
List { ...
NavigationLink(value: category) {
Text("Link to View2")
}
}
.navigationDestination(for: String.self) { str in
View2(item: str)
}
}
}
}
struct View2: View {
var item: String
var body: some View {
NavigationStack {
List { ...
NavigationLink(value: category) {
Text("Link to View3")
}
}
.navigationDestination(for: String.self) { str in
View3(number: str)
}
}
}
}
struct View3: View {
var number: String
var body: some View {
List { ... }
}
}
In this code View1 when press one of the List item it says
" there is no matching navigationDestination declaration visible from the location of the link. "
But when I delete the NavigationStack bracket in the View2, then it works. Why is that?
And I want to put the path to the NavigationStack for going to the root. So I think I should leave the NavigationStack in the View2. Is it right? or is there another way?
In the Maps app, when we search for the location
let request = MKLocalSearch.Request()
request.region = // ???
The app automatically searches again when we scroll the map to the other region.
How to do it?
Setting the region to the current view of the map
Tracking map scrolling start and finish
I made simple school & student model with RelationShip
import SwiftUI
import SwiftData
@Model final class School {
var name: String
@Relationship(deleteRule: .cascade, inverse: \Student.school)
var studentList: [Student] = [Student]()
init(name: String) {
self.name = name
}
}
@Model final class Student {
var name: String
var school: School?
init(name: String) {
self.name = name
}
}
~
struct SchoolView: View {
@Environment(\.modelContext) private var modelContext
@Query(sort: \School.name) var schools: [School]
@Query(sort: \Student.name) var students: [Student]
var body: some View {
NavigationStack {
List {
ForEach(schools) { school in
NavigationLink {
StudentView(school: school)
} label: {
HStack {
Text(school.name)
Spacer()
Text("\(school.studentList.count)")
}
}
.swipeActions {
Button(role: .destructive) {
deleteSchool(school)
} label: {
Label("Delete", systemImage: "trash")
}
}
}
.onDelete(perform: deleteSchools(at:))
}
.navigationTitle("Home")
.listStyle(.plain)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button {
addSchool()
} label: {
Image(systemName: "plus")
}
}
ToolbarItem(placement: .topBarLeading) {
VStack(alignment: .leading) {
Text("School: \(schools.count)")
Text("Student: \(students.count)")
}
}
}
}
}
private func randomString() -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<5).map { _ in letters.randomElement()! })
}
private func addSchool() {
let newSchool = School(name: randomString())
modelContext.insert(newSchool)
}
private func deleteSchools(at offsets: IndexSet) {
offsets.map { schools[$0] }.forEach(deleteSchool)
}
private func deleteSchool(_ school: School) {
modelContext.delete(school)
try? modelContext.save()
}
}
struct StudentView: View {
@Environment(\.modelContext) private var modelContext
var school: School
var body: some View {
List {
ForEach(school.studentList) { student in
Text(student.name)
}
.onDelete(perform: deleteStudents(at:))
}
.navigationTitle("Home")
.navigationBarTitleDisplayMode(.inline)
.listStyle(.plain)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button {
addStudent()
} label: {
Image(systemName: "plus")
}
}
}
}
private func addStudent() {
let newSchool = Student(name: randomString())
modelContext.insert(newSchool)
newSchool.school = school
school.studentList.append(newSchool)
}
private func randomString() -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<5).map { _ in letters.randomElement()! })
}
private func deleteStudents(at offsets: IndexSet) {
withAnimation {
offsets.forEach {
let student = school.studentList[$0]
modelContext.delete(student)
try? modelContext.save()
}
}
}
}
I try my best to follow the SampleTrips app from Apple developer.
When I delete one of the schools, then all the students in the school should be deleted. But the student count never changes.
Deleting the student itself works well - the student count decreases.
Thank you!
I'm using SwiftData to save title and images.
When I delete the model, the fetched model count reduces. But in the settings - storage - myApp, the document and data does not change. I deleted all the models but its like 9GB left.
I followed the SwiftData example app provided by Apple as much as possible.
I tried isAutosaveEnabled = false and put save() to every delete functions.
deleteRule = .cascade
I created an app using SwiftData to store titles, dates, and images. When creating and deleting data models repeatedly, the app's storage space should remains the same, but for me it steadily accumulate so now its 5GB in the app's settings despite having no data. Why is this happening?
Is there a way to view the data saved when using swiftdata? Even after deleting all models, the storage space taken up by the app in Settings is too large.
I used Query(filter:sortBy:) and show them in the ListView.
When I change the property of the model, because I fetched filtered and sorted array, the model immediately reflect the change and find its position.
What I want is at initializing it fetches filtered and sorted array. And when I change the property nothing happens. But when I tap on refresh button, then the array should change.
For example in ToDoList app, the array consists of not done works. when I tap done, it should stay until I refresh.
Is it possible?