Files
comaps/iphone/Maps/UI/PlacePage/PlacePageLayout/Layouts/PlacePageTrackLayout.swift
Kiryl Kaveryn aec82794ac [ios] Fix track selection point updates on every new selection
On the every new tap on the `Track` or during the `Elevation chart` dragging, the track `Active point` will be updated now. It allows to keep the current selected track point coordinates up to date and fix the bug when the `route to/route from` buttons use only the initial coordinates.
Key changes:
1. the `Active point` and `My position` points are moved from the `Elevation profile` to the `PlacePageTrackData` because this properties are related to the whole track. Not only chart. The chart is only one of the consumers of this data updates.
2. The subscription to the active point updates is moved from the `Elevation profile` to the `PlacePagePresenter`. The reason - see 1.
2. The callback `onActivePointChanged` is added to notify that the active point is updated
3. When the callback is triggered the `PlacePageTrackData` fetches the new coordinates from the core and saves it. This coordinates are used by the `route to/from` buttons.

Signed-off-by: Kiryl Kaveryn <kirylkaveryn@gmail.com>
2025-07-04 11:42:44 +02:00

128 lines
4.6 KiB
Swift

class PlacePageTrackLayout: IPlacePageLayout {
private var placePageData: PlacePageData
private var trackData: PlacePageTrackData
private var interactor: PlacePageInteractor
private let storyboard: UIStoryboard
weak var presenter: PlacePagePresenterProtocol?
lazy var bodyViewControllers: [UIViewController] = {
return configureViewControllers()
}()
var actionBar: ActionBarViewController? {
actionBarViewController
}
var navigationBar: UIViewController? {
placePageNavigationViewController
}
lazy var headerViewControllers: [UIViewController] = {
[headerViewController, previewViewController]
}()
lazy var headerViewController: PlacePageHeaderViewController = {
PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .flexible)
}()
lazy var previewViewController: PlacePagePreviewViewController = {
let vc = storyboard.instantiateViewController(ofType: PlacePagePreviewViewController.self)
vc.placePagePreviewData = placePageData.previewData
return vc
}()
lazy var placePageNavigationViewController: PlacePageHeaderViewController = {
return PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .fixed)
}()
lazy var editTrackViewController: PlacePageEditBookmarkOrTrackViewController = {
let vc = storyboard.instantiateViewController(ofType: PlacePageEditBookmarkOrTrackViewController.self)
vc.view.isHidden = true
vc.delegate = interactor
return vc
}()
lazy var elevationMapViewController: ElevationProfileViewController? = {
guard trackData.trackInfo.hasElevationInfo, trackData.elevationProfileData != nil else {
return nil
}
return ElevationProfileBuilder.build(trackData: trackData, delegate: interactor)
}()
lazy var actionBarViewController: ActionBarViewController = {
let vc = storyboard.instantiateViewController(ofType: ActionBarViewController.self)
vc.placePageData = placePageData
vc.canAddStop = MWMRouter.canAddIntermediatePoint()
vc.isRoutePlanning = MWMNavigationDashboardManager.shared().state != .hidden
vc.delegate = interactor
return vc
}()
init(interactor: PlacePageInteractor, storyboard: UIStoryboard, data: PlacePageData) {
self.interactor = interactor
self.storyboard = storyboard
self.placePageData = data
guard let trackData = data.trackData else {
fatalError("PlacePageData must contain trackData for the PlacePageTrackLayout")
}
self.trackData = trackData
}
private func configureViewControllers() -> [UIViewController] {
var viewControllers = [UIViewController]()
viewControllers.append(editTrackViewController)
editTrackViewController.view.isHidden = false
editTrackViewController.data = .track(trackData)
placePageData.onBookmarkStatusUpdate = { [weak self] in
guard let self = self else { return }
self.previewViewController.placePagePreviewData = self.placePageData.previewData
self.updateTrackRelatedSections()
}
if let elevationMapViewController {
viewControllers.append(elevationMapViewController)
}
return viewControllers
}
func calculateSteps(inScrollView scrollView: UIScrollView, compact: Bool) -> [PlacePageState] {
var steps: [PlacePageState] = []
let scrollHeight = scrollView.height
steps.append(.closed(-scrollHeight))
guard elevationMapViewController != nil else {
steps.append(.full(0))
return steps
}
guard let previewView = previewViewController.view else {
return steps
}
let previewFrame = scrollView.convert(previewView.bounds, from: previewView)
steps.append(.preview(previewFrame.maxY - scrollHeight))
steps.append(.full(0))
return steps
}
}
private extension PlacePageTrackLayout {
func updateTrackRelatedSections() {
guard let trackData = placePageData.trackData else {
presenter?.closeAnimated()
return
}
editTrackViewController.data = .track(trackData)
let previewData = placePageData.previewData
if let headerViewController = headerViewControllers.compactMap({ $0 as? PlacePageHeaderViewController }).first {
headerViewController.setTitle(previewData.title, secondaryTitle: previewData.secondaryTitle)
placePageNavigationViewController.setTitle(previewData.title, secondaryTitle: previewData.secondaryTitle)
}
if let previewViewController = headerViewControllers.compactMap({ $0 as? PlacePagePreviewViewController }).first {
previewViewController.placePagePreviewData = previewData
previewViewController.updateViews()
}
presenter?.layoutIfNeeded()
}
}