[ios] implement PP for the track recording
Signed-off-by: Kiryl Kaveryn <kirylkaveryn@gmail.com>
This commit is contained in:
parent
bfb2dc0154
commit
9ada5eeb6b
20 changed files with 327 additions and 128 deletions
|
@ -4,7 +4,13 @@
|
|||
|
||||
@class MapViewController;
|
||||
@class BottomTabBarViewController;
|
||||
@class TrackRecordingViewController;
|
||||
@class TrackRecordingButtonViewController;
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TrackRecordingButtonState) {
|
||||
TrackRecordingButtonStateHidden,
|
||||
TrackRecordingButtonStateVisible,
|
||||
TrackRecordingButtonStateClosed,
|
||||
};
|
||||
|
||||
@protocol MWMFeatureHolder;
|
||||
|
||||
|
@ -20,7 +26,7 @@
|
|||
@property(nonatomic) MWMBottomMenuState menuRestoreState;
|
||||
@property(nonatomic) BOOL isDirectionViewHidden;
|
||||
@property(nonatomic) BottomTabBarViewController * tabBarController;
|
||||
@property(nonatomic) TrackRecordingViewController * trackRecordingButton;
|
||||
@property(nonatomic) TrackRecordingButtonViewController * trackRecordingButton;
|
||||
|
||||
- (instancetype)init __attribute__((unavailable("init is not available")));
|
||||
- (instancetype)initWithParentController:(MapViewController *)controller;
|
||||
|
@ -34,6 +40,8 @@
|
|||
- (void)viewWillTransitionToSize:(CGSize)size
|
||||
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator;
|
||||
|
||||
- (void)setTrackRecordingButtonState:(TrackRecordingButtonState)state;
|
||||
|
||||
#pragma mark - MWMNavigationDashboardManager
|
||||
|
||||
- (void)onRoutePrepare;
|
||||
|
|
|
@ -28,15 +28,15 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
|||
|
||||
@interface MWMMapViewControlsManager () <BottomMenuDelegate>
|
||||
|
||||
@property(nonatomic) MWMSideButtons *sideButtons;
|
||||
@property(nonatomic) MWMTrafficButtonViewController *trafficButton;
|
||||
@property(nonatomic) UIButton *promoButton;
|
||||
@property(nonatomic) UIViewController *menuController;
|
||||
@property(nonatomic) MWMSideButtons * sideButtons;
|
||||
@property(nonatomic) MWMTrafficButtonViewController * trafficButton;
|
||||
@property(nonatomic) UIButton * promoButton;
|
||||
@property(nonatomic) UIViewController * menuController;
|
||||
@property(nonatomic) id<MWMPlacePageProtocol> placePageManager;
|
||||
@property(nonatomic) MWMNavigationDashboardManager *navigationManager;
|
||||
@property(nonatomic) SearchOnMapManager *searchManager;
|
||||
@property(nonatomic) MWMNavigationDashboardManager * navigationManager;
|
||||
@property(nonatomic) SearchOnMapManager * searchManager;
|
||||
|
||||
@property(weak, nonatomic) MapViewController *ownerController;
|
||||
@property(weak, nonatomic) MapViewController * ownerController;
|
||||
|
||||
@property(nonatomic) BOOL disableStandbyOnRouteFollowing;
|
||||
@property(nonatomic) BOOL isAddingPlace;
|
||||
|
@ -63,17 +63,10 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
|||
self.menuState = MWMBottomMenuStateInactive;
|
||||
self.menuRestoreState = MWMBottomMenuStateInactive;
|
||||
self.isAddingPlace = NO;
|
||||
[TrackRecordingManager.shared addObserver:self recordingIsActiveDidChangeHandler:^(TrackRecordingState state, TrackInfo * trackInfo) {
|
||||
[self setTrackRecordingButtonHidden:state == TrackRecordingStateInactive];
|
||||
}];
|
||||
self.searchManager = controller.searchManager;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[TrackRecordingManager.shared removeObserver:self];
|
||||
}
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle {
|
||||
BOOL const isNavigationUnderStatusBar = self.navigationManager.state != MWMNavigationDashboardStateHidden &&
|
||||
self.navigationManager.state != MWMNavigationDashboardStateNavigation;
|
||||
|
@ -280,17 +273,15 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
|||
self.trafficButton.hidden = self.hidden || _trafficButtonHidden;
|
||||
}
|
||||
|
||||
- (void)setTrackRecordingButtonHidden:(BOOL)trackRecordingButtonHidden {
|
||||
if (trackRecordingButtonHidden && _trackRecordingButton) {
|
||||
[self.trackRecordingButton closeWithCompletion:^{
|
||||
[MWMMapWidgetsHelper updateLayoutForAvailableArea];
|
||||
}];
|
||||
_trackRecordingButton = nil;
|
||||
- (void)setTrackRecordingButtonState:(TrackRecordingButtonState)state {
|
||||
if (!_trackRecordingButton) {
|
||||
_trackRecordingButton = [[TrackRecordingButtonViewController alloc] init];
|
||||
}
|
||||
else if (!trackRecordingButtonHidden && !_trackRecordingButton) {
|
||||
_trackRecordingButton = [[TrackRecordingViewController alloc] init];
|
||||
[self.trackRecordingButton setState:state completion:^{
|
||||
[MWMMapWidgetsHelper updateLayoutForAvailableArea];
|
||||
}
|
||||
}];
|
||||
if (state == TrackRecordingButtonStateClosed)
|
||||
_trackRecordingButton = nil;
|
||||
}
|
||||
|
||||
- (void)setMenuState:(MWMBottomMenuState)menuState {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
final class TrackRecordingViewController: MWMViewController {
|
||||
final class TrackRecordingButtonViewController: MWMViewController {
|
||||
|
||||
private enum Constants {
|
||||
static let buttonDiameter = CGFloat(48)
|
||||
|
@ -13,6 +13,7 @@ final class TrackRecordingViewController: MWMViewController {
|
|||
private var blinkingTimer: Timer?
|
||||
private var topConstraint = NSLayoutConstraint()
|
||||
private var trailingConstraint = NSLayoutConstraint()
|
||||
private var state: TrackRecordingButtonState = .hidden
|
||||
|
||||
private static var availableArea: CGRect = .zero
|
||||
private static var topConstraintValue: CGFloat {
|
||||
|
@ -38,31 +39,29 @@ final class TrackRecordingViewController: MWMViewController {
|
|||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
UIView.transition(with: self.view,
|
||||
duration: kDefaultAnimationDuration,
|
||||
options: .transitionCrossDissolve,
|
||||
animations: {
|
||||
self.button.isHidden = false
|
||||
})
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
// async is for smoother appearance
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + kDefaultAnimationDuration) {
|
||||
self.setState(self.state, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Public methods
|
||||
|
||||
@objc
|
||||
func close(completion: @escaping (() -> Void)) {
|
||||
stopTimer()
|
||||
UIView.transition(with: self.view,
|
||||
duration: kDefaultAnimationDuration,
|
||||
options: .transitionCrossDissolve,
|
||||
animations: {
|
||||
self.button.isHidden = true
|
||||
}, completion: { _ in
|
||||
self.removeFromParent()
|
||||
self.view.removeFromSuperview()
|
||||
completion()
|
||||
})
|
||||
func setState(_ state: TrackRecordingButtonState, completion: (() -> Void)?) {
|
||||
self.state = state
|
||||
switch state {
|
||||
case .visible:
|
||||
setHidden(false, completion: nil)
|
||||
case .hidden:
|
||||
setHidden(true, completion: completion)
|
||||
case .closed:
|
||||
close(completion: completion)
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private methods
|
||||
|
@ -75,7 +74,7 @@ final class TrackRecordingViewController: MWMViewController {
|
|||
button.tintColor = Constants.color.darker
|
||||
button.translatesAutoresizingMaskIntoConstraints = false
|
||||
button.setImage(UIImage(resource: .icMenuBookmarkTrackRecording), for: .normal)
|
||||
button.addTarget(self, action: #selector(onTrackRecordingButtonPressed), for: .touchUpInside)
|
||||
button.addTarget(self, action: #selector(didTap), for: .touchUpInside)
|
||||
button.isHidden = true
|
||||
}
|
||||
|
||||
|
@ -97,7 +96,7 @@ final class TrackRecordingViewController: MWMViewController {
|
|||
}
|
||||
|
||||
private func updateLayout() {
|
||||
guard let superview = self.view.superview else { return }
|
||||
guard let superview = view.superview else { return }
|
||||
superview.animateConstraints {
|
||||
self.topConstraint.constant = Self.topConstraintValue
|
||||
self.trailingConstraint.constant = Self.trailingConstraintValue
|
||||
|
@ -123,23 +122,39 @@ final class TrackRecordingViewController: MWMViewController {
|
|||
blinkingTimer = nil
|
||||
}
|
||||
|
||||
private func setHidden(_ hidden: Bool, completion: (() -> Void)?) {
|
||||
UIView.transition(with: self.view,
|
||||
duration: kDefaultAnimationDuration,
|
||||
options: .transitionCrossDissolve,
|
||||
animations: {
|
||||
self.button.isHidden = hidden
|
||||
}) { _ in
|
||||
completion?()
|
||||
}
|
||||
}
|
||||
|
||||
private func close(completion: (() -> Void)?) {
|
||||
stopTimer()
|
||||
setHidden(true) { [weak self] in
|
||||
guard let self else { return }
|
||||
self.removeFromParent()
|
||||
self.view.removeFromSuperview()
|
||||
completion?()
|
||||
}
|
||||
}
|
||||
|
||||
static func updateAvailableArea(_ frame: CGRect) {
|
||||
availableArea = frame
|
||||
guard let controller = MapViewController.shared()?.controlsManager.trackRecordingButton else { return }
|
||||
guard let button = MapViewController.shared()?.controlsManager.trackRecordingButton else { return }
|
||||
DispatchQueue.main.async {
|
||||
controller.updateLayout()
|
||||
button.updateLayout()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@objc
|
||||
private func onTrackRecordingButtonPressed(_ sender: Any) {
|
||||
switch trackRecordingManager.recordingState {
|
||||
case .inactive:
|
||||
trackRecordingManager.processAction(.start)
|
||||
case .active:
|
||||
trackRecordingManager.processAction(.stop)
|
||||
}
|
||||
private func didTap(_ sender: Any) {
|
||||
MapViewController.shared()?.showTrackRecordingPlacePage()
|
||||
}
|
||||
}
|
|
@ -33,6 +33,7 @@
|
|||
- (void)openFullPlaceDescriptionWithHtml:(NSString *_Nonnull)htmlString;
|
||||
- (void)searchText:(NSString *_Nonnull)text;
|
||||
- (void)openDrivingOptions;
|
||||
- (void)showTrackRecordingPlacePage;
|
||||
|
||||
- (void)setPlacePageTopBound:(CGFloat)bound duration:(double)duration;
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ NSString *const kSettingsSegue = @"Map2Settings";
|
|||
|
||||
@property(nonatomic, readwrite) MWMMapViewControlsManager *controlsManager;
|
||||
@property(nonatomic, readwrite) SearchOnMapManager *searchManager;
|
||||
@property(nonatomic, readwrite) TrackRecordingManager *trackRecordingManager;
|
||||
|
||||
@property(nonatomic) BOOL disableStandbyOnLocationStateMode;
|
||||
|
||||
|
@ -116,29 +117,7 @@ NSString *const kSettingsSegue = @"Map2Settings";
|
|||
return [MapsAppDelegate theApp].mapViewController;
|
||||
}
|
||||
|
||||
#pragma mark - Map Navigation
|
||||
|
||||
- (void)showTrackRecordingPlacePage {
|
||||
__block PlacePageData * placePageData = [[PlacePageData alloc] initWithTrackInfo:TrackRecordingManager.shared.trackRecordingInfo
|
||||
elevationInfo:[MWMFrameworkHelper trackRecordingElevationInfo]];
|
||||
[TrackRecordingManager.shared addObserver:self recordingIsActiveDidChangeHandler:^(TrackRecordingState state, TrackInfo * _Nonnull trackInfo) {
|
||||
switch (state) {
|
||||
case TrackRecordingStateInactive:
|
||||
[self stopObservingTrackRecordingUpdates];
|
||||
break;
|
||||
case TrackRecordingStateActive:
|
||||
if (UIApplication.sharedApplication.applicationState != UIApplicationStateActive)
|
||||
return;
|
||||
[placePageData updateWithTrackInfo:trackInfo elevationInfo:[MWMFrameworkHelper trackRecordingElevationInfo]];
|
||||
break;
|
||||
}
|
||||
}];
|
||||
[self showOrUpdatePlacePage:placePageData];
|
||||
}
|
||||
|
||||
- (void)stopObservingTrackRecordingUpdates {
|
||||
[TrackRecordingManager.shared removeObserver:self];
|
||||
}
|
||||
#pragma mark - PlacePage
|
||||
|
||||
- (void)showOrUpdatePlacePage:(PlacePageData *)data {
|
||||
if (self.searchManager.isSearching)
|
||||
|
@ -146,9 +125,10 @@ NSString *const kSettingsSegue = @"Map2Settings";
|
|||
|
||||
self.controlsManager.trafficButtonHidden = YES;
|
||||
if (self.placePageVC != nil) {
|
||||
[PlacePageBuilder update:(PlacePageViewController *)self.placePageVC with:data];
|
||||
[PlacePageBuilder update:self.placePageVC with:data];
|
||||
return;
|
||||
}
|
||||
|
||||
[self showPlacePageFor:data];
|
||||
}
|
||||
|
||||
|
@ -433,6 +413,9 @@ NSString *const kSettingsSegue = @"Map2Settings";
|
|||
// After all users migrate to OAuth2 we can remove next code
|
||||
[self migrateOAuthCredentials];
|
||||
|
||||
if (self.trackRecordingManager.isActive)
|
||||
[self showTrackRecordingPlacePage];
|
||||
|
||||
/// @todo: Uncomment update dialog when will be ready to handle big traffic bursts.
|
||||
/*
|
||||
if (!DeepLinkHandler.shared.isLaunchedByDeeplink)
|
||||
|
@ -754,6 +737,12 @@ NSString *const kSettingsSegue = @"Map2Settings";
|
|||
return _searchManager;
|
||||
}
|
||||
|
||||
- (TrackRecordingManager *)trackRecordingManager {
|
||||
if (!_trackRecordingManager)
|
||||
_trackRecordingManager = TrackRecordingManager.shared;
|
||||
return _trackRecordingManager;
|
||||
}
|
||||
|
||||
- (UIView * _Nullable)searchViewContainer {
|
||||
return self.searchManager.viewController.view;
|
||||
}
|
||||
|
@ -873,6 +862,50 @@ NSString *const kSettingsSegue = @"Map2Settings";
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - Track Recording Place Page
|
||||
|
||||
- (void)showTrackRecordingPlacePage {
|
||||
if ([self.trackRecordingManager contains:self]) {
|
||||
[self dismissPlacePage];
|
||||
return;
|
||||
}
|
||||
PlacePageData * placePageData = [[PlacePageData alloc] initWithTrackInfo:self.trackRecordingManager.trackRecordingInfo
|
||||
elevationInfo:self.trackRecordingManager.trackRecordingElevationProfileData];
|
||||
[self.controlsManager setTrackRecordingButtonState:TrackRecordingButtonStateHidden];
|
||||
[self showOrUpdatePlacePage:placePageData];
|
||||
[self startObservingTrackRecordingUpdatesForPlacePageData:placePageData];
|
||||
}
|
||||
|
||||
- (void)startObservingTrackRecordingUpdatesForPlacePageData:(PlacePageData *)placePageData {
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
[self.trackRecordingManager addObserver:self
|
||||
recordingIsActiveDidChangeHandler:^(TrackRecordingState state,
|
||||
TrackInfo * _Nonnull trackInfo,
|
||||
ElevationProfileData * _Nonnull (^ _Nullable elevationData) ()) {
|
||||
__strong __typeof(weakSelf) self = weakSelf;
|
||||
|
||||
switch (state) {
|
||||
case TrackRecordingStateInactive:
|
||||
[self stopObservingTrackRecordingUpdates];
|
||||
[self.controlsManager setTrackRecordingButtonState:TrackRecordingButtonStateClosed];
|
||||
break;
|
||||
case TrackRecordingStateActive:
|
||||
if (UIApplication.sharedApplication.applicationState != UIApplicationStateActive)
|
||||
return;
|
||||
[self.controlsManager setTrackRecordingButtonState:TrackRecordingButtonStateHidden];
|
||||
[placePageData updateWithTrackInfo:trackInfo
|
||||
elevationInfo:elevationData()];
|
||||
break;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)stopObservingTrackRecordingUpdates {
|
||||
[self.trackRecordingManager removeObserver:self];
|
||||
if (self.trackRecordingManager.isActive)
|
||||
[self.controlsManager setTrackRecordingButtonState:TrackRecordingButtonStateVisible];
|
||||
}
|
||||
|
||||
// MARK: - Handle macOS trackpad gestures
|
||||
|
||||
- (void)handlePan:(UIPanGestureRecognizer *)recognizer API_AVAILABLE(ios(14.0)) {
|
||||
|
|
|
@ -185,6 +185,7 @@ extension GlobalStyleSheet: IStyleSheet {
|
|||
case .trackRecordingWidgetButton:
|
||||
return .addFrom(Self.bottomTabBarButton) { s in
|
||||
s.cornerRadius = 23
|
||||
s.coloring = .red
|
||||
}
|
||||
case .blackOpaqueBackground:
|
||||
return .add { s in
|
||||
|
|
|
@ -24,13 +24,22 @@ enum TrackRecordingActionResult {
|
|||
protocol TrackRecordingObservable: AnyObject {
|
||||
var recordingState: TrackRecordingState { get }
|
||||
var trackRecordingInfo: TrackInfo { get }
|
||||
var trackRecordingElevationProfileData: ElevationProfileData { get }
|
||||
|
||||
func addObserver(_ observer: AnyObject, recordingIsActiveDidChangeHandler: @escaping TrackRecordingStateHandler)
|
||||
func removeObserver(_ observer: AnyObject)
|
||||
func contains(_ observer: AnyObject) -> Bool
|
||||
}
|
||||
|
||||
typealias TrackRecordingStateHandler = (TrackRecordingState, TrackInfo) -> Void
|
||||
/// A handler type for extracting elevation profile data on demand.
|
||||
typealias ElevationProfileDataExtractionHandler = () -> ElevationProfileData
|
||||
|
||||
/// A callback type that notifies observers about track recording state changes.
|
||||
/// - Parameters:
|
||||
/// - state: The current recording state.
|
||||
/// - info: The current track recording info.
|
||||
/// - elevationProfileExtractor: A closure to fetch elevation profile data lazily.
|
||||
typealias TrackRecordingStateHandler = (TrackRecordingState, TrackInfo, ElevationProfileDataExtractionHandler?) -> Void
|
||||
|
||||
@objcMembers
|
||||
final class TrackRecordingManager: NSObject {
|
||||
|
@ -62,6 +71,10 @@ final class TrackRecordingManager: NSObject {
|
|||
private var observations: [Observation] = []
|
||||
private(set) var trackRecordingInfo: TrackInfo = .empty()
|
||||
|
||||
var trackRecordingElevationProfileData: ElevationProfileData {
|
||||
FrameworkHelper.trackRecordingElevationInfo()
|
||||
}
|
||||
|
||||
var recordingState: TrackRecordingState {
|
||||
trackRecorder.isTrackRecordingEnabled() ? .active : .inactive
|
||||
}
|
||||
|
@ -73,6 +86,7 @@ final class TrackRecordingManager: NSObject {
|
|||
self.locationService = locationService
|
||||
self.activityManager = activityManager
|
||||
super.init()
|
||||
self.subscribeOnTheAppLifecycleEvents()
|
||||
}
|
||||
|
||||
// MARK: - Public methods
|
||||
|
@ -115,6 +129,13 @@ final class TrackRecordingManager: NSObject {
|
|||
|
||||
// MARK: - Private methods
|
||||
|
||||
private func subscribeOnTheAppLifecycleEvents() {
|
||||
NotificationCenter.default.addObserver(self,
|
||||
selector: #selector(notifyObservers),
|
||||
name: UIApplication.didBecomeActiveNotification,
|
||||
object: nil)
|
||||
}
|
||||
|
||||
private func checkIsLocationEnabled() throws(TrackRecordingError) {
|
||||
if locationService.isLocationProhibited() {
|
||||
throw TrackRecordingError.locationIsProhibited
|
||||
|
@ -199,7 +220,9 @@ extension TrackRecordingManager: TrackRecordingObservable {
|
|||
guard !observations.contains(where: { $0.observer === observer }) else { return }
|
||||
let observation = Observation(observer: observer, recordingStateDidChangeHandler: recordingIsActiveDidChangeHandler)
|
||||
observations.append(observation)
|
||||
recordingIsActiveDidChangeHandler(recordingState, trackRecordingInfo)
|
||||
recordingIsActiveDidChangeHandler(recordingState, trackRecordingInfo) {
|
||||
self.trackRecordingElevationProfileData
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
|
@ -212,8 +235,11 @@ extension TrackRecordingManager: TrackRecordingObservable {
|
|||
observations.contains { $0.observer === observer }
|
||||
}
|
||||
|
||||
@objc
|
||||
private func notifyObservers() {
|
||||
observations = observations.filter { $0.observer != nil }
|
||||
observations.forEach { $0.recordingStateDidChangeHandler?(recordingState, trackRecordingInfo) }
|
||||
observations.removeAll { $0.observer == nil }
|
||||
observations.forEach {
|
||||
$0.recordingStateDidChangeHandler?(recordingState, trackRecordingInfo, { self.trackRecordingElevationProfileData })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
15
iphone/Maps/Images.xcassets/Place Page/ic_placepage_save_track_recording.imageset/Contents.json
vendored
Normal file
15
iphone/Maps/Images.xcassets/Place Page/ic_placepage_save_track_recording.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "ic_track_save.png",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
BIN
iphone/Maps/Images.xcassets/Place Page/ic_placepage_save_track_recording.imageset/ic_track_save.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/Place Page/ic_placepage_save_track_recording.imageset/ic_track_save.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
|
@ -481,7 +481,7 @@
|
|||
ED2D74652D14357F00660FBF /* TrackRecordingLiveActivityAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED2D74302D14337500660FBF /* TrackRecordingLiveActivityAttributes.swift */; };
|
||||
ED2D74662D1435A600660FBF /* LiveActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED2D742D2D14337500660FBF /* LiveActivityManager.swift */; };
|
||||
ED2E328E2D10500900807A08 /* TrackRecordingButtonArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED46DD922D06F804007CACD6 /* TrackRecordingButtonArea.swift */; };
|
||||
ED2E32912D10501700807A08 /* TrackRecordingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED49D76F2CF0E3A8004AF27E /* TrackRecordingViewController.swift */; };
|
||||
ED2E32912D10501700807A08 /* TrackRecordingButtonViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED49D76F2CF0E3A8004AF27E /* TrackRecordingButtonViewController.swift */; };
|
||||
ED3EAC202B03C88100220A4A /* BottomTabBarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED3EAC1F2B03C88100220A4A /* BottomTabBarButton.swift */; };
|
||||
ED43B8BD2C12063500D07BAA /* DocumentPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED43B8BC2C12063500D07BAA /* DocumentPicker.swift */; };
|
||||
ED46DDCE2D098A0B007CACD6 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED46DDCD2D098A0B007CACD6 /* WidgetKit.framework */; };
|
||||
|
@ -524,6 +524,7 @@
|
|||
ED914ABE2D351FF800973C45 /* UILabel+SetFontStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED914ABD2D351FF800973C45 /* UILabel+SetFontStyle.swift */; };
|
||||
ED9857082C4ED02D00694F6C /* MailComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED9857072C4ED02D00694F6C /* MailComposer.swift */; };
|
||||
ED9966802B94FBC20083CE55 /* ColorPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED99667D2B94FBC20083CE55 /* ColorPicker.swift */; };
|
||||
ED9DDF882D6F151000645BC8 /* PlacePageTrackRecordingLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED9DDF872D6F151000645BC8 /* PlacePageTrackRecordingLayout.swift */; };
|
||||
EDA1EAA42CC7ECAD00DBDCAA /* ElevationProfileFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDA1EAA32CC7ECAD00DBDCAA /* ElevationProfileFormatter.swift */; };
|
||||
EDBD68072B625724005DD151 /* LocationServicesDisabledAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = EDBD68062B625724005DD151 /* LocationServicesDisabledAlert.xib */; };
|
||||
EDBD680B2B62572E005DD151 /* LocationServicesDisabledAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDBD680A2B62572E005DD151 /* LocationServicesDisabledAlert.swift */; };
|
||||
|
@ -1449,7 +1450,7 @@
|
|||
ED46DDCF2D098A0B007CACD6 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
|
||||
ED48BBB817C2B1E2003E7E92 /* CircleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CircleView.h; sourceTree = "<group>"; };
|
||||
ED48BBB917C2B1E2003E7E92 /* CircleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CircleView.m; sourceTree = "<group>"; };
|
||||
ED49D76F2CF0E3A8004AF27E /* TrackRecordingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackRecordingViewController.swift; sourceTree = "<group>"; };
|
||||
ED49D76F2CF0E3A8004AF27E /* TrackRecordingButtonViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackRecordingButtonViewController.swift; sourceTree = "<group>"; };
|
||||
ED4DC7732CAEDECC0029B338 /* ProductButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductButton.swift; sourceTree = "<group>"; };
|
||||
ED4DC7742CAEDECC0029B338 /* ProductsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductsViewController.swift; sourceTree = "<group>"; };
|
||||
ED4DC7752CAEDECC0029B338 /* ProductsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductsViewModel.swift; sourceTree = "<group>"; };
|
||||
|
@ -1490,6 +1491,7 @@
|
|||
ED914ABD2D351FF800973C45 /* UILabel+SetFontStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+SetFontStyle.swift"; sourceTree = "<group>"; };
|
||||
ED9857072C4ED02D00694F6C /* MailComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MailComposer.swift; sourceTree = "<group>"; };
|
||||
ED99667D2B94FBC20083CE55 /* ColorPicker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorPicker.swift; sourceTree = "<group>"; };
|
||||
ED9DDF872D6F151000645BC8 /* PlacePageTrackRecordingLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlacePageTrackRecordingLayout.swift; sourceTree = "<group>"; };
|
||||
EDA1EAA32CC7ECAD00DBDCAA /* ElevationProfileFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElevationProfileFormatter.swift; sourceTree = "<group>"; };
|
||||
EDBD68062B625724005DD151 /* LocationServicesDisabledAlert.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LocationServicesDisabledAlert.xib; sourceTree = "<group>"; };
|
||||
EDBD680A2B62572E005DD151 /* LocationServicesDisabledAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationServicesDisabledAlert.swift; sourceTree = "<group>"; };
|
||||
|
@ -2569,7 +2571,7 @@
|
|||
34BC72091B0DECAE0012A34B /* MapViewControls */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ED49D76F2CF0E3A8004AF27E /* TrackRecordingViewController.swift */,
|
||||
ED49D76F2CF0E3A8004AF27E /* TrackRecordingButtonViewController.swift */,
|
||||
340537621BBED98600D452C6 /* MWMMapViewControlsCommon.h */,
|
||||
34BC72101B0DECAE0012A34B /* MWMMapViewControlsManager.h */,
|
||||
34BC72111B0DECAE0012A34B /* MWMMapViewControlsManager.mm */,
|
||||
|
@ -3031,6 +3033,7 @@
|
|||
99C6532123F2F506004322F3 /* IPlacePageLayout.swift */,
|
||||
99F3EB0223F4178200C713F8 /* PlacePageCommonLayout.swift */,
|
||||
993DF0B423F6B2EF00AC231A /* PlacePageTrackLayout.swift */,
|
||||
ED9DDF872D6F151000645BC8 /* PlacePageTrackRecordingLayout.swift */,
|
||||
);
|
||||
path = Layouts;
|
||||
sourceTree = "<group>";
|
||||
|
@ -4489,7 +4492,7 @@
|
|||
340708651F2905A500029ECC /* NavigationInfoArea.swift in Sources */,
|
||||
993DF0CC23F6BD0600AC231A /* ElevationDetailsPresenter.swift in Sources */,
|
||||
34AB666B1FC5AA330078E451 /* TransportTransitCell.swift in Sources */,
|
||||
ED2E32912D10501700807A08 /* TrackRecordingViewController.swift in Sources */,
|
||||
ED2E32912D10501700807A08 /* TrackRecordingButtonViewController.swift in Sources */,
|
||||
47E8163323B17734008FD836 /* MWMStorage+UI.m in Sources */,
|
||||
993DF11123F6BDB100AC231A /* UILabelRenderer.swift in Sources */,
|
||||
34AB66471FC5AA330078E451 /* RouteManagerTableView.swift in Sources */,
|
||||
|
@ -4630,6 +4633,7 @@
|
|||
1DFA2F6A20D3B57400FB2C66 /* UIColor+PartnerColor.m in Sources */,
|
||||
9989273B2449E60200260CE2 /* BottomMenuBuilder.swift in Sources */,
|
||||
993DF10F23F6BDB100AC231A /* UIActivityIndicatorRenderer.swift in Sources */,
|
||||
ED9DDF882D6F151000645BC8 /* PlacePageTrackRecordingLayout.swift in Sources */,
|
||||
ED0B1FEF2CAA9A25006E31A4 /* UIView+Highlight.swift in Sources */,
|
||||
99A614E423CDD1D900D8D8D0 /* UIButton+RuntimeAttributes.m in Sources */,
|
||||
343E75981E5B1EE20041226A /* MWMCollectionViewController.m in Sources */,
|
||||
|
|
|
@ -10,7 +10,7 @@ final class TrackRecordingButtonArea: AvailableArea {
|
|||
}
|
||||
|
||||
override func notifyObserver() {
|
||||
TrackRecordingViewController.updateAvailableArea(areaFrame)
|
||||
TrackRecordingButtonViewController.updateAvailableArea(areaFrame)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,8 +79,13 @@ extension BottomMenuInteractor: BottomMenuInteractorProtocol {
|
|||
}
|
||||
|
||||
func toggleTrackRecording() {
|
||||
trackRecorder.processAction(trackRecorder.recordingState == .active ? .stop : .start) { [weak self] in
|
||||
self?.close()
|
||||
switch trackRecorder.recordingState {
|
||||
case .active:
|
||||
break
|
||||
case .inactive:
|
||||
trackRecorder.processAction(.start)
|
||||
}
|
||||
close()
|
||||
MapViewController.shared()?.showTrackRecordingPlacePage()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,18 +62,26 @@ final class ActionBarViewController: UIViewController {
|
|||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
var buttons: [ActionBarButtonType] = []
|
||||
if isRoutePlanning {
|
||||
buttons.append(.routeFrom)
|
||||
}
|
||||
if placePageData.infoData?.phone != nil, AppInfo.shared().canMakeCalls {
|
||||
buttons.append(.call)
|
||||
}
|
||||
if !isRoutePlanning {
|
||||
buttons.append(.routeFrom)
|
||||
switch placePageData.objectType {
|
||||
case .POI, .bookmark, .track:
|
||||
if isRoutePlanning {
|
||||
buttons.append(.routeFrom)
|
||||
}
|
||||
if placePageData.infoData?.phone != nil, AppInfo.shared().canMakeCalls {
|
||||
buttons.append(.call)
|
||||
}
|
||||
if !isRoutePlanning {
|
||||
buttons.append(.routeFrom)
|
||||
}
|
||||
case .trackRecording:
|
||||
break
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
|
||||
assert(buttons.count > 0)
|
||||
guard !buttons.isEmpty else { return }
|
||||
visibleButtons.append(buttons[0])
|
||||
if buttons.count > 1 {
|
||||
additionalButtons.append(contentsOf: buttons.suffix(from: 1))
|
||||
|
@ -91,8 +99,7 @@ final class ActionBarViewController: UIViewController {
|
|||
case .track:
|
||||
buttons.append(.track)
|
||||
case .trackRecording:
|
||||
// TODO: implement for track recording
|
||||
break
|
||||
buttons.append(.saveTrackRecording)
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
|
@ -104,7 +111,14 @@ final class ActionBarViewController: UIViewController {
|
|||
}
|
||||
|
||||
private func configButton3() {
|
||||
visibleButtons.append(.routeTo)
|
||||
switch placePageData.objectType {
|
||||
case .POI, .bookmark, .track:
|
||||
visibleButtons.append(.routeTo)
|
||||
case .trackRecording:
|
||||
break
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
private func configButton4() {
|
||||
|
|
|
@ -51,8 +51,6 @@ extension PlacePageHeaderPresenter: PlacePageHeaderPresenterProtocol {
|
|||
view?.isExpandViewHidden = true
|
||||
view?.isShadowViewHidden = false
|
||||
}
|
||||
// TODO: (KK) Enable share button for the tracks to share the whole track gpx/kml
|
||||
view?.isShareButtonHidden = false
|
||||
}
|
||||
|
||||
func onClosePress() {
|
||||
|
|
|
@ -2,7 +2,6 @@ protocol PlacePageHeaderViewProtocol: AnyObject {
|
|||
var presenter: PlacePageHeaderPresenterProtocol? { get set }
|
||||
var isExpandViewHidden: Bool { get set }
|
||||
var isShadowViewHidden: Bool { get set }
|
||||
var isShareButtonHidden: Bool { get set }
|
||||
|
||||
func setTitle(_ title: String?, secondaryTitle: String?)
|
||||
func showShareTrackMenu()
|
||||
|
@ -78,15 +77,6 @@ extension PlacePageHeaderViewController: PlacePageHeaderViewProtocol {
|
|||
}
|
||||
}
|
||||
|
||||
var isShareButtonHidden: Bool {
|
||||
get {
|
||||
shareButton.isHidden
|
||||
}
|
||||
set {
|
||||
shareButton.isHidden = newValue
|
||||
}
|
||||
}
|
||||
|
||||
func setTitle(_ title: String?, secondaryTitle: String?) {
|
||||
titleText = title
|
||||
secondaryText = secondaryTitle
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
case .track:
|
||||
layout = PlacePageTrackLayout(interactor: interactor, storyboard: storyboard, data: data)
|
||||
case .trackRecording:
|
||||
// TODO: Implement PlacePageTrackRecordingLayout
|
||||
fatalError("PlacePageTrackRecordingLayout is not implemented")
|
||||
layout = PlacePageTrackRecordingLayout(interactor: interactor, storyboard: storyboard, data: data)
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
|
@ -34,14 +33,14 @@
|
|||
data: data,
|
||||
mapViewController: MapViewController.shared()!)
|
||||
let layout: IPlacePageLayout
|
||||
let storyboard = viewController.storyboard!
|
||||
switch data.objectType {
|
||||
case .POI, .bookmark:
|
||||
layout = PlacePageCommonLayout(interactor: interactor, storyboard: viewController.storyboard!, data: data)
|
||||
layout = PlacePageCommonLayout(interactor: interactor, storyboard: storyboard, data: data)
|
||||
case .track:
|
||||
layout = PlacePageTrackLayout(interactor: interactor, storyboard: viewController.storyboard!, data: data)
|
||||
layout = PlacePageTrackLayout(interactor: interactor, storyboard: storyboard, data: data)
|
||||
case .trackRecording:
|
||||
// TODO: Implement PlacePageTrackRecordingLayout
|
||||
fatalError("PlacePageTrackRecordingLayout is not implemented")
|
||||
layout = PlacePageTrackRecordingLayout(interactor: interactor, storyboard: storyboard, data: data)
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ class PlacePageInteractor: NSObject {
|
|||
|
||||
private func updatePlacePageIfNeeded() {
|
||||
let isBookmark = placePageData.bookmarkData != nil && bookmarksManager.hasBookmark(placePageData.bookmarkData!.bookmarkId)
|
||||
let isTrack = placePageData.trackData != nil && bookmarksManager.hasTrack(placePageData.trackData!.trackId)
|
||||
let isTrack = placePageData.trackData != nil/* && bookmarksManager.hasTrack(placePageData.trackData!.trackId)*/
|
||||
guard isBookmark || isTrack else {
|
||||
presenter?.closeAnimated()
|
||||
return
|
||||
|
@ -239,11 +239,11 @@ extension PlacePageInteractor: ActionBarViewControllerDelegate {
|
|||
fatalError("More button should've been handled in ActionBarViewContoller")
|
||||
case .track:
|
||||
guard placePageData.trackData != nil else { return }
|
||||
// TODO: This is temporary solution. Remove the dialog and use the MWMPlacePageManagerHelper.removeTrack
|
||||
// TODO: (KK) This is temporary solution. Remove the dialog and use the MWMPlacePageManagerHelper.removeTrack
|
||||
// directly here when the track recovery mechanism will be implemented.
|
||||
showTrackDeletionConfirmationDialog()
|
||||
case .saveTrackRecording:
|
||||
// TODO: (KK) pass name
|
||||
// TODO: (KK) pass name typed by user
|
||||
TrackRecordingManager.shared.processAction(.stopAndSave(name: "")) { [weak self] result in
|
||||
switch result {
|
||||
case .success:
|
||||
|
@ -287,8 +287,8 @@ extension PlacePageInteractor: ElevationProfileViewControllerDelegate {
|
|||
}
|
||||
|
||||
func updateMapPoint(_ point: CLLocationCoordinate2D, distance: Double) {
|
||||
guard let trackId = placePageData.trackData?.trackId else { return }
|
||||
BookmarksManager.shared().setElevationActivePoint(point, distance: distance, trackId: trackId)
|
||||
guard let trackData = placePageData.trackData, trackData.elevationProfileData?.isTrackRecording == false else { return }
|
||||
BookmarksManager.shared().setElevationActivePoint(point, distance: distance, trackId: trackData.trackId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ typedef NS_ENUM(NSInteger, MWMActionBarButtonType) {
|
|||
MWMActionBarButtonTypeBookingSearch,
|
||||
MWMActionBarButtonTypeBookmark,
|
||||
MWMActionBarButtonTypeTrack,
|
||||
MWMActionBarButtonTypeSaveTrackRecording,
|
||||
MWMActionBarButtonTypeCall,
|
||||
MWMActionBarButtonTypeDownload,
|
||||
MWMActionBarButtonTypeMore,
|
||||
|
|
|
@ -19,6 +19,8 @@ NSString *titleForButton(MWMActionBarButtonType type, BOOL isSelected) {
|
|||
case MWMActionBarButtonTypeBookmark:
|
||||
case MWMActionBarButtonTypeTrack:
|
||||
return L(isSelected ? @"delete" : @"save");
|
||||
case MWMActionBarButtonTypeSaveTrackRecording:
|
||||
return L(@"save");
|
||||
case MWMActionBarButtonTypeRouteFrom:
|
||||
return L(@"p2p_from_here");
|
||||
case MWMActionBarButtonTypeRouteTo:
|
||||
|
@ -55,7 +57,8 @@ NSString *titleForButton(MWMActionBarButtonType type, BOOL isSelected) {
|
|||
self.label.text = titleForButton(self.type, isSelected);
|
||||
self.extraBackground.hidden = YES;
|
||||
self.button.coloring = MWMButtonColoringBlack;
|
||||
|
||||
[self.button.imageView setContentMode:UIViewContentModeScaleAspectFit];
|
||||
|
||||
switch (self.type) {
|
||||
case MWMActionBarButtonTypeDownload: {
|
||||
if (self.mapDownloadProgress)
|
||||
|
@ -108,6 +111,9 @@ NSString *titleForButton(MWMActionBarButtonType type, BOOL isSelected) {
|
|||
[self.button setImage:[[UIImage imageNamed:@"ic_route_manager_trash"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
|
||||
self.button.coloring = MWMButtonColoringRed;
|
||||
break;
|
||||
case MWMActionBarButtonTypeSaveTrackRecording:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_placepage_save_track_recording"] forState:UIControlStateNormal];
|
||||
break;
|
||||
case MWMActionBarButtonTypeRouteFrom:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_route_from"] forState:UIControlStateNormal];
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
final class PlacePageTrackRecordingLayout: IPlacePageLayout {
|
||||
private var placePageData: PlacePageData
|
||||
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]
|
||||
}()
|
||||
|
||||
lazy var headerViewController: PlacePageHeaderViewController = {
|
||||
return PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .flexible)
|
||||
}()
|
||||
|
||||
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 elevationProfileViewController: ElevationProfileViewController? = {
|
||||
guard let trackData = placePageData.trackData else {
|
||||
return nil
|
||||
}
|
||||
return ElevationProfileBuilder.build(trackInfo: trackData.trackInfo,
|
||||
elevationProfileData: trackData.elevationProfileData,
|
||||
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
|
||||
}
|
||||
|
||||
private func configureViewControllers() -> [UIViewController] {
|
||||
var viewControllers = [UIViewController]()
|
||||
|
||||
if let elevationProfileViewController {
|
||||
viewControllers.append(elevationProfileViewController)
|
||||
}
|
||||
|
||||
placePageData.onTrackRecordingProgressUpdate = { [weak self] in
|
||||
self?.updateTrackRecordingRelatedSections()
|
||||
}
|
||||
|
||||
return viewControllers
|
||||
}
|
||||
|
||||
func calculateSteps(inScrollView scrollView: UIScrollView, compact: Bool) -> [PlacePageState] {
|
||||
var steps: [PlacePageState] = []
|
||||
let scrollHeight = scrollView.height
|
||||
steps.append(.closed(-scrollHeight))
|
||||
steps.append(.full(0))
|
||||
return steps
|
||||
}
|
||||
}
|
||||
|
||||
private extension PlacePageTrackRecordingLayout {
|
||||
func updateTrackRecordingRelatedSections() {
|
||||
guard let elevationProfileViewController, let trackInfo = placePageData.trackData?.trackInfo else { return }
|
||||
headerViewController.setTitle(placePageData.previewData.title, secondaryTitle: nil)
|
||||
elevationProfileViewController.presenter?.update(trackInfo: trackInfo, profileData: placePageData.trackData?.elevationProfileData)
|
||||
presenter?.layoutIfNeeded()
|
||||
}
|
||||
}
|
Reference in a new issue