Here is the code:
class SearchViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
private let label: UILabel = {
let label = UILabel()
label.text = "Where to?"
label.font = .systemFont(ofSize: 24, weight: .semibold)
return label
}()
private let field: UITextField = {
let field = UITextField()
field.placeholder = "Enter destination"
field.layer.cornerRadius = 9
field.backgroundColor = .tertiarySystemBackground
field.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 50))
field.leftViewMode = .always
return field
}()
private let tableView: UITableView = {
let table = UITableView()
table.register(UITableViewCell.self,
forCellReuseIdentifier: "cell")
return table
}()
var locations = [Location]()
override func viewDidLoad() {
view.backgroundColor = .secondarySystemBackground
view.addSubview(label)
view.addSubview(field)
view.addSubview(tableView)
tableView.delegate = self
tableView.dataSource = self
field.delegate
// Do any additional setup after loading the view.
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
label.sizeToFit()
label.frame = CGRect(x: 10, y: 10, width: label.frame.size.width, height: label.frame.size.height)
field.frame = CGRect(x: 10, y: 20+label.frame.size.height, width: view.frame.size.width-20, height: 50)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
field.resignFirstResponder()
if let text = field.text, !text.isEmpty {
LocationMananger.shared.findLocation(with: text) { [weak self] location in
}
}
return true
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return locations.count
}
func tableview(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell",
for: indexPath)
cell.textLabel?.text = locations[indexPath.row].title
cell.textLabel?.numberOfLines = 0
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let coordinate = locations[indexPath.row].coordinates
}
}
Please can you help, I'm realitivly new to swift and I need to finish this problem urgently.
Post
Replies
Boosts
Views
Activity
// Page 1: Map Search
VStack {
ZStack(alignment: .topLeading) {
Map(coordinateRegion: $mapAPI.region, annotationItems: mapAPI.locations) { location in
MapMarker(coordinate: location.coordinate, tint: .red)
}
.ignoresSafeArea()
VStack {
HStack {
TextField("Enter an address", text: $text)
.textFieldStyle(.roundedBorder)
.padding(.horizontal)
.foregroundColor(.black)
Button(action: {
fetchLocationInfoFromWikipedia(for: text)
mapAPI.getLocation(address: text, delta: 0.5)
showLocationInfo = true
}) {
Image(systemName: "magnifyingglass")
.foregroundColor(.black)
}
.padding(.leading, -50)
}
.padding()
if showLocationInfo {
VStack {
Spacer()
Rectangle()
.fill(Color.white)
.frame(height: 250)
.frame(width: 400)
.cornerRadius(15)
.overlay(
ScrollView {
Text(locationInfo)
.foregroundColor(.black)
.padding(.horizontal, 10)
.font(.system(size: 14))
.font(.custom("Serif", fixedSize: 14))
}
.padding()
)
.padding(.horizontal, 20)
.padding(.bottom, 10) // Adjust the bottom padding here
HStack(spacing: 70) {
Button(action: {
// Open YouTube search with address
openWebsite("https://www.youtube.com/results?search_query=\(encodedAddress)")
}) {
Image(systemName: "play.circle")
.foregroundColor(.black)
}
Button(action: {
// Open Google Maps with address
openWebsite("https://www.google.com/maps/place/\(encodedAddress)")
}) {
Image(systemName: "map")
.foregroundColor(.black)
}
Button(action: {
// Open Google Earth with address
openWebsite("https://earth.google.com/web/search/\(encodedAddress)/")
}) {
Image(systemName: "globe")
.foregroundColor(.black)
}
}
.frame(maxWidth: .infinity-10) // Expand the HStack to full width
.padding(.vertical, 10) // Adjust the vertical padding here
.background(Color.white) // Set background color to white
.cornerRadius(10) // Apply corner radius
.padding(.horizontal, 20)
.padding(.bottom, 20)
.padding(.top, -10)// Adjust the horizontal padding here
}
}
}
}
}
.tabItem {
Image(systemName: "location.circle.fill")
Text("Map")
}
// Page 2: Photos
VStack {
Button(action: {
showImagePicker = true
selectedImageSourceType = .photoLibrary
}) {
Image(systemName: "photo")
.font(.title)
.foregroundColor(.black)
}
.padding()
.sheet(isPresented: $showImagePicker, onDismiss: loadImage) {
ImagePicker(sourceType: selectedImageSourceType ?? .photoLibrary) { image in
selectedImage = image
}
}
Button(action: {
showImagePicker = true
selectedImageSourceType = .camera
}) {
Image(systemName: "camera")
.font(.title)
.foregroundColor(.black)
}
.padding()
.sheet(isPresented: $showImagePicker, onDismiss: loadImage) {
ImagePicker(sourceType: selectedImageSourceType ?? .photoLibrary) { image in
selectedImage = image
}
}
if !images.isEmpty {
ScrollView {
LazyVGrid(columns: [GridItem(.adaptive(minimum: 120))], spacing: 10) {
ForEach(images, id: \.self) { image in
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(height: 120)
.cornerRadius(10)
}
}
.padding()
}
} else {
Text("No photos available")
.foregroundColor(.gray)
}
}
struct ImagePicker: UIViewControllerRepresentable {
typealias UIViewControllerType = UIImagePickerController
var sourceType: UIImagePickerController.SourceType
var completionHandler: (UIImage?) -> Void
func makeUIViewController(context: Context) -> UIImagePickerController {
let imagePicker = UIImagePickerController()
imagePicker.sourceType = sourceType
imagePicker.delegate = context.coordinator
return imagePicker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {
// No update needed
}
func makeCoordinator() -> Coordinator {
Coordinator(completionHandler: completionHandler)
}
final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
private let completionHandler: (UIImage?) -> Void
init(completionHandler: @escaping (UIImage?) -> Void) {
self.completionHandler = completionHandler
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else {
completionHandler(nil)
picker.dismiss(animated: true)
return
}
completionHandler(image)
picker.dismiss(animated: true)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
completionHandler(nil)
picker.dismiss(animated: true)
}
}
}
var body: some View {
TabView {
// Page 1: Map Search
// Page 2: Photos
VStack {
Spacer()
Menu {
Button(action: {
showImagePicker = true
selectedImageSourceType = .photoLibrary
}) {
Label("Choose from Library", systemImage: "photo")
}
Button(action: {
showImagePicker = true
selectedImageSourceType = .camera
}) {
Label("Take Photo", systemImage: "camera")
}
} label: {
Text("Memories")
.font(.title)
.foregroundColor(.black)
}
.padding()
.sheet(isPresented: $showImagePicker, onDismiss: loadImage) {
ImagePicker(sourceType: selectedImageSourceType ?? .photoLibrary) { image in
selectedImage = image
}
}
.padding()
.sheet(isPresented: $showImagePicker, onDismiss: loadImage) {
ImagePicker(sourceType: selectedImageSourceType ?? .photoLibrary) { image in
selectedImage = image
}
}
if !images.isEmpty {
ScrollView {
LazyVGrid(columns: [GridItem(.adaptive(minimum: 200, maximum: 700))], spacing: 20) {
ForEach(images, id: \.self) { image in
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(height: UIScreen.main.bounds.height / 5)
.frame(width: UIScreen.main.bounds.width - 60)
.cornerRadius(15)
}
}
.padding()
}
} else {
Text("No photos available")
.foregroundColor(.gray)
}
}
.tabItem {
Image(systemName: "camera")
Text("Memories")
}
.tag(1)
}
.accentColor(.blue)
}
@State private var encodedAddress = ""
func fetchLocationInfoFromWikipedia(for address: String) {
guard let encodedAddress = address.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let url = URL(string: "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&exintro=true&explaintext=true&titles=\(encodedAddress)") else {
self.encodedAddress = encodedAddress
return
}
URLSession.shared.dataTask(with: url) { data, _, error in
if let data = data {
if let responseJSON = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
let query = responseJSON["query"] as? [String: Any],
let pages = query["pages"] as? [String: Any],
let page = pages.keys.first,
let pageData = pages[page] as? [String: Any],
let extract = pageData["extract"] as? String {
DispatchQueue.main.async {
self.locationInfo = extract
}
}
}
}
.resume()
}
func openWebsite(_ urlString: String) {
if let encodedAddress = self.text.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let url = URL(string: urlString + encodedAddress) {
UIApplication.shared.open(url)
}
}
func loadImage() {
guard let selectedImage = selectedImage else { return }
images.append(selectedImage)
self.selectedImage = nil
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I am using mapkit and when i try to move around on the map i get glitches and issues can anyone fix.
import SwiftUI
import MapKit
import CoreLocation
struct ContentView: View {
@StateObject private var mapAPI = MapAPI()
@State private var text = ""
@State private var locationInfo: String = ""
@State private var showLocationInfo = false
@State private var imageUrls = [String]() // Array to store image URLs
@State private var locationManager = CLLocationManager()
@State private var isMovingOnMap = false
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
if manager.authorizationStatus == .authorizedWhenInUse {
locationManager.startUpdatingLocation()
}
}
@State private var showImagePicker = false
@State private var showCamera = false
@State private var selectedImage: UIImage?
@State private var images: [UIImage] = []
@State private var selectedImageSourceType: UIImagePickerController.SourceType?
struct ImagePicker: UIViewControllerRepresentable {
typealias UIViewControllerType = UIImagePickerController
var sourceType: UIImagePickerController.SourceType
var completionHandler: (UIImage?) -> Void
func makeUIViewController(context: Context) -> UIImagePickerController {
let imagePicker = UIImagePickerController()
imagePicker.sourceType = sourceType
imagePicker.delegate = context.coordinator
return imagePicker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {
// No update needed
}
func makeCoordinator() -> Coordinator {
Coordinator(completionHandler: completionHandler)
}
final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
private let completionHandler: (UIImage?) -> Void
init(completionHandler: @escaping (UIImage?) -> Void) {
self.completionHandler = completionHandler
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else {
completionHandler(nil)
picker.dismiss(animated: true)
return
}
completionHandler(image)
picker.dismiss(animated: true)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
completionHandler(nil)
picker.dismiss(animated: true)
}
}
}
var body: some View {
TabView {
// Page 1
ZStack(alignment: .topLeading) {
Map(coordinateRegion: $mapAPI.region, interactionModes: .all, showsUserLocation: true)
.edgesIgnoringSafeArea(.all)
.gesture(
DragGesture()
.onChanged { gesture in
isMovingOnMap = true
showLocationInfo = false
let translation = gesture.translation
let currentRegion = mapAPI.region
// Check if the horizontal drag distance is larger than the vertical distance
if abs(translation.width) > abs(translation.height) {
// Update the map's center coordinate based on the horizontal drag
let mapWidth = UIScreen.main.bounds.size.width
let coordinateSpan = currentRegion.span.longitudeDelta * Double(mapWidth) / 360.0
let coordinateDelta = CLLocationDegrees(translation.width) * coordinateSpan / Double(mapWidth)
let updatedCenter = CLLocationCoordinate2D(latitude: currentRegion.center.latitude, longitude: currentRegion.center.longitude - coordinateDelta)
let updatedRegion = MKCoordinateRegion(center: updatedCenter, span: currentRegion.span)
DispatchQueue.main.async {
mapAPI.region = updatedRegion
}
} else {
// Update the map's region for vertical or diagonal drags (zooming)
let span = currentRegion.span
let spanMultiplier = min(span.latitudeDelta, span.longitudeDelta) / 500.0
let latitudeDelta = span.latitudeDelta - (translation.height * spanMultiplier)
let longitudeDelta = span.longitudeDelta - (translation.width * spanMultiplier)
let updatedRegion = MKCoordinateRegion(center: currentRegion.center, span: MKCoordinateSpan(latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta))
DispatchQueue.main.async {
mapAPI.region = updatedRegion
}
}
}
.onEnded { _ in
isMovingOnMap = false
}
)
VStack {
HStack {
So basically I can tell that the images are being saved by the system (it shows it on the debug terminal) however whenever I close, and then reopen the app the images firstly aren't there at all but also whenever I search the address name I saved them as... I have tried diagonsing the problem by changing UUID's, changing PNGs to JPGS - no matter what I do it does not show once the application has closed. I think it might have to do with how the image are .HEIF (apple's standard) but I don't have any concrete evidence to back this up. If anyone can help it would be greatly apperciated.
import SwiftUI
import MapKit
import CoreLocation
struct ContentView: View {
@StateObject private var mapAPI = MapAPI()
@State private var text = ""
@State private var locationInfo: String = ""
@State private var showLocationInfo = false
@State private var imageUrls = [String]() // Array to store image URLs
@State private var showImagePicker = false
@State private var showCamera = false
@State private var selectedImage: UIImage?
@State private var images: [UIImage] = []
@State private var selectedImageSourceType: UIImagePickerController.SourceType?
struct ImageInfo: Identifiable {
let id = UUID()
let address: String
let imageUrl: URL
}
...
// Page 2: Photo
VStack {
Spacer()
Menu {
Button(action: {
showImagePicker = true
selectedImageSourceType = .photoLibrary
}) {
Label("Choose from Library", systemImage: "photo")
}
Button(action: {
showImagePicker = true
selectedImageSourceType = .camera
}) {
Label("Take Photo", systemImage: "camera")
}
} label: {
Text("Memories")
.font(.title)
.foregroundColor(.black)
}
.padding()
.sheet(isPresented: $showImagePicker, onDismiss: loadImage) {
ImagePicker(sourceType: selectedImageSourceType ?? .photoLibrary) { image in
selectedImage = image
}
}
if !images.isEmpty {
ScrollView {
LazyVGrid(columns: [GridItem(.adaptive(minimum: 200, maximum: 700))], spacing: 20) {
ForEach(images, id: \.self) { image in
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(height: UIScreen.main.bounds.height / 5)
.frame(width: UIScreen.main.bounds.width - 60)
.cornerRadius(15)
}
}
.padding()
}
} else {
Text("No photos available")
.foregroundColor(.gray)
}
}
.tabItem {
Image(systemName: "camera")
Text("Memories")
}
.tag(1)
}
.accentColor(.black)
}
@State private var encodedAddress = ""
func fetchLocationInfoFromWikipedia(for address: String) {
guard let encodedAddress = address.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let url = URL(string: "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&exintro=true&explaintext=true&titles=\(encodedAddress)") else {
self.encodedAddress = encodedAddress
return
}
URLSession.shared.dataTask(with: url) { data, _, error in
if let data = data {
if let responseJSON = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
let query = responseJSON["query"] as? [String: Any],
let pages = query["pages"] as? [String: Any],
let page = pages.keys.first,
let pageData = pages[page] as? [String: Any],
let extract = pageData["extract"] as? String {
DispatchQueue.main.async {
self.locationInfo = extract
}
}
}
}
.resume()
}
func openWebsite(_ urlString: String) {
if let encodedAddress = self.text.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let url = URL(string: urlString + encodedAddress) {
UIApplication.shared.open(url)
}
}
func loadImage() {
guard let selectedImage = selectedImage else { return }
images.append(selectedImage)
saveImage(selectedImage)
self.selectedImage = nil
}
func saveImage(_ image: UIImage) {
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let filename = UUID().uuidString
let fileURL = documentsDirectory.appendingPathComponent(filename)
if let imageData = image.jpegData(compressionQuality: 1.0) {
do {
try imageData.write(to: fileURL)
print("Image saved at: \(fileURL)")
} catch {
print("Error saving image data: \(error.localizedDescription)")
}
}
}
func loadSavedImages() {
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
do {
let fileURLs = try FileManager.default.contentsOfDirectory(at: documentsDirectory, includingPropertiesForKeys: nil, options: [])
let imageFiles = fileURLs.filter { $0.pathExtension == "png" || $0.pathExtension == "png" }
for fileURL in imageFiles {
if let imageData = try? Data(contentsOf: fileURL),
let image = UIImage(data: imageData) {
images.append(image)
}
}
} catch {
print("Error loading saved images: \(error.localizedDescription)")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
So basically I can tell that the images are being saved by the system (it shows it on the debug terminal) however whenever I close, and then reopen the app the images firstly aren't there at all but also whenever I search the address name I saved them as... I have tried diagonsing the problem by changing UUID's, changing PNGs to JPGS - no matter what I do it does not show once the application has closed. I think it might have to do with how the image are .HEIF (apple's standard) but I don't have any concrete evidence to back this up. If anyone can help it would be greatly apperciated.
import SwiftUI
import MapKit
import CoreLocation
struct ContentView: View {
@StateObject private var mapAPI = MapAPI()
@State private var text = ""
@State private var locationInfo: String = ""
@State private var showLocationInfo = false
@State private var imageUrls = [String]() // Array to store image URLs
@State private var showImagePicker = false
@State private var showCamera = false
@State private var selectedImage: UIImage?
@State private var images: [UIImage] = []
@State private var selectedImageSourceType: UIImagePickerController.SourceType?
struct ImageInfo: Identifiable {
let id = UUID()
let address: String
let imageUrl: URL
}
...
// Page 2: Photo
VStack {
Spacer()
Menu {
Button(action: {
showImagePicker = true
selectedImageSourceType = .photoLibrary
}) {
Label("Choose from Library", systemImage: "photo")
}
Button(action: {
showImagePicker = true
selectedImageSourceType = .camera
}) {
Label("Take Photo", systemImage: "camera")
}
} label: {
Text("Memories")
.font(.title)
.foregroundColor(.black)
}
.padding()
.sheet(isPresented: $showImagePicker, onDismiss: loadImage) {
ImagePicker(sourceType: selectedImageSourceType ?? .photoLibrary) { image in
selectedImage = image
}
}
if !images.isEmpty {
ScrollView {
LazyVGrid(columns: [GridItem(.adaptive(minimum: 200, maximum: 700))], spacing: 20) {
ForEach(images, id: \.self) { image in
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(height: UIScreen.main.bounds.height / 5)
.frame(width: UIScreen.main.bounds.width - 60)
.cornerRadius(15)
}
}
.padding()
}
} else {
Text("No photos available")
.foregroundColor(.gray)
}
}
.tabItem {
Image(systemName: "camera")
Text("Memories")
}
.tag(1)
}
.accentColor(.black)
}
@State private var encodedAddress = ""
func fetchLocationInfoFromWikipedia(for address: String) {
guard let encodedAddress = address.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let url = URL(string: "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&exintro=true&explaintext=true&titles=\(encodedAddress)") else {
self.encodedAddress = encodedAddress
return
}
URLSession.shared.dataTask(with: url) { data, _, error in
if let data = data {
if let responseJSON = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
let query = responseJSON["query"] as? [String: Any],
let pages = query["pages"] as? [String: Any],
let page = pages.keys.first,
let pageData = pages[page] as? [String: Any],
let extract = pageData["extract"] as? String {
DispatchQueue.main.async {
self.locationInfo = extract
}
}
}
}
.resume()
}
func openWebsite(_ urlString: String) {
if let encodedAddress = self.text.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let url = URL(string: urlString + encodedAddress) {
UIApplication.shared.open(url)
}
}
func loadImage() {
guard let selectedImage = selectedImage else { return }
images.append(selectedImage)
saveImage(selectedImage)
self.selectedImage = nil
}
func saveImage(_ image: UIImage) {
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let filename = UUID().uuidString
let fileURL = documentsDirectory.appendingPathComponent(filename)
if let imageData = image.jpegData(compressionQuality: 1.0) {
do {
try imageData.write(to: fileURL)
print("Image saved at: \(fileURL)")
} catch {
print("Error saving image data: \(error.localizedDescription)")
}
}
}
func loadSavedImages() {
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
do {
let fileURLs = try FileManager.default.contentsOfDirectory(at: documentsDirectory, includingPropertiesForKeys: nil, options: [])
let imageFiles = fileURLs.filter { $0.pathExtension == "png" || $0.pathExtension == "png" }
for fileURL in imageFiles {
if let imageData = try? Data(contentsOf: fileURL),
let image = UIImage(data: imageData) {
images.append(image)
}
}
} catch {
print("Error loading saved images: \(error.localizedDescription)")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I'm working on a functionality on my code - where it will add a flag to the map once an image is added to the app (via the second page, not shown) but it just doesn't perform how I want. Basically the photo saving is working perfectly and shows via the terminal where and how something is saving and the flags or pins that are added to the map also do save however just to see the you have to go to the second page (press on it) and come back to page 1 (Map) to see them - I just want to be able to see them from the start of the app. I tried init() { loadSavedImages(for: "") loadSavedImageLocations()
but this doesn't really help much - if anyone can help it would really be apperciated.
import SwiftUI
import MapKit
import CoreLocation
import UIKit
struct MapView: UIViewRepresentable {
@Binding var region: MKCoordinateRegion
@Binding var mapType: MKMapType
var imageLocations: [CLLocationCoordinate2D]
@Binding var weatherInfo: String
@Binding var showWeatherInfo: Bool
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.setRegion(region, animated: true)
mapView.mapType = mapType
// Add annotations for image locations
mapView.addAnnotations(imageLocations.map { location in
let annotation = ImageAnnotation(coordinate: location)
return annotation
})
...
class ImageAnnotation: NSObject, MKAnnotation {
let coordinate: CLLocationCoordinate2D
init(coordinate: CLLocationCoordinate2D) {
self.coordinate = coordinate
super.init()
}
}
struct ImageLocation: Codable {
let latitude: Double
let longitude: Double
init(coordinate: CLLocationCoordinate2D) {
self.latitude = coordinate.latitude
self.longitude = coordinate.longitude
}
...
private init() {}
func saveImageLocation(_ location: CLLocationCoordinate2D) {
var savedLocations = getSavedLocations()
let imageLocation = ImageLocation(coordinate: location)
savedLocations.append(imageLocation)
do {
let data = try JSONEncoder().encode(savedLocations)
let fileURL = documentsDirectory.appendingPathComponent("ImageLocations.json")
try data.write(to: fileURL)
} catch {
print("Error saving image locations: \(error.localizedDescription)")
}
}
func getSavedLocations() -> [ImageLocation] {
let fileURL = documentsDirectory.appendingPathComponent("ImageLocations.json")
guard let data = try? Data(contentsOf: fileURL) else {
return []
}
...
struct ImageInfo: Identifiable {
let id = UUID()
let address: String
let imageUrl: URL
}
init() {
loadSavedImages(for: "")
loadSavedImageLocations() // Load saved image locations when the app launches
}
...
MapView(region: $mapAPI.region, mapType: $mapType, imageLocations: imageLocations,
weatherInfo: $weatherInfo, showWeatherInfo: $showWeatherInfo)
.ignoresSafeArea()
....
// Page 2: Photo
VStack {
Spacer()
Menu {
Button(action: {
showImagePicker = true
selectedImageSourceType = .photoLibrary
}) {
Label("Choose from Library", systemImage: "photo")
}
Button(action: {
showImagePicker = true
selectedImageSourceType = .camera
}) {
}
} label: {
Text("Memories")
.font(.title)
...
.onAppear {
loadSavedImages(for: text)
loadSavedImageLocations()
...
func saveImage(_ image: UIImage, for address: String) {
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
// Generate a unique filename based on address and timestamp
let timestamp = Int(Date().timeIntervalSince1970)
let filename = "\(address)_\(timestamp).jpg"
let fileURL = documentsDirectory.appendingPathComponent(filename)
if let imageData = image.jpegData(compressionQuality: 0.5) {
do {
try imageData.write(to: fileURL)
print("Image saved at: \(fileURL)")
// Add the file URL to the imageUrls array
let imageInfo = ImageInfo(address: address, imageUrl: fileURL)
imageUrls.append(imageInfo)
} catch {
print("Error saving image data: \(error.localizedDescription)")
}
// Append the location to the imageLocations array
if let location = mapAPI.locations.last?.coordinate {
imageLocations.append(location)
}
}
}
func loadSavedImages(for address: String) {
images = [] // Clear the existing images
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
do {
let fileURLs = try FileManager.default.contentsOfDirectory(at: documentsDirectory, includingPropertiesForKeys: nil, options: [])
// Filter and get file URLs for the images associated with the specified address
let imageFiles = fileURLs
.filter { $0.pathExtension == "jpg" }
.filter { $0.lastPathComponent.contains(address + "_") }
for fileURL in imageFiles {
if let imageData = try? Data(contentsOf: fileURL),
let image = UIImage(data: imageData) {
images.append(image)
}
}
} catch {
print("Error loading saved images: \(error.localizedDescription)")
}
}
func loadSavedImageLocations() {
let savedLocations = ImageDataManager.shared.getSavedLocations()
imageLocations = savedLocations.map { $0.locationCoordinate }
}
func deleteImage(at index: Int) {
let imageInfo = imageUrls[index]
let fileManager = FileManager.default
do {
try fileManager.removeItem(at: imageInfo.imageUrl)
images.remove(at: index)
imageUrls.remove(at: index)
} catch {
print("Error deleting image: \(error.localizedDescription)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
}
This is part of the code from my project - the issue that I am getting is that the bottom sheet when it appears it appears infront of the tabview items - while I want it to appear behind the tabview.
import SwiftUI
import MapKit
import CoreLocation
import UIKit
...
struct ContentView: View {
@State private var mapType: MKMapType = .standard
@State private var selectedTab = 0
@State private var ShowingBottomSheet = false
...
VStack {
ZStack(alignment: .topLeading) {
MapView(region: $mapAPI.region, mapType: $mapType, imageLocations: imageLocations,
weatherInfo: $weatherInfo, showWeatherInfo: $showWeatherInfo)
.ignoresSafeArea(edges: .top)
VStack {
HStack {
TextField("Enter an address", text: $text, onCommit: {
fetchLocationInfoFromWikipedia(for: text)
mapAPI.getLocation(address: text, delta: 0.5)
showLocationInfo = true
ShowingBottomSheet.toggle()
// Save the image location
if let location = mapAPI.locations.last?.coordinate {
ImageDataManager.shared.saveImageLocation(location)
}
})
.textFieldStyle(.roundedBorder)
.padding(.horizontal)
.foregroundColor(.black)
.frame(width: UIScreen.main.bounds.size.width - 40)
.sheet(isPresented: $ShowingBottomSheet, content: {
ZStack(content: {
ScrollView {
Text(locationInfo)
.foregroundColor(.black)
.frame(maxWidth: .infinity, alignment: .leading)
.padding()
.fixedSize(horizontal: false, vertical: true)
.font(.custom("SanFranciscoDisplay-Bold", size: 13))
}
})
.presentationDetents([.fraction(0.2), .fraction(0.4), .fraction(0.6)])
.zIndex(1)
})
...
}
.zIndex(0)
}
.tabItem {
Image(systemName: "location.circle.fill")
.accentColor(.black)
Text("Map")
}
.tag(0)
...
}
.tag(1)
...
}
.tag(3)
}
.accentColor(.black)
}
...