Skip to content

Commit

Permalink
feat: add clickable functionality and autoscroll
Browse files Browse the repository at this point in the history
  • Loading branch information
hilmyveradin committed Aug 10, 2024
1 parent 13e3c17 commit 386ed34
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@
import SwiftUI

struct DirectionLegOriginDestinationView: View {
let title: String
let description: String
private let title: String
private let description: String

init(title: String, description: String) {
self.title = title
self.description = description
}

var body: some View {
HStack(spacing: 24) {
Expand Down
102 changes: 78 additions & 24 deletions OTPKit/Features/TripPlanner/Direction/DirectionSheetView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@
// Created by Hilmy Veradin on 08/08/24.
//

import MapKit
import SwiftUI

public struct DirectionSheetView: View {
@ObservedObject private var locationManagerService = LocationManagerService.shared
@Environment(\.dismiss) private var dismiss
@State private var scrollToItem: String?
@Binding var sheetDetent: PresentationDetent

@Environment(\.dismiss) var dismiss

public init() {}
public init(sheetDetent: Binding<PresentationDetent>) {
_sheetDetent = sheetDetent
}

private func generateLegView(leg: Leg) -> some View {
Group {
Expand All @@ -27,35 +31,85 @@ public struct DirectionSheetView: View {
}
}

private func handleTap(coordinate: CLLocationCoordinate2D, itemId: String) {
let placemark = MKPlacemark(coordinate: coordinate)
let item = MKMapItem(placemark: placemark)
locationManagerService.changeMapCamera(item)
scrollToItem = itemId
sheetDetent = .fraction(0.2)
}

public var body: some View {
ScrollView {
VStack(alignment: .leading, spacing: 24) {
PageHeaderView(text: "\(locationManagerService.destinationName)") {
locationManagerService.resetTripPlanner()
dismiss()
}
ScrollViewReader { proxy in
ScrollView {
VStack(alignment: .leading, spacing: 24) {
PageHeaderView(text: "\(locationManagerService.destinationName)") {
locationManagerService.resetTripPlanner()
dismiss()
}
.frame(height: 50)

if let itinerary = locationManagerService.selectedItinerary {
DirectionLegOriginDestinationView(
title: "Origin",
description: locationManagerService.originName
)
ForEach(itinerary.legs, id: \.self) { leg in
generateLegView(leg: leg)
if let itinerary = locationManagerService.selectedItinerary {
Group {
createOriginView(itinerary: itinerary)
createLegsView(itinerary: itinerary)
createDestinationView(itinerary: itinerary)
}
}
DirectionLegOriginDestinationView(
title: "Destination",
description: locationManagerService.destinationName
)
Spacer()
}
Spacer()
.padding(.horizontal, 12)
.padding(.top, 16)
}
.onChange(of: scrollToItem) {
if let itemId = scrollToItem {
withAnimation {
proxy.scrollTo(itemId, anchor: .top)
}
scrollToItem = nil
}
}
}
}

private func createOriginView(itinerary _: Itinerary) -> some View {
DirectionLegOriginDestinationView(
title: "Origin",
description: locationManagerService.originName
)
.id("item-0")
.onTapGesture {
if let originCoordinate = locationManagerService.originCoordinate {
handleTap(coordinate: originCoordinate, itemId: "item-0")
}
}
}

private func createLegsView(itinerary: Itinerary) -> some View {
ForEach(Array(itinerary.legs.enumerated()), id: \.offset) { index, leg in
generateLegView(leg: leg)
.id("item-\(index + 1)")
.onTapGesture {
let coordinate = CLLocationCoordinate2D(latitude: leg.to.lat, longitude: leg.to.lon)
handleTap(coordinate: coordinate, itemId: "item-\(index + 1)")
}
}
}

private func createDestinationView(itinerary: Itinerary) -> some View {
DirectionLegOriginDestinationView(
title: "Destination",
description: locationManagerService.destinationName
)
.id("item-\(itinerary.legs.count + 1)")
.onTapGesture {
if let destinationCoordinate = locationManagerService.destinationCoordinate {
handleTap(coordinate: destinationCoordinate, itemId: "item-\(itinerary.legs.count + 1)")
}
.padding(.horizontal, 12)
.padding(.top, 16)
}
}
}

#Preview {
DirectionSheetView()
DirectionSheetView(sheetDetent: .constant(.fraction(0.2)))
}
4 changes: 2 additions & 2 deletions OTPKit/Services/LocationManagerService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,11 @@ public final class LocationManagerService: NSObject, ObservableObject {
isMapMarkingMode = isMapMarking
}

private func changeMapCamera(_ item: MKMapItem) {
public func changeMapCamera(_ item: MKMapItem) {
currentCameraPosition = MapCameraPosition.item(item)
}

public func generateMarkers() -> ForEach<[MarkerItem], MarkerItem.ID, Marker<Text>> {
public func generateMarkers() -> some MapContent {
ForEach(Array(selectedMapPoint.values.compactMap { $0 }), id: \.id) { markerItem in
Marker(item: markerItem.item)
}
Expand Down
9 changes: 7 additions & 2 deletions OTPKitDemo/MapView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public struct MapView: View {
@ObservedObject private var locationManagerService = LocationManagerService.shared

@State private var position: MapCameraPosition = .userLocation(fallback: .automatic)
@State private var directionSheetDetent: PresentationDetent = .fraction(0.2)

private var isPlanResponsePresented: Binding<Bool> {
Binding(
Expand Down Expand Up @@ -71,8 +72,12 @@ public struct MapView: View {
.sheet(isPresented: isStepsViewPresented, onDismiss: {
locationManagerService.resetTripPlanner()
}, content: {
DirectionSheetView()
.presentationDetents([.medium, .large])
DirectionSheetView(sheetDetent: $directionSheetDetent)
.presentationDetents([.fraction(0.2), .medium, .large], selection: $directionSheetDetent)
.interactiveDismissDisabled()
.presentationBackgroundInteraction(
.enabled(upThrough: .fraction(0.2))
)
})
}

Expand Down

0 comments on commit 386ed34

Please sign in to comment.