feat(searchItem): style search item, move route
This commit is contained in:
		| @@ -30,11 +30,11 @@ struct ContentView: View { | |||||||
|                         .stroke(Constants.routeColor[i], lineWidth: Constants.routeWidth) |                         .stroke(Constants.routeColor[i], lineWidth: Constants.routeWidth) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         //            .ignoresSafeArea() |  | ||||||
|         .sheet( |         .sheet( | ||||||
|             isPresented: $showSearch, |             isPresented: $showSearch, | ||||||
|             content: { |             content: { | ||||||
|                 SearchView(directions: $directions) |                 SearchView(directions: $directions) | ||||||
|  |                     .ignoresSafeArea() | ||||||
|             }) |             }) | ||||||
|         //        Text("This is what's set: \(viewModel.test)") |         //        Text("This is what's set: \(viewModel.test)") | ||||||
|         //        Button(action: { |         //        Button(action: { | ||||||
|   | |||||||
| @@ -10,8 +10,175 @@ import SwiftUI | |||||||
|  |  | ||||||
| struct SearchItemView: View { | struct SearchItemView: View { | ||||||
|     var location: MKMapItem |     var location: MKMapItem | ||||||
|  |     @State var distance: CLLocationDistance? | ||||||
|  |     @Binding var directions: [MKRoute] | ||||||
|  |     @State var localDirections: [MKRoute] = [] | ||||||
|  |  | ||||||
|     var body: some View { |     var body: some View { | ||||||
|  |  | ||||||
|  |         Button( | ||||||
|  |             action: { | ||||||
|  |                 if localDirections == [] { | ||||||
|  |                     findDirections() | ||||||
|  |                 } | ||||||
|  |                 directions = localDirections | ||||||
|  |             }, | ||||||
|  |             label: { | ||||||
|  |                 HStack { | ||||||
|  |                     Circle() | ||||||
|  |                         .padding() | ||||||
|  |                         .overlay(alignment: .center) { | ||||||
|  |                             Image( | ||||||
|  |                                 systemName: Defaults.getIconFor( | ||||||
|  |                                     pointOfInterest: location.pointOfInterestCategory) | ||||||
|  |                             ) | ||||||
|  |                             .foregroundStyle(.white) | ||||||
|  |                             .font(.title) | ||||||
|  |                         } | ||||||
|  |                         .foregroundStyle(.green) | ||||||
|  |                     //            Spacer() | ||||||
|  |                     HStack { | ||||||
|  |                         VStack { | ||||||
|  |                             HStack { | ||||||
|                                 Text("\(location.name ?? "")") |                                 Text("\(location.name ?? "")") | ||||||
|  |                                     .foregroundStyle(.black) | ||||||
|  |                                     .font(.title3) | ||||||
|  |                                     .lineLimit(1) | ||||||
|  |                                 Spacer() | ||||||
|  |                             } | ||||||
|  |                             HStack { | ||||||
|  |                                 Text("\(location.placemark.locality ?? "")") | ||||||
|  |                                     //                    .font(.) | ||||||
|  |                                     .foregroundStyle(.gray) | ||||||
|  |                                 Spacer() | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|  |                         if distance != nil { | ||||||
|  |                             Text("\(formatDistance(distance: distance!))") | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     Spacer() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ) | ||||||
|  |         .frame(height: 100) | ||||||
|  |         .onAppear { | ||||||
|  |             findDirections() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     func formatDistance(distance: CLLocationDistance) -> String { | ||||||
|  |         let distanceFormatter = MKDistanceFormatter() | ||||||
|  |         return distanceFormatter.string(fromDistance: distance) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     func findDirections() { | ||||||
|  |         let directionsRequest = MKDirections.Request() | ||||||
|  |         //        directionsRequest.source = MKMapItem.forCurrentLocation() | ||||||
|  |         directionsRequest.source = MKMapItem.init( | ||||||
|  |             placemark: MKPlacemark( | ||||||
|  |                 coordinate: CLLocationCoordinate2D(latitude: 52.3676, longitude: 4.9041))) | ||||||
|  |         directionsRequest.destination = location | ||||||
|  |         directionsRequest.transportType = .walking | ||||||
|  |         directionsRequest.requestsAlternateRoutes = false  // TODO: make alternative routes available | ||||||
|  |         directionsRequest.departureDate = .now | ||||||
|  |  | ||||||
|  |         let searchDirections = MKDirections(request: directionsRequest) | ||||||
|  |         searchDirections.calculate { (response, error) in | ||||||
|  |             guard let response = response else { | ||||||
|  |                 print(error ?? "") | ||||||
|  |                 print("Error while searching for directions") | ||||||
|  |                 return | ||||||
|  |             } | ||||||
|  |             self.localDirections = response.routes | ||||||
|  |             self.distance = response.routes.first?.distance | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     struct Defaults { | ||||||
|  |         static let pointOfInterestIcons: [MKPointOfInterestCategory: String] = [ | ||||||
|  |             .museum: "building.columns.fill", | ||||||
|  |             .musicVenue: "music.note.house.fill", | ||||||
|  |             .theater: "theatermasks.fill", | ||||||
|  |             .library: "books.vertical.fill", | ||||||
|  |             .planetarium: "sparkles", | ||||||
|  |             .school: "graduationcap.fill", | ||||||
|  |             .university: "building.columns.fill", | ||||||
|  |             .movieTheater: "film.fill", | ||||||
|  |             .nightlife: "music.mic", | ||||||
|  |             .fireStation: "flame.fill", | ||||||
|  |             .hospital: "cross.case.fill", | ||||||
|  |             .pharmacy: "cross.fill", | ||||||
|  |             .police: "shield.fill", | ||||||
|  |             .castle: "building.fill", | ||||||
|  |             .fortress: "shield.lefthalf.filled", | ||||||
|  |             .landmark: "building.columns.fill", | ||||||
|  |             .nationalMonument: "star.circle.fill", | ||||||
|  |             .bakery: "takeoutbag.and.cup.and.straw", | ||||||
|  |             .brewery: "mug.fill", | ||||||
|  |             .cafe: "cup.and.saucer.fill", | ||||||
|  |             .distillery: "wineglass.fill", | ||||||
|  |             .foodMarket: "cart.fill", | ||||||
|  |             .restaurant: "fork.knife", | ||||||
|  |             .winery: "wineglass", | ||||||
|  |             .animalService: "pawprint.fill", | ||||||
|  |             .atm: "creditcard.fill", | ||||||
|  |             .automotiveRepair: "wrench.and.screwdriver.fill", | ||||||
|  |             .bank: "building.columns.fill", | ||||||
|  |             .beauty: "scissors", | ||||||
|  |             .evCharger: "bolt.car.fill", | ||||||
|  |             .fitnessCenter: "dumbbell.fill", | ||||||
|  |             .laundry: "washer.fill", | ||||||
|  |             .mailbox: "envelope.fill", | ||||||
|  |             .postOffice: "envelope.fill", | ||||||
|  |             .restroom: "figure.restroom", | ||||||
|  |             .spa: "drop.fill", | ||||||
|  |             .store: "bag.fill", | ||||||
|  |             .amusementPark: "ferriswheel", | ||||||
|  |             .aquarium: "tortoise.fill", | ||||||
|  |             .beach: "beach.umbrella.fill", | ||||||
|  |             .campground: "tent.fill", | ||||||
|  |             .fairground: "carousel.fill", | ||||||
|  |             .marina: "sailboat.fill", | ||||||
|  |             .nationalPark: "leaf.fill", | ||||||
|  |             .park: "tree.fill", | ||||||
|  |             .rvPark: "car.fill", | ||||||
|  |             .zoo: "pawprint.fill", | ||||||
|  |             .baseball: "baseball.fill", | ||||||
|  |             .basketball: "basketball.fill", | ||||||
|  |             .bowling: "figure.bowling", | ||||||
|  |             .goKart: "car.circle.fill", | ||||||
|  |             .golf: "flag.and.hole.fill", | ||||||
|  |             .hiking: "figure.hiking", | ||||||
|  |             .miniGolf: "flag.and.hole.fill", | ||||||
|  |             .rockClimbing: "figure.climbing", | ||||||
|  |             .skatePark: "figure.skating", | ||||||
|  |             .skating: "figure.skating", | ||||||
|  |             .skiing: "figure.skiing.downhill", | ||||||
|  |             .soccer: "soccerball", | ||||||
|  |             .stadium: "sportscourt.fill", | ||||||
|  |             .tennis: "tennisball.fill", | ||||||
|  |             .volleyball: "volleyball.fill", | ||||||
|  |             .airport: "airplane", | ||||||
|  |             .carRental: "car.fill", | ||||||
|  |             .conventionCenter: "building.2.fill", | ||||||
|  |             .gasStation: "fuelpump.fill", | ||||||
|  |             .hotel: "bed.double.fill", | ||||||
|  |             .parking: "parkingsign.circle.fill", | ||||||
|  |             .publicTransport: "bus.fill", | ||||||
|  |             .fishing: "fish.fill", | ||||||
|  |             .kayaking: "figure.rowing", | ||||||
|  |             .surfing: "figure.surfing", | ||||||
|  |             .swimming: "figure.pool.swim", | ||||||
|  |         ] | ||||||
|  |  | ||||||
|  |         static func getIconFor(pointOfInterest: MKPointOfInterestCategory?) -> String { | ||||||
|  |             if pointOfInterest == nil { | ||||||
|  |                 return "mappin" | ||||||
|  |             } | ||||||
|  |             return pointOfInterestIcons[pointOfInterest!] ?? "mappin" | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     //    let address = location.placemark.title | ||||||
|  | } | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import MapKit | |||||||
| import SwiftUI | import SwiftUI | ||||||
|  |  | ||||||
| struct SearchView: View { | struct SearchView: View { | ||||||
|     @State private var query: String = "" |     @State private var query: String = "airport" | ||||||
|     @State private var locations: [MKMapItem] = [] |     @State private var locations: [MKMapItem] = [] | ||||||
|     @Binding var directions: [MKRoute] |     @Binding var directions: [MKRoute] | ||||||
|      |      | ||||||
| @@ -22,17 +22,17 @@ struct SearchView: View { | |||||||
|                     .onChange(of: self.query) { |                     .onChange(of: self.query) { | ||||||
|                         search(for: self.query) |                         search(for: self.query) | ||||||
|                     } |                     } | ||||||
|  |                     .onAppear { | ||||||
|  |                         // TODO: delete this, it's for debug only | ||||||
|  |                         search(for: self.query) | ||||||
|  |                     } | ||||||
|             } |             } | ||||||
|             .modifier(TextFieldGrayBackgroudColor()) |             .modifier(TextFieldGrayBackgroudColor()) | ||||||
|             Spacer() |             Spacer() | ||||||
|             List(self.locations, id: \.identifier) { location in |             ScrollView { | ||||||
|                 Button( |                 ForEach(self.locations, id: \.identifier) { location in | ||||||
|                     action: { |                     SearchItemView(location: location, directions: $directions) | ||||||
|                         self.findDirections(to: location) |                 } | ||||||
|                     }, |  | ||||||
|                     label: { |  | ||||||
|                         SearchItemView(location: location) |  | ||||||
|                     }) |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         .padding() |         .padding() | ||||||
| @@ -57,7 +57,7 @@ struct SearchView: View { | |||||||
|         let searchDirections = MKDirections(request: directionsRequest) |         let searchDirections = MKDirections(request: directionsRequest) | ||||||
|         searchDirections.calculate { (response, error) in |         searchDirections.calculate { (response, error) in | ||||||
|             guard let response = response else { |             guard let response = response else { | ||||||
|                 print(error) |                 print(error ?? "") | ||||||
|                 print("Error while searching for directions") |                 print("Error while searching for directions") | ||||||
|                 return |                 return | ||||||
|             } |             } | ||||||
| @@ -100,7 +100,8 @@ struct TextFieldGrayBackgroudColor: ViewModifier { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| #Preview { | //#Preview { | ||||||
|     @Previewable @State var directions: [MKRoute] = [] | //    @Previewable @State var directions: [MKRoute] = [] | ||||||
|     return SearchView(directions: $directions) | //    @Previewable @State var displayRoute: Bool = false | ||||||
| } | //    return SearchView(directions: $directions, $disp) | ||||||
|  | //} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user