diff --git a/iphone/Maps/Bridging-Header.h b/iphone/Maps/Bridging-Header.h index 9b79341152..04ca808569 100644 --- a/iphone/Maps/Bridging-Header.h +++ b/iphone/Maps/Bridging-Header.h @@ -34,6 +34,7 @@ #import "MWMPlacePageManagerHelper.h" #import "MWMPlacePageTaxiProvider.h" #import "MWMPushNotifications.h" +#import "MWMRouteManagerPointType.h" #import "MWMRoutePreviewTaxiCellType.h" #import "MWMRouter.h" #import "MWMSearchItemType.h" @@ -41,12 +42,12 @@ #import "MWMSettings.h" #import "MWMSideButtons.h" #import "MWMTableViewCell.h" +#import "MWMTableViewController.h" #import "MWMTextToSpeech.h" #import "MWMTextToSpeechObserver.h" #import "MWMTextView.h" #import "MWMTrafficButtonViewController.h" #import "MWMTrafficManager.h" - #import "MWMViewController.h" #import "Statistics.h" #import "UIButton+RuntimeAttributes.h" diff --git a/iphone/Maps/Categories/UIKitCategories.h b/iphone/Maps/Categories/UIKitCategories.h index 63acc0e2c5..e2e516e34b 100644 --- a/iphone/Maps/Categories/UIKitCategories.h +++ b/iphone/Maps/Categories/UIKitCategories.h @@ -96,13 +96,6 @@ typedef void (^MWMAlertViewCompletionBlock) (UIAlertView * alertView, NSInteger @end -@interface UINavigationController (Autorotate) - -- (BOOL)shouldAutorotate; -- (NSUInteger)supportedInterfaceOrientations; - -@end - @interface UIViewController (Safari) - (void)openUrl:(NSURL *)url; diff --git a/iphone/Maps/Categories/UIKitCategories.mm b/iphone/Maps/Categories/UIKitCategories.mm index f5691abc26..b92ec48558 100644 --- a/iphone/Maps/Categories/UIKitCategories.mm +++ b/iphone/Maps/Categories/UIKitCategories.mm @@ -280,6 +280,10 @@ @implementation UINavigationController (Autorotate) - (BOOL)shouldAutorotate { return [[self.viewControllers lastObject] shouldAutorotate]; } +@end + +@implementation UIViewController (Autorotate) + - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } @end diff --git a/iphone/Maps/Categories/UITableView+Updates.swift b/iphone/Maps/Categories/UITableView+Updates.swift index 40446ae096..660322cf22 100644 --- a/iphone/Maps/Categories/UITableView+Updates.swift +++ b/iphone/Maps/Categories/UITableView+Updates.swift @@ -1,5 +1,6 @@ extension UITableView { typealias Updates = () -> Void + typealias Completion = () -> Void func update(_ updates: Updates) { beginUpdates() @@ -7,6 +8,15 @@ extension UITableView { endUpdates() } + func update(_ updates: Updates, completion: @escaping Completion) { + CATransaction.begin() + beginUpdates() + CATransaction.setCompletionBlock(completion) + updates() + endUpdates() + CATransaction.commit() + } + func refresh() { update {} } diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm index 109a050cc8..9a24219659 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm @@ -51,7 +51,9 @@ using Observers = NSHashTable; @property(nonatomic) Observers * observers; @property(nonatomic, readwrite) MWMTaxiPreviewDataSource * taxiDataSource; @property(weak, nonatomic) IBOutlet MWMTaxiCollectionView * taxiCollectionView; +@property(weak, nonatomic) IBOutlet UIButton * showRouteManagerButton; @property(weak, nonatomic) UIView * ownerView; +@property(nonatomic) MWMRouteManagerTransitioningManager * routeManagerTransitioningManager; @end @@ -225,6 +227,28 @@ using Observers = NSHashTable; [self onNavigationInfoUpdated]; } +#pragma mark - MWMRoutePreviewStatus + +- (IBAction)showRouteManager +{ + auto routeManagerViewModel = [[MWMRouteManagerViewModel alloc] init]; + auto routeManager = + [[MWMRouteManagerViewController alloc] initWithViewModel:routeManagerViewModel]; + routeManager.modalPresentationStyle = UIModalPresentationCustom; + if (IPAD) + { + self.routeManagerTransitioningManager = [[MWMRouteManagerTransitioningManager alloc] + initWithPopoverSourceView:self.showRouteManagerButton + permittedArrowDirections:UIPopoverArrowDirectionLeft]; + } + else + { + self.routeManagerTransitioningManager = [[MWMRouteManagerTransitioningManager alloc] init]; + } + routeManager.transitioningDelegate = self.routeManagerTransitioningManager; + [[MapViewController controller] presentViewController:routeManager animated:YES completion:nil]; +} + #pragma mark - MWMNavigationControlView - (IBAction)ttsButtonAction diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPadRoutePreview.xib b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPadRoutePreview.xib index 06c6451d52..a669364a67 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPadRoutePreview.xib +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPadRoutePreview.xib @@ -19,6 +19,7 @@ + @@ -260,6 +261,9 @@ + + + diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPhoneRoutePreview.xib b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPhoneRoutePreview.xib index 582476df55..f9ff9c7880 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPhoneRoutePreview.xib +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPhoneRoutePreview.xib @@ -180,6 +180,9 @@ + + + diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/MWMRouteManagerPointType.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/MWMRouteManagerPointType.h new file mode 100644 index 0000000000..3e4f19adf8 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/MWMRouteManagerPointType.h @@ -0,0 +1,8 @@ +typedef NS_ENUM(NSInteger, MWMRouteManagerPointType) { + MWMRouteManagerPointTypeStart, + MWMRouteManagerPointTypeA, + MWMRouteManagerPointTypeB, + MWMRouteManagerPointTypeC, + MWMRouteManagerPointTypeFinish, + MWMRouteManagerPointTypeMyPosition +}; diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerCell.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerCell.swift new file mode 100644 index 0000000000..15edc766bf --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerCell.swift @@ -0,0 +1,99 @@ +final class RouteManagerCell: MWMTableViewCell { + @IBOutlet private weak var typeImage: UIImageView! + @IBOutlet private weak var titleLabel: UILabel! { + didSet { + titleLabel.textColor = UIColor.blackPrimaryText() + titleLabel.font = UIFont.regular16() + } + } + @IBOutlet weak var subtitleLabel: UILabel! { + didSet { + subtitleLabel.textColor = UIColor.blackSecondaryText() + subtitleLabel.font = UIFont.regular14() + } + } + @IBOutlet private weak var dragImage: UIImageView! { + didSet { + dragImage.image = #imageLiteral(resourceName: "ic_route_manager_move") + dragImage.tintColor = UIColor.blackSecondaryText() + } + } + @IBOutlet private weak var separator1: UIView! { + didSet { + separator1.backgroundColor = UIColor.blackDividers() + separator1.layer.cornerRadius = 2 + } + } + @IBOutlet weak var separator2: UIView! { + didSet { + separator2.backgroundColor = UIColor.blackDividers() + } + } + + var model: MWMRoutePoint! { + didSet { + guard model != nil else { return } + backgroundColor = UIColor.white() + setupTypeImage() + setupLabels() + setupSeparators() + } + } + @IBOutlet var subtitleConstraints: [NSLayoutConstraint]! + + override var snapshot: UIView { + let skipViews: [UIView] = [typeImage, separator1, separator2] + skipViews.forEach { $0.isHidden = true } + backgroundColor = UIColor.blackOpaque() + let snapshot = super.snapshot + backgroundColor = UIColor.white() + skipViews.forEach { $0.isHidden = false } + return snapshot + } + + private func setupTypeImage() { + if model.isMyPosition { + typeImage.image = #imageLiteral(resourceName: "ic_route_manager_my_position") + typeImage.tintColor = UIColor.linkBlue() + } else { + switch model.type { + case .start: + typeImage.image = #imageLiteral(resourceName: "ic_route_manager_start") + typeImage.tintColor = UIColor.linkBlue() + case .intermediate: + switch model.intermediateIndex { + case 0: + typeImage.image = #imageLiteral(resourceName: "ic_route_manager_stop_a") + typeImage.tintColor = UIColor.primary() + case 1: + typeImage.image = #imageLiteral(resourceName: "ic_route_manager_stop_b") + typeImage.tintColor = UIColor.primary() + case 2: + typeImage.image = #imageLiteral(resourceName: "ic_route_manager_stop_c") + typeImage.tintColor = UIColor.primary() + default: fatalError("Unsupported route point intermediateIndex.") + } + case .finish: + typeImage.image = #imageLiteral(resourceName: "ic_route_manager_finish") + typeImage.tintColor = UIColor.blackPrimaryText() + } + } + } + + private func setupLabels() { + titleLabel.text = model.title + var subtitleConstraintsActive = false + if let subtitle = model.subtitle, !subtitle.isEmpty { + subtitleLabel.text = subtitle + subtitleConstraintsActive = true + } + subtitleLabel.isHidden = !subtitleConstraintsActive + subtitleConstraints.forEach { $0.isActive = subtitleConstraintsActive } + } + + private func setupSeparators() { + let isSeparatorsHidden = model.type == .finish + separator1.isHidden = isSeparatorsHidden + separator2.isHidden = isSeparatorsHidden + } +} diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerCell.xib b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerCell.xib new file mode 100644 index 0000000000..9098846910 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerCell.xib @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerDimView.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerDimView.swift new file mode 100644 index 0000000000..ee772c95e9 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerDimView.swift @@ -0,0 +1,94 @@ +final class RouteManagerDimView: UIView { + @IBOutlet private weak var image: UIImageView! + @IBOutlet private weak var label: UILabel! { + didSet { + label.text = L("planning_route_remove_title") + label.font = UIFont.regular18() + label.textColor = UIColor.white() + } + } + @IBOutlet private weak var messageView: UIView! + @IBOutlet private weak var messageViewContainer: UIView! + @IBOutlet private var messageViewVerticalCenter: NSLayoutConstraint! + @IBOutlet private var labelVerticalCenter: NSLayoutConstraint! + + enum State { + case visible + case binOpenned + case hidden + } + + var state = State.hidden { + didSet { + guard state != oldValue else { return } + switch state { + case .visible: + isVisible = true + image.image = #imageLiteral(resourceName: "ic_route_manager_trash") + case .binOpenned: + isVisible = true + image.image = #imageLiteral(resourceName: "ic_route_manager_trash_open") + case .hidden: + isVisible = false + } + } + } + + var binDropPoint: CGPoint { + return convert(image.isHidden ? label.center : image.center, from: messageView) + } + + private var isVisible = false { + didSet { + guard isVisible != oldValue else { return } + let componentsAlpha: CGFloat = 0.5 + backgroundColor = UIColor.blackStatusBarBackground() + alpha = isVisible ? 0 : 1 + image.alpha = isVisible ? 0 : componentsAlpha + label.alpha = isVisible ? 0 : componentsAlpha + UIView.animate(withDuration: kDefaultAnimationDuration, + animations: { + self.alpha = self.isVisible ? 1 : 0 + self.image.alpha = self.isVisible ? componentsAlpha : 0 + self.label.alpha = self.isVisible ? componentsAlpha : 0 + }, + completion: { _ in + self.alpha = 1 + if !self.isVisible { + self.backgroundColor = UIColor.clear + } + }) + setNeedsLayout() + } + } + + func setViews(container: UIView, controller: UIView, manager: UIView) { + alpha = 0 + + alternative(iPhone: { + controller.insertSubview(self, at: 0) + + NSLayoutConstraint(item: self, attribute: .left, relatedBy: .equal, toItem: self.messageViewContainer, attribute: .left, multiplier: 1, constant: 0).isActive = true + NSLayoutConstraint(item: manager, attribute: .top, relatedBy: .equal, toItem: self.messageViewContainer, attribute: .bottom, multiplier: 1, constant: 0).isActive = true + }, + iPad: { + container.insertSubview(self, at: 0) + + NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal, toItem: self.messageViewContainer, attribute: .bottom, multiplier: 1, constant: 0).isActive = true + NSLayoutConstraint(item: controller, attribute: .right, relatedBy: .equal, toItem: self.messageViewContainer, attribute: .left, multiplier: 1, constant: 0).isActive = true + })() + + NSLayoutConstraint(item: container, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1, constant: 0).isActive = true + NSLayoutConstraint(item: container, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 0).isActive = true + NSLayoutConstraint(item: container, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1, constant: 0).isActive = true + NSLayoutConstraint(item: container, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1, constant: 0).isActive = true + } + + override func layoutSubviews() { + super.layoutSubviews() + let isImageHidden = messageView.height > messageViewContainer.height + image.isHidden = isImageHidden + messageViewVerticalCenter.isActive = !isImageHidden + labelVerticalCenter.isActive = isImageHidden + } +} diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerFooterView.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerFooterView.swift new file mode 100644 index 0000000000..c83710a0ae --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerFooterView.swift @@ -0,0 +1,31 @@ +final class RouteManagerFooterView: UIView { + @IBOutlet private weak var cancelButton: UIButton! { + didSet { + cancelButton.setTitle(L("cancel"), for: .normal) + cancelButton.setTitleColor(UIColor.linkBlue(), for: .normal) + } + } + @IBOutlet private weak var planButton: UIButton! { + didSet { + planButton.setTitle(L("button_plan"), for: .normal) + planButton.setTitleColor(UIColor.linkBlue(), for: .normal) + planButton.setTitleColor(UIColor.buttonDisabledBlueText(), for: .disabled) + } + } + @IBOutlet weak var separator: UIView! { + didSet { + separator.backgroundColor = UIColor.blackDividers() + } + } + + var isPlanButtonEnabled = true { + didSet { + planButton.isEnabled = isPlanButtonEnabled + } + } + + override func awakeFromNib() { + super.awakeFromNib() + backgroundColor = UIColor.blackOpaque() + } +} diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerHeaderView.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerHeaderView.swift new file mode 100644 index 0000000000..adfb8b9464 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerHeaderView.swift @@ -0,0 +1,39 @@ +final class RouteManagerHeaderView: UIView { + @IBOutlet private weak var titleLabel: UILabel! { + didSet { + titleLabel.text = L("planning_route_manage_route") + titleLabel.font = UIFont.bold22() + titleLabel.textColor = UIColor.blackPrimaryText() + } + } + @IBOutlet private weak var addLocationButton: UIButton! { + didSet { + addLocationButton.setTitle(L("start_from_my_position"), for: .normal) + addLocationButton.setTitleColor(UIColor.linkBlue(), for: .normal) + addLocationButton.setTitleColor(UIColor.buttonDisabledBlueText(), for: .disabled) + addLocationButton.tintColor = UIColor.linkBlue() + + let flipLR = CGAffineTransform(scaleX: -1.0, y: 1.0) + addLocationButton.transform = flipLR + addLocationButton.titleLabel?.transform = flipLR + addLocationButton.imageView?.transform = flipLR + } + } + @IBOutlet weak var separator: UIView! { + didSet { + separator.backgroundColor = UIColor.blackDividers() + } + } + + var isLocationButtonEnabled = true { + didSet { + addLocationButton.isEnabled = isLocationButtonEnabled + addLocationButton.tintColor = isLocationButtonEnabled ? UIColor.linkBlue() : UIColor.buttonDisabledBlueText() + } + } + + override func awakeFromNib() { + super.awakeFromNib() + backgroundColor = UIColor.white() + } +} diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerTableView.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerTableView.swift new file mode 100644 index 0000000000..1c34631abb --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerTableView.swift @@ -0,0 +1,33 @@ +final class RouteManagerTableView: UITableView { + @IBOutlet private weak var tableViewHeight: NSLayoutConstraint! + + enum HeightUpdateStyle { + case animated + case deferred + case off + } + + var heightUpdateStyle = HeightUpdateStyle.deferred + + override var contentSize: CGSize { + didSet { + guard contentSize != oldValue else { return } + let sel = #selector(updateHeight) + NSObject.cancelPreviousPerformRequests(withTarget: self, selector: sel, object: nil) + switch heightUpdateStyle { + case .animated: + guard let sv = superview else { return } + sv.setNeedsLayout() + updateHeight() + UIView.animate(withDuration: kDefaultAnimationDuration) { sv.layoutIfNeeded() } + case .deferred: perform(sel, with: nil, afterDelay: 0) + case .off: break + } + } + } + + @objc + private func updateHeight() { + tableViewHeight.constant = contentSize.height + } +} diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerTransitioning.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerTransitioning.swift new file mode 100644 index 0000000000..549ea9c0f6 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerTransitioning.swift @@ -0,0 +1,35 @@ +final class RouteManagerTransitioning: NSObject, UIViewControllerAnimatedTransitioning { + private let isPresentation: Bool + + init(isPresentation: Bool) { + self.isPresentation = isPresentation + super.init() + } + + func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { + return kDefaultAnimationDuration + } + + func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + guard let fromVC = transitionContext.viewController(forKey: .from), + let toVC = transitionContext.viewController(forKey: .to) else { return } + + let animatingVC = isPresentation ? toVC : fromVC + guard let animatingView = animatingVC.view else { return } + + let finalFrameForVC = transitionContext.finalFrame(for: animatingVC) + var initialFrameForVC = finalFrameForVC + initialFrameForVC.origin.y += initialFrameForVC.size.height + + let initialFrame = isPresentation ? initialFrameForVC : finalFrameForVC + let finalFrame = isPresentation ? finalFrameForVC : initialFrameForVC + + animatingView.frame = initialFrame + + UIView.animate(withDuration: transitionDuration(using: transitionContext), + animations: { animatingView.frame = finalFrame }, + completion: { _ in + transitionContext.completeTransition(true) + }) + } +} diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerTransitioningManager.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerTransitioningManager.swift new file mode 100644 index 0000000000..e22f5ba888 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerTransitioningManager.swift @@ -0,0 +1,38 @@ +@objc(MWMRouteManagerTransitioningManager) +final class RouteManagerTransitioningManager: NSObject, UIViewControllerTransitioningDelegate { + private var popoverSourceView: UIView! + private var permittedArrowDirections: UIPopoverArrowDirection! + + override init() { + super.init() + } + + init(popoverSourceView: UIView, permittedArrowDirections: UIPopoverArrowDirection) { + self.popoverSourceView = popoverSourceView + self.permittedArrowDirections = permittedArrowDirections + super.init() + } + + func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { + return alternative(iPhone: { () -> UIPresentationController in + return RouteManageriPhonePresentationController(presentedViewController: presented, + presenting: presenting) + }, + iPad: { () -> UIPresentationController in + let popover = RouteManageriPadPresentationController(presentedViewController: presented, + presenting: presenting) + popover.sourceView = self.popoverSourceView + popover.sourceRect = self.popoverSourceView.bounds + popover.permittedArrowDirections = self.permittedArrowDirections + return popover + })() + } + + func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { + return RouteManagerTransitioning(isPresentation: true) + } + + func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { + return RouteManagerTransitioning(isPresentation: false) + } +} diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerViewController.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerViewController.swift new file mode 100644 index 0000000000..c4a0da0b5f --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerViewController.swift @@ -0,0 +1,239 @@ +@objc(MWMRouteManagerViewController) +final class RouteManagerViewController: MWMViewController, UITableViewDataSource, UITableViewDelegate { + let viewModel: RouteManagerViewModelProtocol + + @IBOutlet private var dimView: RouteManagerDimView! + @IBOutlet private weak var footerViewHeight: NSLayoutConstraint! + @IBOutlet private weak var headerView: RouteManagerHeaderView! + @IBOutlet private weak var footerView: RouteManagerFooterView! + @IBOutlet private weak var headerViewHeight: NSLayoutConstraint! + @IBOutlet private weak var managerView: UIView! + @IBOutlet private weak var managerWidth: NSLayoutConstraint! + @IBOutlet private weak var minManagerTopOffset: NSLayoutConstraint! + @IBOutlet private weak var tableView: RouteManagerTableView! + + lazy var chromeView: UIView = { + let view = UIView() + view.backgroundColor = UIColor.blackStatusBarBackground() + return view + }() + + weak var containerView: UIView! + + final class DragCell { + weak var controller: RouteManagerViewController! + let snapshot: UIView + var indexPath: IndexPath + + init(controller: RouteManagerViewController, cell: UITableViewCell, dragPoint: CGPoint, indexPath: IndexPath) { + self.controller = controller + snapshot = cell.snapshot + self.indexPath = indexPath + addSubView(cell: cell, dragPoint: dragPoint) + controller.tableView.heightUpdateStyle = .off + controller.dimView.state = .visible + } + + private func addSubView(cell: UITableViewCell, dragPoint: CGPoint) { + let view = controller.containerView! + view.addSubview(snapshot) + snapshot.center = view.convert(cell.center, from: controller.tableView) + cell.isHidden = true + UIView.animate(withDuration: kDefaultAnimationDuration, + animations: { [snapshot] in + snapshot.center = dragPoint + let scaleFactor: CGFloat = 1.05 + snapshot.transform = CGAffineTransform(scaleX: scaleFactor, y: scaleFactor) + }) + } + + func move(dragPoint: CGPoint, indexPath: IndexPath?, inManagerView: Bool) { + snapshot.center = dragPoint + controller.dimView.state = inManagerView ? .visible : .binOpenned + guard let indexPath = indexPath else { return } + let tv = controller.tableView! + let cell = tv.cellForRow(at: indexPath) + let canMoveCell: Bool + if let cell = cell { + let (centerX, centerY) = (snapshot.width / 2, snapshot.height / 2) + canMoveCell = cell.point(inside: cell.convert(CGPoint(x: centerX, y: 1.5 * centerY), from: snapshot), with: nil) && + cell.point(inside: cell.convert(CGPoint(x: centerX, y: 0.5 * centerY), from: snapshot), with: nil) + } else { + canMoveCell = true + } + guard canMoveCell else { return } + let selfIndexPath = self.indexPath + if indexPath != selfIndexPath { + controller.viewModel.movePoint(at: selfIndexPath.row, to: indexPath.row) + + tv.moveRow(at: selfIndexPath, to: indexPath) + tv.reloadRows(at: [selfIndexPath, indexPath], with: .fade) + tv.cellForRow(at: indexPath)?.isHidden = true + + self.indexPath = indexPath + } + } + + func drop(inManagerView: Bool) { + let removeSnapshot = { + self.snapshot.removeFromSuperview() + self.controller.dimView.state = .hidden + } + let containerView = controller.containerView! + let tv = controller.tableView! + if inManagerView { + let dropCenter = tv.cellForRow(at: indexPath)?.center ?? snapshot.center + UIView.animate(withDuration: kDefaultAnimationDuration, + animations: { [snapshot] in + snapshot.center = containerView.convert(dropCenter, from: tv) + snapshot.transform = CGAffineTransform.identity + }, + completion: { [indexPath] _ in + tv.reloadRows(at: [indexPath], with: .none) + removeSnapshot() + }) + } else { + controller.viewModel.deletePoint(at: indexPath.row) + tv.heightUpdateStyle = .animated + tv.deleteRows(at: [indexPath], with: .automatic) + let dimView = controller.dimView! + UIView.animate(withDuration: kDefaultAnimationDuration, + animations: { [snapshot] in + snapshot.center = containerView.convert(dimView.binDropPoint, from: dimView) + let scaleFactor: CGFloat = 0.2 + snapshot.transform = CGAffineTransform(scaleX: scaleFactor, y: scaleFactor) + }, + completion: { _ in + removeSnapshot() + }) + } + } + + deinit { + controller.tableView.heightUpdateStyle = .deferred + } + } + + var dragCell: DragCell? + + init(viewModel: RouteManagerViewModelProtocol) { + self.viewModel = viewModel + super.init(nibName: toString(type(of: self)), bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + setupTableView() + setupLayout() + + viewModel.refreshControlsCallback = { [unowned viewModel, unowned self] in + let points = viewModel.routePoints + self.footerView.isPlanButtonEnabled = points.count >= 2 + self.headerView.isLocationButtonEnabled = true + points.forEach { + if $0.isMyPosition { + self.headerView.isLocationButtonEnabled = false + } + } + } + viewModel.refreshControlsCallback() + viewModel.startTransaction() + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + dimView.setViews(container: containerView, controller: view, manager: managerView) + containerView.insertSubview(chromeView, at: 0) + } + + override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + if preferredContentSize != managerView.size { + preferredContentSize = managerView.size + } + } + + private func setupLayout() { + alternative(iPhone: { self.managerWidth.isActive = false }, + iPad: { self.minManagerTopOffset.isActive = false })() + } + + private func setupTableView() { + tableView.register(cellClass: RouteManagerCell.self) + tableView.estimatedRowHeight = 48 + tableView.rowHeight = UITableViewAutomaticDimension + } + + @IBAction func onCancel() { + viewModel.cancelTransaction() + dismiss(animated: true, completion: nil) + } + + @IBAction func onPlan() { + viewModel.finishTransaction() + dismiss(animated: true, completion: nil) + } + + @IBAction func onAdd() { + viewModel.addLocationPoint() + tableView.heightUpdateStyle = .off + tableView.update({ + tableView.reloadRows(at: [IndexPath(row: 0, section: 0)], with: .fade) + }, completion: { + self.tableView.heightUpdateStyle = .deferred + }) + } + + @IBAction private func longPressGestureRecognized(_ longPress: UILongPressGestureRecognizer) { + let locationInView = gestureLocation(longPress, in: containerView) + let locationInTableView = gestureLocation(longPress, in: tableView) + switch longPress.state { + case .began: + guard let indexPath = tableView.indexPathForRow(at: locationInTableView), + let cell = tableView.cellForRow(at: indexPath) else { return } + dragCell = DragCell(controller: self, cell: cell, dragPoint: locationInView, indexPath: indexPath) + case .changed: + guard let dragCell = dragCell else { return } + let indexPath = tableView.indexPathForRow(at: locationInTableView) + let inManagerView = managerView.point(inside: gestureLocation(longPress, in: managerView), with: nil) + dragCell.move(dragPoint: locationInView, indexPath: indexPath, inManagerView: inManagerView) + default: + guard let dragCell = dragCell else { return } + let inManagerView = managerView.point(inside: gestureLocation(longPress, in: managerView), with: nil) + dragCell.drop(inManagerView: inManagerView) + self.dragCell = nil + } + } + + private func gestureLocation(_ gestureRecognizer: UIGestureRecognizer, in view: UIView) -> CGPoint { + var location = gestureRecognizer.location(in: view) + iPhoneSpecific { location.x = view.width / 2 } + return location + } + +// MARK: - UITableViewDataSource + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return viewModel.routePoints.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withCellClass: RouteManagerCell.self, indexPath: indexPath) as! RouteManagerCell + cell.model = viewModel.routePoints[indexPath.row] +// cell.isHidden = indexPath == dragCell?.indexPath + return cell + } + + func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { + viewModel.deletePoint(at: indexPath.row) + tableView.deleteRows(at: [indexPath], with: .automatic) + } + +// MARK: - UITableViewDelegate + func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle { + return .delete + } +} diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerViewController.xib b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerViewController.xib new file mode 100644 index 0000000000..344190636c --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerViewController.xib @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerViewModel.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerViewModel.swift new file mode 100644 index 0000000000..c4c60f4545 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerViewModel.swift @@ -0,0 +1,27 @@ +@objc(MWMRouteManagerViewModel) +final class RouteManagerViewModel: NSObject, RouteManagerViewModelProtocol { + var routePoints: [MWMRoutePoint] { return MWMRouter.points() } + var refreshControlsCallback: (() -> Void)! + + func startTransaction() { MWMRouter.openRouteManagerTransaction() } + + func finishTransaction() { + MWMRouter.applyRouteManagerTransaction() + MWMRouter.rebuild(withBestRouter: false) + } + + func cancelTransaction() { MWMRouter.cancelRouteManagerTransaction() } + + func addLocationPoint() { + MWMRouter.addPoint(MWMRoutePoint(lastLocationAndType: .start, intermediateIndex: 0)) + refreshControlsCallback() + } + func movePoint(at index: Int, to newIndex: Int) { + MWMRouter.movePoint(at: index, to: newIndex) + refreshControlsCallback() + } + func deletePoint(at index: Int) { + MWMRouter.removePoint(routePoints[index]) + refreshControlsCallback() + } +} diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerViewModelProtocol.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerViewModelProtocol.swift new file mode 100644 index 0000000000..1dcd471daf --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManagerViewModelProtocol.swift @@ -0,0 +1,14 @@ +@objc(MWMRouteManagerViewModelProtocol) +protocol RouteManagerViewModelProtocol: class { + var routePoints: [MWMRoutePoint] { get } + + var refreshControlsCallback: (() -> Void)! { get set } + + func startTransaction() + func finishTransaction() + func cancelTransaction() + + func addLocationPoint() + func movePoint(at index: Int, to newIndex: Int) + func deletePoint(at index: Int) +} diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManageriPadPresentationController.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManageriPadPresentationController.swift new file mode 100644 index 0000000000..86c4c49108 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManageriPadPresentationController.swift @@ -0,0 +1,36 @@ +final class RouteManageriPadPresentationController: UIPopoverPresentationController { + private let chromeView = UIView() + + override func containerViewWillLayoutSubviews() { + super.containerViewWillLayoutSubviews() + (presentedViewController as? RouteManagerViewController)?.chromeView.frame = containerView!.bounds + } + + override func presentationTransitionWillBegin() { + super.presentationTransitionWillBegin() + guard let presentedViewController = presentedViewController as? RouteManagerViewController, + let coordinator = presentedViewController.transitionCoordinator, + let containerView = containerView else { return } + + presentedViewController.containerView = containerView + presentedViewController.chromeView.frame = containerView.bounds + presentedViewController.chromeView.alpha = 0 + + coordinator.animate(alongsideTransition: { _ in + presentedViewController.chromeView.alpha = 1 + }, completion: nil) + } + + override func dismissalTransitionWillBegin() { + super.dismissalTransitionWillBegin() + guard let presentedViewController = presentedViewController as? RouteManagerViewController, + let coordinator = presentedViewController.transitionCoordinator, + let presentedView = presentedView else { return } + + coordinator.animate(alongsideTransition: { _ in + presentedViewController.chromeView.alpha = 0 + }, completion: { _ in + presentedView.removeFromSuperview() + }) + } +} diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManageriPhonePresentationController.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManageriPhonePresentationController.swift new file mode 100644 index 0000000000..d5abe50be3 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteManager/RouteManageriPhonePresentationController.swift @@ -0,0 +1,36 @@ +final class RouteManageriPhonePresentationController: UIPresentationController { + override func containerViewWillLayoutSubviews() { + super.containerViewWillLayoutSubviews() + (presentedViewController as? RouteManagerViewController)?.chromeView.frame = containerView!.bounds + presentedView?.frame = frameOfPresentedViewInContainerView + } + + override func presentationTransitionWillBegin() { + super.presentationTransitionWillBegin() + guard let presentedViewController = presentedViewController as? RouteManagerViewController, + let coordinator = presentedViewController.transitionCoordinator, + let containerView = containerView else { return } + + containerView.addSubview(presentedView!) + presentedViewController.containerView = containerView + presentedViewController.chromeView.frame = containerView.bounds + presentedViewController.chromeView.alpha = 0 + + coordinator.animate(alongsideTransition: { _ in + presentedViewController.chromeView.alpha = 1 + }, completion: nil) + } + + override func dismissalTransitionWillBegin() { + super.dismissalTransitionWillBegin() + guard let presentedViewController = presentedViewController as? RouteManagerViewController, + let coordinator = presentedViewController.transitionCoordinator, + let presentedView = presentedView else { return } + + coordinator.animate(alongsideTransition: { _ in + presentedViewController.chromeView.alpha = 0 + }, completion: { _ in + presentedView.removeFromSuperview() + }) + } +} diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index d1a6ece980..19443d9d14 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -181,6 +181,27 @@ 341F09841C20138100F18AC5 /* libpugixml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 341F09831C20138100F18AC5 /* libpugixml.a */; }; 34201E091DC0DC7300D24118 /* libpartners_api.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DDB4BC31DAB98F000F4D021 /* libpartners_api.a */; }; 34201E0C1DC0E33100D24118 /* libtracking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34201E0B1DC0E33100D24118 /* libtracking.a */; }; + 342360931F3456E200AFE44D /* RouteManagerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342360911F3456E200AFE44D /* RouteManagerViewController.swift */; }; + 342360941F3456E200AFE44D /* RouteManagerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342360911F3456E200AFE44D /* RouteManagerViewController.swift */; }; + 342360951F3456E200AFE44D /* RouteManagerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342360911F3456E200AFE44D /* RouteManagerViewController.swift */; }; + 342360961F3456E200AFE44D /* RouteManagerViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 342360921F3456E200AFE44D /* RouteManagerViewController.xib */; }; + 342360971F3456E200AFE44D /* RouteManagerViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 342360921F3456E200AFE44D /* RouteManagerViewController.xib */; }; + 342360981F3456E200AFE44D /* RouteManagerViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 342360921F3456E200AFE44D /* RouteManagerViewController.xib */; }; + 3423609A1F34585A00AFE44D /* RouteManagerFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342360991F34585A00AFE44D /* RouteManagerFooterView.swift */; }; + 3423609B1F34585A00AFE44D /* RouteManagerFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342360991F34585A00AFE44D /* RouteManagerFooterView.swift */; }; + 3423609C1F34585A00AFE44D /* RouteManagerFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342360991F34585A00AFE44D /* RouteManagerFooterView.swift */; }; + 3423609E1F34787F00AFE44D /* RouteManagerTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3423609D1F34787F00AFE44D /* RouteManagerTableView.swift */; }; + 3423609F1F34787F00AFE44D /* RouteManagerTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3423609D1F34787F00AFE44D /* RouteManagerTableView.swift */; }; + 342360A01F34787F00AFE44D /* RouteManagerTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3423609D1F34787F00AFE44D /* RouteManagerTableView.swift */; }; + 342360A21F34840500AFE44D /* RouteManagerDimView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342360A11F34840500AFE44D /* RouteManagerDimView.swift */; }; + 342360A31F34840500AFE44D /* RouteManagerDimView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342360A11F34840500AFE44D /* RouteManagerDimView.swift */; }; + 342360A41F34840500AFE44D /* RouteManagerDimView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342360A11F34840500AFE44D /* RouteManagerDimView.swift */; }; + 342360A71F34906700AFE44D /* RouteManagerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342360A51F34906700AFE44D /* RouteManagerCell.swift */; }; + 342360A81F34906700AFE44D /* RouteManagerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342360A51F34906700AFE44D /* RouteManagerCell.swift */; }; + 342360A91F34906700AFE44D /* RouteManagerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342360A51F34906700AFE44D /* RouteManagerCell.swift */; }; + 342360AA1F34906700AFE44D /* RouteManagerCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 342360A61F34906700AFE44D /* RouteManagerCell.xib */; }; + 342360AB1F34906700AFE44D /* RouteManagerCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 342360A61F34906700AFE44D /* RouteManagerCell.xib */; }; + 342360AC1F34906700AFE44D /* RouteManagerCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 342360A61F34906700AFE44D /* RouteManagerCell.xib */; }; 342639361EA0E60A0025EB89 /* local_ads_symbols.txt in Resources */ = {isa = PBXBuildFile; fileRef = 450703081E9E6CF000E8C029 /* local_ads_symbols.txt */; }; 342639381EA0E60B0025EB89 /* local_ads_symbols.txt in Resources */ = {isa = PBXBuildFile; fileRef = 450703081E9E6CF000E8C029 /* local_ads_symbols.txt */; }; 342CC5F11C2D7730005F3FE5 /* MWMAuthorizationLoginViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 342CC5F01C2D7730005F3FE5 /* MWMAuthorizationLoginViewController.mm */; }; @@ -402,6 +423,12 @@ 3495433E1EB22DAC00F08F73 /* MPAdBrowserController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3495433C1EB22D9600F08F73 /* MPAdBrowserController.xib */; }; 3495433F1EB22DAD00F08F73 /* MPAdBrowserController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3495433C1EB22D9600F08F73 /* MPAdBrowserController.xib */; }; 3497A93A1B5CF8A900F51E55 /* MWMNavigationDashboardManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3497A9371B5CF8A900F51E55 /* MWMNavigationDashboardManager.mm */; }; + 349993FA1F388F970064CFBE /* RouteManageriPadPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349993F81F388F970064CFBE /* RouteManageriPadPresentationController.swift */; }; + 349993FB1F388F970064CFBE /* RouteManageriPadPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349993F81F388F970064CFBE /* RouteManageriPadPresentationController.swift */; }; + 349993FC1F388F970064CFBE /* RouteManageriPadPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349993F81F388F970064CFBE /* RouteManageriPadPresentationController.swift */; }; + 349993FD1F388F970064CFBE /* RouteManageriPhonePresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349993F91F388F970064CFBE /* RouteManageriPhonePresentationController.swift */; }; + 349993FE1F388F970064CFBE /* RouteManageriPhonePresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349993F91F388F970064CFBE /* RouteManageriPhonePresentationController.swift */; }; + 349993FF1F388F970064CFBE /* RouteManageriPhonePresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349993F91F388F970064CFBE /* RouteManageriPhonePresentationController.swift */; }; 349A13821DEC138C00C7DB60 /* MWMMobileInternetAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = 349A13801DEC138C00C7DB60 /* MWMMobileInternetAlert.mm */; }; 349A13831DEC138C00C7DB60 /* MWMMobileInternetAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = 349A13801DEC138C00C7DB60 /* MWMMobileInternetAlert.mm */; }; 349A13841DEC138C00C7DB60 /* MWMMobileInternetAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = 349A13811DEC138C00C7DB60 /* MWMMobileInternetAlert.xib */; }; @@ -478,6 +505,18 @@ 34BC72241B0DECAE0012A34B /* MWMMapViewControlsManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34BC72111B0DECAE0012A34B /* MWMMapViewControlsManager.mm */; }; 34BF0CC61C31304A00D097EB /* MWMAuthorizationCommon.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34BF0CC51C31304A00D097EB /* MWMAuthorizationCommon.mm */; }; 34BF0CC71C31304A00D097EB /* MWMAuthorizationCommon.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34BF0CC51C31304A00D097EB /* MWMAuthorizationCommon.mm */; }; + 34C5B80F1F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B80E1F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift */; }; + 34C5B8101F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B80E1F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift */; }; + 34C5B8111F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B80E1F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift */; }; + 34C5B8131F335BCA005E50B6 /* RouteManagerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B8121F335BCA005E50B6 /* RouteManagerViewModel.swift */; }; + 34C5B8141F335BCA005E50B6 /* RouteManagerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B8121F335BCA005E50B6 /* RouteManagerViewModel.swift */; }; + 34C5B8151F335BCA005E50B6 /* RouteManagerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B8121F335BCA005E50B6 /* RouteManagerViewModel.swift */; }; + 34C5B81B1F3367E1005E50B6 /* RouteManagerTransitioningManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B81A1F3367E1005E50B6 /* RouteManagerTransitioningManager.swift */; }; + 34C5B81C1F3367E1005E50B6 /* RouteManagerTransitioningManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B81A1F3367E1005E50B6 /* RouteManagerTransitioningManager.swift */; }; + 34C5B81D1F3367E1005E50B6 /* RouteManagerTransitioningManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B81A1F3367E1005E50B6 /* RouteManagerTransitioningManager.swift */; }; + 34C5B8231F336DF5005E50B6 /* RouteManagerTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B8221F336DF5005E50B6 /* RouteManagerTransitioning.swift */; }; + 34C5B8241F336DF5005E50B6 /* RouteManagerTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B8221F336DF5005E50B6 /* RouteManagerTransitioning.swift */; }; + 34C5B8251F336DF5005E50B6 /* RouteManagerTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B8221F336DF5005E50B6 /* RouteManagerTransitioning.swift */; }; 34C9BD021C6DB693000DC38D /* MWMTableViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34C9BCFF1C6DB693000DC38D /* MWMTableViewController.mm */; }; 34C9BD031C6DB693000DC38D /* MWMTableViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34C9BCFF1C6DB693000DC38D /* MWMTableViewController.mm */; }; 34C9BD041C6DB693000DC38D /* MWMViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34C9BD011C6DB693000DC38D /* MWMViewController.mm */; }; @@ -562,6 +601,9 @@ 34D4FA661E265749003F53EF /* WhatsNewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D4FA651E265749003F53EF /* WhatsNewController.swift */; }; 34D4FA671E265749003F53EF /* WhatsNewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D4FA651E265749003F53EF /* WhatsNewController.swift */; }; 34D4FA681E265749003F53EF /* WhatsNewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D4FA651E265749003F53EF /* WhatsNewController.swift */; }; + 34D7F3411F33903F001D5ED5 /* RouteManagerHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D7F3401F33903F001D5ED5 /* RouteManagerHeaderView.swift */; }; + 34D7F3421F33903F001D5ED5 /* RouteManagerHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D7F3401F33903F001D5ED5 /* RouteManagerHeaderView.swift */; }; + 34D7F3431F33903F001D5ED5 /* RouteManagerHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D7F3401F33903F001D5ED5 /* RouteManagerHeaderView.swift */; }; 34D8087B1E793606002F0584 /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34D8087A1E793606002F0584 /* Alamofire.framework */; }; 34D8087D1E79360D002F0584 /* AlamofireImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34D8087C1E79360D002F0584 /* AlamofireImage.framework */; }; 34D8087E1E79361A002F0584 /* AlamofireImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34D8087C1E79360D002F0584 /* AlamofireImage.framework */; }; @@ -1797,6 +1839,14 @@ 341C2A5A1B720B8A00AD41A1 /* MWMAPIBarView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMAPIBarView.xib; sourceTree = ""; }; 341F09831C20138100F18AC5 /* libpugixml.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpugixml.a; path = "../../../omim-xcode-build/Debug/libpugixml.a"; sourceTree = ""; }; 34201E0B1DC0E33100D24118 /* libtracking.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtracking.a; path = "../../../omim-xcode-build/Debug/libtracking.a"; sourceTree = ""; }; + 342360911F3456E200AFE44D /* RouteManagerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManagerViewController.swift; sourceTree = ""; }; + 342360921F3456E200AFE44D /* RouteManagerViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RouteManagerViewController.xib; sourceTree = ""; }; + 342360991F34585A00AFE44D /* RouteManagerFooterView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManagerFooterView.swift; sourceTree = ""; }; + 3423609D1F34787F00AFE44D /* RouteManagerTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManagerTableView.swift; sourceTree = ""; }; + 342360A11F34840500AFE44D /* RouteManagerDimView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManagerDimView.swift; sourceTree = ""; }; + 342360A51F34906700AFE44D /* RouteManagerCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManagerCell.swift; sourceTree = ""; }; + 342360A61F34906700AFE44D /* RouteManagerCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RouteManagerCell.xib; sourceTree = ""; }; + 342360B11F349F9800AFE44D /* MWMRouteManagerPointType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMRouteManagerPointType.h; sourceTree = ""; }; 342639461EA0FDB30025EB89 /* MWMSearchItemType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMSearchItemType.h; sourceTree = ""; }; 3427AF0B1E49E3A500D466DB /* MWMConsts.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMConsts.h; sourceTree = ""; }; 342CC5EF1C2D7730005F3FE5 /* MWMAuthorizationLoginViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMAuthorizationLoginViewController.h; sourceTree = ""; }; @@ -1927,6 +1977,8 @@ 3495433C1EB22D9600F08F73 /* MPAdBrowserController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MPAdBrowserController.xib; path = 3party/MoPubSDK/Internal/Common/MPAdBrowserController.xib; sourceTree = ""; }; 3497A9361B5CF8A900F51E55 /* MWMNavigationDashboardManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMNavigationDashboardManager.h; sourceTree = ""; }; 3497A9371B5CF8A900F51E55 /* MWMNavigationDashboardManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = MWMNavigationDashboardManager.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + 349993F81F388F970064CFBE /* RouteManageriPadPresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManageriPadPresentationController.swift; sourceTree = ""; }; + 349993F91F388F970064CFBE /* RouteManageriPhonePresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManageriPhonePresentationController.swift; sourceTree = ""; }; 349A137F1DEC138C00C7DB60 /* MWMMobileInternetAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMMobileInternetAlert.h; sourceTree = ""; }; 349A13801DEC138C00C7DB60 /* MWMMobileInternetAlert.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMMobileInternetAlert.mm; sourceTree = ""; }; 349A13811DEC138C00C7DB60 /* MWMMobileInternetAlert.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMMobileInternetAlert.xib; sourceTree = ""; }; @@ -1981,6 +2033,10 @@ 34BC72111B0DECAE0012A34B /* MWMMapViewControlsManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = MWMMapViewControlsManager.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 34BF0CC51C31304A00D097EB /* MWMAuthorizationCommon.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMAuthorizationCommon.mm; sourceTree = ""; }; 34BF0CC81C31306300D097EB /* MWMAuthorizationCommon.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMAuthorizationCommon.h; sourceTree = ""; }; + 34C5B80E1F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManagerViewModelProtocol.swift; sourceTree = ""; }; + 34C5B8121F335BCA005E50B6 /* RouteManagerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManagerViewModel.swift; sourceTree = ""; }; + 34C5B81A1F3367E1005E50B6 /* RouteManagerTransitioningManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManagerTransitioningManager.swift; sourceTree = ""; }; + 34C5B8221F336DF5005E50B6 /* RouteManagerTransitioning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManagerTransitioning.swift; sourceTree = ""; }; 34C9BCFE1C6DB693000DC38D /* MWMTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMTableViewController.h; sourceTree = ""; }; 34C9BCFF1C6DB693000DC38D /* MWMTableViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = MWMTableViewController.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 34C9BD001C6DB693000DC38D /* MWMViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMViewController.h; sourceTree = ""; }; @@ -2025,6 +2081,7 @@ 34D3B04D1E38A20C004100F9 /* Bundle+Init.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Bundle+Init.swift"; sourceTree = ""; }; 34D4FA611E26572D003F53EF /* FirstLaunchController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FirstLaunchController.swift; sourceTree = ""; }; 34D4FA651E265749003F53EF /* WhatsNewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WhatsNewController.swift; sourceTree = ""; }; + 34D7F3401F33903F001D5ED5 /* RouteManagerHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManagerHeaderView.swift; sourceTree = ""; }; 34D8087A1E793606002F0584 /* Alamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Alamofire.framework; path = Carthage/Build/iOS/Alamofire.framework; sourceTree = ""; }; 34D8087C1E79360D002F0584 /* AlamofireImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AlamofireImage.framework; path = Carthage/Build/iOS/AlamofireImage.framework; sourceTree = ""; }; 34D808851E793F91002F0584 /* Pushwoosh.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Pushwoosh.framework; path = Carthage/Build/iOS/Pushwoosh.framework; sourceTree = ""; }; @@ -3059,6 +3116,7 @@ 3409C9B11F28D3870038F2A9 /* RoutePreview */ = { isa = PBXGroup; children = ( + 34C5B8051F335AC7005E50B6 /* RouteManager */, 3407085E1F28FE2800029ECC /* MWMiPadRoutePreview.h */, 3407085F1F28FE2800029ECC /* MWMiPadRoutePreview.mm */, 340708441F28EDD100029ECC /* MWMiPadRoutePreview.xib */, @@ -3473,6 +3531,28 @@ path = CustomViews/MapViewControls; sourceTree = ""; }; + 34C5B8051F335AC7005E50B6 /* RouteManager */ = { + isa = PBXGroup; + children = ( + 342360B11F349F9800AFE44D /* MWMRouteManagerPointType.h */, + 342360A51F34906700AFE44D /* RouteManagerCell.swift */, + 342360A61F34906700AFE44D /* RouteManagerCell.xib */, + 342360A11F34840500AFE44D /* RouteManagerDimView.swift */, + 342360991F34585A00AFE44D /* RouteManagerFooterView.swift */, + 34D7F3401F33903F001D5ED5 /* RouteManagerHeaderView.swift */, + 349993F81F388F970064CFBE /* RouteManageriPadPresentationController.swift */, + 349993F91F388F970064CFBE /* RouteManageriPhonePresentationController.swift */, + 3423609D1F34787F00AFE44D /* RouteManagerTableView.swift */, + 34C5B8221F336DF5005E50B6 /* RouteManagerTransitioning.swift */, + 34C5B81A1F3367E1005E50B6 /* RouteManagerTransitioningManager.swift */, + 342360911F3456E200AFE44D /* RouteManagerViewController.swift */, + 342360921F3456E200AFE44D /* RouteManagerViewController.xib */, + 34C5B8121F335BCA005E50B6 /* RouteManagerViewModel.swift */, + 34C5B80E1F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift */, + ); + path = RouteManager; + sourceTree = ""; + }; 34D3AFFC1E389D05004100F9 /* Cells */ = { isa = PBXGroup; children = ( @@ -4746,6 +4826,7 @@ 340E1EEB1E2F614400CE49BF /* Authorization.storyboard in Resources */, FAAFD697139D9BE2000AE70C /* categories.txt in Resources */, EE026F0611D6AC0D00645242 /* classificator.txt in Resources */, + 342360961F3456E200AFE44D /* RouteManagerViewController.xib in Resources */, 452FCA3B1B6A3DF7007019AB /* colors.txt in Resources */, 97A5967F19B9CD47007A963F /* copyright.html in Resources */, 4A300ED41C6DCFD400140018 /* countries-strings in Resources */, @@ -4812,6 +4893,7 @@ F6E2FD6D1E097BA00083EBEC /* MWMMapDownloaderSubplaceTableViewCell.xib in Resources */, F6E2FD731E097BA00083EBEC /* MWMMapDownloaderTableViewCell.xib in Resources */, 349A13841DEC138C00C7DB60 /* MWMMobileInternetAlert.xib in Resources */, + 342360AA1F34906700AFE44D /* RouteManagerCell.xib in Resources */, 34D3B04A1E389D05004100F9 /* MWMNoteCell.xib in Resources */, F6E2FDEE1E097BA00083EBEC /* MWMOpeningHoursAddClosedTableViewCell.xib in Resources */, F6E2FDF41E097BA00083EBEC /* MWMOpeningHoursAddScheduleTableViewCell.xib in Resources */, @@ -4928,6 +5010,7 @@ 6741A95C1BF340DE002C974C /* categories.txt in Resources */, 6741A9451BF340DE002C974C /* classificator.txt in Resources */, 676507611C10559B00830BB3 /* colors.txt in Resources */, + 342360971F3456E200AFE44D /* RouteManagerViewController.xib in Resources */, 6741A9711BF340DE002C974C /* copyright.html in Resources */, 4A300ED51C6DCFD400140018 /* countries-strings in Resources */, 6741A9491BF340DE002C974C /* countries.txt in Resources */, @@ -4994,6 +5077,7 @@ 349A13851DEC138C00C7DB60 /* MWMMobileInternetAlert.xib in Resources */, 34D3B04B1E389D05004100F9 /* MWMNoteCell.xib in Resources */, F6E2FDEF1E097BA00083EBEC /* MWMOpeningHoursAddClosedTableViewCell.xib in Resources */, + 342360AB1F34906700AFE44D /* RouteManagerCell.xib in Resources */, F6E2FDF51E097BA00083EBEC /* MWMOpeningHoursAddScheduleTableViewCell.xib in Resources */, F6E2FDFB1E097BA00083EBEC /* MWMOpeningHoursAllDayTableViewCell.xib in Resources */, 342639361EA0E60A0025EB89 /* local_ads_symbols.txt in Resources */, @@ -5110,6 +5194,7 @@ 849CF5ED1DE842290024A8A5 /* classificator.txt in Resources */, 849CF5EC1DE842290024A8A5 /* colors.txt in Resources */, 849CF6391DE842290024A8A5 /* copyright.html in Resources */, + 342360981F3456E200AFE44D /* RouteManagerViewController.xib in Resources */, 849CF6581DE842290024A8A5 /* countries-strings in Resources */, 849CF5F41DE842290024A8A5 /* countries.txt in Resources */, 849CF6571DE842290024A8A5 /* countries_obsolete.txt in Resources */, @@ -5176,6 +5261,7 @@ F6E2FD751E097BA00083EBEC /* MWMMapDownloaderTableViewCell.xib in Resources */, 34D3B04C1E389D05004100F9 /* MWMNoteCell.xib in Resources */, F6E2FDF01E097BA00083EBEC /* MWMOpeningHoursAddClosedTableViewCell.xib in Resources */, + 342360AC1F34906700AFE44D /* RouteManagerCell.xib in Resources */, F6E2FDF61E097BA00083EBEC /* MWMOpeningHoursAddScheduleTableViewCell.xib in Resources */, F6E2FDFC1E097BA00083EBEC /* MWMOpeningHoursAllDayTableViewCell.xib in Resources */, 342639381EA0E60B0025EB89 /* local_ads_symbols.txt in Resources */, @@ -5388,9 +5474,11 @@ buildActionMask = 2147483647; files = ( 34845DB61E166084003D55B9 /* Common.swift in Sources */, + 349993FD1F388F970064CFBE /* RouteManageriPhonePresentationController.swift in Sources */, 1D60589B0D05DD56006BFB54 /* main.mm in Sources */, 34D3B04E1E38A20C004100F9 /* Bundle+Init.swift in Sources */, 340837161B72451A00B5C185 /* MWMShareActivityItem.mm in Sources */, + 342360931F3456E200AFE44D /* RouteManagerViewController.swift in Sources */, F6E2FF531E097BA00083EBEC /* MWMHelpController.mm in Sources */, F6E2FF591E097BA00083EBEC /* MWMNightModeController.mm in Sources */, 3454D7B81E07F045004AF2AD /* CALayer+RuntimeAttributes.mm in Sources */, @@ -5417,6 +5505,7 @@ F6150E511EFA7352000B955D /* MWUGCCommentsController.mm in Sources */, F6E2FE0F1E097BA00083EBEC /* MWMOpeningHoursTableViewCell.mm in Sources */, 341522BF1B666A550077AA8F /* MWMAPIBarView.mm in Sources */, + 3423609A1F34585A00AFE44D /* RouteManagerFooterView.swift in Sources */, 34F742311E0834F400AC1FD6 /* UIViewController+Navigation.mm in Sources */, 340475801E081B3300C92850 /* iosOGLContextFactory.mm in Sources */, 3486B51D1E27AD590069C126 /* MWMFrameworkHelper.mm in Sources */, @@ -5424,6 +5513,7 @@ 34D3B0201E389D05004100F9 /* MWMEditorAddAdditionalNameTableViewCell.mm in Sources */, F6E2FE481E097BA00083EBEC /* MWMPlacePageData.mm in Sources */, 3404754F1E081A4600C92850 /* fabric_logging_ios.mm in Sources */, + 34C5B81B1F3367E1005E50B6 /* RouteManagerTransitioningManager.swift in Sources */, 34ABA6281C2D567B00FE1BEC /* MWMInputLoginValidator.mm in Sources */, 34F4073D1E9E1AFF00E57AC0 /* MPNativeAd+MWM.mm in Sources */, F69018B81E9E601400B3C10B /* MWMAutoupdateController.mm in Sources */, @@ -5461,6 +5551,7 @@ 34763F061F3092E700F4D2D3 /* String+Format.swift in Sources */, F6E2FE4B1E097BA00083EBEC /* MWMPlacePageManager.mm in Sources */, 346DB8391E5C4F6700E3123E /* GalleryItemModel.swift in Sources */, + 34D7F3411F33903F001D5ED5 /* RouteManagerHeaderView.swift in Sources */, 3404757D1E081B3300C92850 /* iosOGLContext.mm in Sources */, F6150E311EF953A6000B955D /* MWMUGCReviewVM.mm in Sources */, 34D3AFF11E37945B004100F9 /* UITableView+Cells.swift in Sources */, @@ -5489,6 +5580,7 @@ 34D3B0171E389D05004100F9 /* EditorAdditionalNamePlaceholderTableViewCell.swift in Sources */, 346DB8271E5C4F6700E3123E /* GalleryCell.swift in Sources */, 3406FA151C6E0C3300E9FAD2 /* MWMMapDownloadDialog.mm in Sources */, + 342360A21F34840500AFE44D /* RouteManagerDimView.swift in Sources */, F6E2FECC1E097BA00083EBEC /* MWMSearchFilterTransitioningManager.mm in Sources */, F6E2FF111E097BA00083EBEC /* MWMSearchHistoryRequestCell.mm in Sources */, 34C9BD021C6DB693000DC38D /* MWMTableViewController.mm in Sources */, @@ -5510,6 +5602,7 @@ F6E2FE271E097BA00083EBEC /* MWMOpeningHoursSection.mm in Sources */, 34F407341E9E1AFF00E57AC0 /* CoreBanner.swift in Sources */, F6E2FE241E097BA00083EBEC /* MWMOpeningHoursModel.mm in Sources */, + 342360A71F34906700AFE44D /* RouteManagerCell.swift in Sources */, 34D3B0351E389D05004100F9 /* MWMEditorSelectTableViewCell.mm in Sources */, F6E2FD8B1E097BA00083EBEC /* MWMNoMapsView.mm in Sources */, F6E2FD701E097BA00083EBEC /* MWMMapDownloaderTableViewCell.mm in Sources */, @@ -5565,6 +5658,7 @@ 3454D7C11E07F045004AF2AD /* NSString+Categories.mm in Sources */, 340E1EFA1E2F614400CE49BF /* Storyboard.swift in Sources */, F6E2FE7B1E097BA00083EBEC /* MWMPlacePageOpeningHoursCell.mm in Sources */, + 34C5B8131F335BCA005E50B6 /* RouteManagerViewModel.swift in Sources */, 34E776321F15FAC2003040B3 /* MWMPlacePageManagerHelper.mm in Sources */, F6E2FF351E097BA00083EBEC /* MWMSearchSuggestionCell.mm in Sources */, F6E2FE391E097BA00083EBEC /* MWMMigrationView.mm in Sources */, @@ -5601,6 +5695,7 @@ F6E2FE031E097BA00083EBEC /* MWMOpeningHoursDaysSelectorTableViewCell.mm in Sources */, F6E2FE661E097BA00083EBEC /* MWMPlacePageButtonCell.mm in Sources */, F6E2FE121E097BA00083EBEC /* MWMOpeningHoursTimeSelectorTableViewCell.mm in Sources */, + 34C5B80F1F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift in Sources */, 340837131B7243CE00B5C185 /* MWMActivityViewController.mm in Sources */, 3486B5181E27AD3B0069C126 /* MWMFrameworkListener.mm in Sources */, 3404756A1E081A4600C92850 /* MWMSearch+CoreSpotlight.mm in Sources */, @@ -5616,12 +5711,14 @@ F6E2FED81E097BA00083EBEC /* MWMSearchContentView.mm in Sources */, F6E2FD881E097BA00083EBEC /* MWMMapDownloaderViewController.mm in Sources */, 34BC72241B0DECAE0012A34B /* MWMMapViewControlsManager.mm in Sources */, + 34C5B8231F336DF5005E50B6 /* RouteManagerTransitioning.swift in Sources */, F6E2FF4A1E097BA00083EBEC /* SettingsTableViewSwitchCell.swift in Sources */, 3407087B1F2B6F5200029ECC /* NavigationControlView.swift in Sources */, 3470402F1EA6470700038379 /* BorderedButton.swift in Sources */, F6E2FE781E097BA00083EBEC /* MWMOpeningHoursLayoutHelper.mm in Sources */, F6BD1D201CA412920047B8E8 /* MWMOsmAuthAlert.mm in Sources */, F6B97B261CD0CA990009B612 /* MWMBookmarkNameCell.mm in Sources */, + 349993FA1F388F970064CFBE /* RouteManageriPadPresentationController.swift in Sources */, F6E2FD7C1E097BA00083EBEC /* MWMMapDownloaderExtendedDataSource.mm in Sources */, F6E2FED21E097BA00083EBEC /* MWMSearchHotelsFilterViewController.mm in Sources */, 34ABA6201C2D517500FE1BEC /* MWMInputValidator.mm in Sources */, @@ -5655,6 +5752,7 @@ 340475701E081A4600C92850 /* MWMSettings.mm in Sources */, 3404756D1E081A4600C92850 /* MWMSearch.mm in Sources */, 3486B5071E27A4B50069C126 /* LocalNotificationManager.mm in Sources */, + 3423609E1F34787F00AFE44D /* RouteManagerTableView.swift in Sources */, F6E2FEFC1E097BA00083EBEC /* MWMSearchCategoryCell.mm in Sources */, 3454D7CA1E07F045004AF2AD /* UIColor+MapsMeColor.mm in Sources */, 3454D7BE1E07F045004AF2AD /* DateComponentsFormatter+ETA.swift in Sources */, @@ -5713,9 +5811,11 @@ buildActionMask = 2147483647; files = ( 34845DB71E166084003D55B9 /* Common.swift in Sources */, + 349993FE1F388F970064CFBE /* RouteManageriPhonePresentationController.swift in Sources */, 6741A9A31BF340DE002C974C /* main.mm in Sources */, 34D3B04F1E38A20C004100F9 /* Bundle+Init.swift in Sources */, F6E2FF541E097BA00083EBEC /* MWMHelpController.mm in Sources */, + 342360941F3456E200AFE44D /* RouteManagerViewController.swift in Sources */, F6E2FF5A1E097BA00083EBEC /* MWMNightModeController.mm in Sources */, 340708581F28F1F000029ECC /* MWMTaxiCollectionLayout.mm in Sources */, 6741A9A51BF340DE002C974C /* MWMShareActivityItem.mm in Sources */, @@ -5742,6 +5842,7 @@ F6150E521EFA7352000B955D /* MWUGCCommentsController.mm in Sources */, F6E2FE101E097BA00083EBEC /* MWMOpeningHoursTableViewCell.mm in Sources */, 6741A9B01BF340DE002C974C /* MapsAppDelegate.mm in Sources */, + 3423609B1F34585A00AFE44D /* RouteManagerFooterView.swift in Sources */, 34F742321E0834F400AC1FD6 /* UIViewController+Navigation.mm in Sources */, 340475811E081B3300C92850 /* iosOGLContextFactory.mm in Sources */, 6741A9B11BF340DE002C974C /* MWMAPIBarView.mm in Sources */, @@ -5749,6 +5850,7 @@ 34D3B0211E389D05004100F9 /* MWMEditorAddAdditionalNameTableViewCell.mm in Sources */, 3486B51E1E27AD590069C126 /* MWMFrameworkHelper.mm in Sources */, F6E2FE491E097BA00083EBEC /* MWMPlacePageData.mm in Sources */, + 34C5B81C1F3367E1005E50B6 /* RouteManagerTransitioningManager.swift in Sources */, 340475501E081A4600C92850 /* fabric_logging_ios.mm in Sources */, 34F4073E1E9E1AFF00E57AC0 /* MPNativeAd+MWM.mm in Sources */, F6E2FED01E097BA00083EBEC /* MWMSearchFilterViewController.mm in Sources */, @@ -5786,6 +5888,7 @@ 34763F071F3092E700F4D2D3 /* String+Format.swift in Sources */, 346DB83A1E5C4F6700E3123E /* GalleryItemModel.swift in Sources */, F6E2FD5C1E097BA00083EBEC /* MWMMapDownloaderCellHeader.mm in Sources */, + 34D7F3421F33903F001D5ED5 /* RouteManagerHeaderView.swift in Sources */, 34D3AFF21E37945B004100F9 /* UITableView+Cells.swift in Sources */, F6150E321EF953A6000B955D /* MWMUGCReviewVM.mm in Sources */, 34D3B0301E389D05004100F9 /* MWMEditorCategoryCell.mm in Sources */, @@ -5814,6 +5917,7 @@ F6FE3C391CC50FFD00A73196 /* MWMPlaceDoesntExistAlert.mm in Sources */, F6E2FDFE1E097BA00083EBEC /* MWMOpeningHoursClosedSpanTableViewCell.mm in Sources */, F6E2FEDC1E097BA00083EBEC /* MWMSearchManager+Filter.mm in Sources */, + 342360A31F34840500AFE44D /* RouteManagerDimView.swift in Sources */, 346DB8341E5C4F6700E3123E /* GalleryViewController.swift in Sources */, 34943BB71E26222300B14F84 /* WelcomeProtocol.swift in Sources */, F6E2FD5F1E097BA00083EBEC /* MWMMapDownloaderLargeCountryTableViewCell.mm in Sources */, @@ -5835,6 +5939,7 @@ F6E2FD8C1E097BA00083EBEC /* MWMNoMapsView.mm in Sources */, 34D3B0361E389D05004100F9 /* MWMEditorSelectTableViewCell.mm in Sources */, F6E2FD711E097BA00083EBEC /* MWMMapDownloaderTableViewCell.mm in Sources */, + 342360A81F34906700AFE44D /* RouteManagerCell.swift in Sources */, F6E2FE4F1E097BA00083EBEC /* MWMActionBarButton.mm in Sources */, 340475531E081A4600C92850 /* MWMCustomFacebookEvents.mm in Sources */, 349D1CE41E3F836900A878FD /* UIViewController+Hierarchy.swift in Sources */, @@ -5890,6 +5995,7 @@ F6664C021E6459DA00E703C2 /* PPReviewHeaderCell.swift in Sources */, F6E2FE7C1E097BA00083EBEC /* MWMPlacePageOpeningHoursCell.mm in Sources */, 340E1EFB1E2F614400CE49BF /* Storyboard.swift in Sources */, + 34C5B8141F335BCA005E50B6 /* RouteManagerViewModel.swift in Sources */, 34E776331F15FAC2003040B3 /* MWMPlacePageManagerHelper.mm in Sources */, F6E2FF361E097BA00083EBEC /* MWMSearchSuggestionCell.mm in Sources */, F6E2FE3A1E097BA00083EBEC /* MWMMigrationView.mm in Sources */, @@ -5926,6 +6032,7 @@ F6E2FE041E097BA00083EBEC /* MWMOpeningHoursDaysSelectorTableViewCell.mm in Sources */, F6E2FE671E097BA00083EBEC /* MWMPlacePageButtonCell.mm in Sources */, F6E2FE131E097BA00083EBEC /* MWMOpeningHoursTimeSelectorTableViewCell.mm in Sources */, + 34C5B8101F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift in Sources */, F626D52F1C3E83F800C17D15 /* MWMTableViewCell.mm in Sources */, 3486B5191E27AD3B0069C126 /* MWMFrameworkListener.mm in Sources */, 3404756B1E081A4600C92850 /* MWMSearch+CoreSpotlight.mm in Sources */, @@ -5941,12 +6048,14 @@ F6E2FED91E097BA00083EBEC /* MWMSearchContentView.mm in Sources */, F6E2FD891E097BA00083EBEC /* MWMMapDownloaderViewController.mm in Sources */, F6BD1D211CA412920047B8E8 /* MWMOsmAuthAlert.mm in Sources */, + 34C5B8241F336DF5005E50B6 /* RouteManagerTransitioning.swift in Sources */, 347040301EA6470700038379 /* BorderedButton.swift in Sources */, 3407087C1F2B6F5200029ECC /* NavigationControlView.swift in Sources */, F6E2FF4B1E097BA00083EBEC /* SettingsTableViewSwitchCell.swift in Sources */, F6E2FE791E097BA00083EBEC /* MWMOpeningHoursLayoutHelper.mm in Sources */, F6B97B271CD0CA990009B612 /* MWMBookmarkNameCell.mm in Sources */, 34ABA6211C2D517500FE1BEC /* MWMInputValidator.mm in Sources */, + 349993FB1F388F970064CFBE /* RouteManageriPadPresentationController.swift in Sources */, F6E2FD7D1E097BA00083EBEC /* MWMMapDownloaderExtendedDataSource.mm in Sources */, F6E2FED31E097BA00083EBEC /* MWMSearchHotelsFilterViewController.mm in Sources */, 340475741E081A4600C92850 /* MWMStorage.mm in Sources */, @@ -5980,6 +6089,7 @@ 3404165C1E7C29AE00E2B6D6 /* PhotosInteractionAnimator.swift in Sources */, 34D4FA631E26572D003F53EF /* FirstLaunchController.swift in Sources */, 3404756E1E081A4600C92850 /* MWMSearch.mm in Sources */, + 3423609F1F34787F00AFE44D /* RouteManagerTableView.swift in Sources */, 6741AA191BF340DE002C974C /* MWMDownloaderDialogCell.mm in Sources */, F6E2FEFD1E097BA00083EBEC /* MWMSearchCategoryCell.mm in Sources */, 3486B5081E27A4B50069C126 /* LocalNotificationManager.mm in Sources */, @@ -6038,9 +6148,11 @@ buildActionMask = 2147483647; files = ( 34845DB81E166084003D55B9 /* Common.swift in Sources */, + 349993FF1F388F970064CFBE /* RouteManageriPhonePresentationController.swift in Sources */, 849CF6821DE842290024A8A5 /* main.mm in Sources */, 34D3B0501E38A20C004100F9 /* Bundle+Init.swift in Sources */, 3454D7D51E07F045004AF2AD /* UIImageView+Coloring.mm in Sources */, + 342360951F3456E200AFE44D /* RouteManagerViewController.swift in Sources */, F6E2FF551E097BA00083EBEC /* MWMHelpController.mm in Sources */, 340708591F28F1F000029ECC /* MWMTaxiCollectionLayout.mm in Sources */, F6E2FF5B1E097BA00083EBEC /* MWMNightModeController.mm in Sources */, @@ -6067,6 +6179,7 @@ F6E2FDED1E097BA00083EBEC /* MWMOpeningHoursAddClosedTableViewCell.mm in Sources */, F6150E531EFA7352000B955D /* MWUGCCommentsController.mm in Sources */, F6E2FE111E097BA00083EBEC /* MWMOpeningHoursTableViewCell.mm in Sources */, + 3423609C1F34585A00AFE44D /* RouteManagerFooterView.swift in Sources */, 3404755A1E081A4600C92850 /* WebViewController.mm in Sources */, 34F742331E0834F400AC1FD6 /* UIViewController+Navigation.mm in Sources */, 849CF6911DE842290024A8A5 /* MWMSideButtons.mm in Sources */, @@ -6074,6 +6187,7 @@ 34F407301E9E1AFF00E57AC0 /* BannersCache.swift in Sources */, 34D3B0221E389D05004100F9 /* MWMEditorAddAdditionalNameTableViewCell.mm in Sources */, 3486B51F1E27AD590069C126 /* MWMFrameworkHelper.mm in Sources */, + 34C5B81D1F3367E1005E50B6 /* RouteManagerTransitioningManager.swift in Sources */, F6E2FE4A1E097BA00083EBEC /* MWMPlacePageData.mm in Sources */, 849CF6981DE842290024A8A5 /* MWMAPIBarView.mm in Sources */, 34F4073F1E9E1AFF00E57AC0 /* MPNativeAd+MWM.mm in Sources */, @@ -6111,6 +6225,7 @@ 34763F081F3092E700F4D2D3 /* String+Format.swift in Sources */, 849CF6B11DE842290024A8A5 /* MWMMapWidgets.mm in Sources */, F6E2FE4D1E097BA00083EBEC /* MWMPlacePageManager.mm in Sources */, + 34D7F3431F33903F001D5ED5 /* RouteManagerHeaderView.swift in Sources */, 346DB83B1E5C4F6700E3123E /* GalleryItemModel.swift in Sources */, 340475631E081A4600C92850 /* MWMNetworkPolicy.mm in Sources */, 34D3AFF31E37945B004100F9 /* UITableView+Cells.swift in Sources */, @@ -6139,6 +6254,7 @@ 346DB8291E5C4F6700E3123E /* GalleryCell.swift in Sources */, 340475781E081A4600C92850 /* MWMTrafficManager.mm in Sources */, F6E2FECE1E097BA00083EBEC /* MWMSearchFilterTransitioningManager.mm in Sources */, + 342360A41F34840500AFE44D /* RouteManagerDimView.swift in Sources */, F6E2FF131E097BA00083EBEC /* MWMSearchHistoryRequestCell.mm in Sources */, 849CF6D21DE842290024A8A5 /* MWMNavigationController.mm in Sources */, 346DB8351E5C4F6700E3123E /* GalleryViewController.swift in Sources */, @@ -6160,6 +6276,7 @@ 34F407361E9E1AFF00E57AC0 /* CoreBanner.swift in Sources */, 849CF6D31DE842290024A8A5 /* MWMMapDownloadDialog.mm in Sources */, F6E2FE261E097BA00083EBEC /* MWMOpeningHoursModel.mm in Sources */, + 342360A91F34906700AFE44D /* RouteManagerCell.swift in Sources */, 34D3B0371E389D05004100F9 /* MWMEditorSelectTableViewCell.mm in Sources */, 849CF6D51DE842290024A8A5 /* MWMTableViewController.mm in Sources */, F6E2FD8D1E097BA00083EBEC /* MWMNoMapsView.mm in Sources */, @@ -6215,6 +6332,7 @@ F6664C031E6459DA00E703C2 /* PPReviewHeaderCell.swift in Sources */, 849CF6F61DE842290024A8A5 /* MWMNavigationDashboardEntity.mm in Sources */, 340E1EFC1E2F614400CE49BF /* Storyboard.swift in Sources */, + 34C5B8151F335BCA005E50B6 /* RouteManagerViewModel.swift in Sources */, F6E2FE7D1E097BA00083EBEC /* MWMPlacePageOpeningHoursCell.mm in Sources */, 34E776341F15FAC2003040B3 /* MWMPlacePageManagerHelper.mm in Sources */, F6E2FF371E097BA00083EBEC /* MWMSearchSuggestionCell.mm in Sources */, @@ -6251,6 +6369,7 @@ F6E2FE051E097BA00083EBEC /* MWMOpeningHoursDaysSelectorTableViewCell.mm in Sources */, F6E2FE681E097BA00083EBEC /* MWMPlacePageButtonCell.mm in Sources */, F6E2FE141E097BA00083EBEC /* MWMOpeningHoursTimeSelectorTableViewCell.mm in Sources */, + 34C5B8111F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift in Sources */, 849CF7151DE842290024A8A5 /* MWMInputEmailValidator.mm in Sources */, 3486B51A1E27AD3B0069C126 /* MWMFrameworkListener.mm in Sources */, 845E4B1D1DEC83AE00D6BED8 /* MWMMobileInternetAlert.mm in Sources */, @@ -6266,12 +6385,14 @@ 3454D7C91E07F045004AF2AD /* UIButton+RuntimeAttributes.mm in Sources */, F6E2FEDA1E097BA00083EBEC /* MWMSearchContentView.mm in Sources */, F6E2FD8A1E097BA00083EBEC /* MWMMapDownloaderViewController.mm in Sources */, + 34C5B8251F336DF5005E50B6 /* RouteManagerTransitioning.swift in Sources */, F6E2FF4C1E097BA00083EBEC /* SettingsTableViewSwitchCell.swift in Sources */, 3407087D1F2B6F5200029ECC /* NavigationControlView.swift in Sources */, 347040311EA6470700038379 /* BorderedButton.swift in Sources */, F6E2FE7A1E097BA00083EBEC /* MWMOpeningHoursLayoutHelper.mm in Sources */, 849CF7251DE842290024A8A5 /* MWMMapViewControlsManager.mm in Sources */, 849CF7281DE842290024A8A5 /* MWMOsmAuthAlert.mm in Sources */, + 349993FC1F388F970064CFBE /* RouteManageriPadPresentationController.swift in Sources */, F6E2FD7E1E097BA00083EBEC /* MWMMapDownloaderExtendedDataSource.mm in Sources */, F6E2FED41E097BA00083EBEC /* MWMSearchHotelsFilterViewController.mm in Sources */, 849CF72B1DE842290024A8A5 /* MWMBookmarkNameCell.mm in Sources */, @@ -6305,6 +6426,7 @@ 3404165D1E7C29AE00E2B6D6 /* PhotosInteractionAnimator.swift in Sources */, 340475571E081A4600C92850 /* Statistics.mm in Sources */, 3486B5091E27A4B50069C126 /* LocalNotificationManager.mm in Sources */, + 342360A01F34787F00AFE44D /* RouteManagerTableView.swift in Sources */, F6E2FEFE1E097BA00083EBEC /* MWMSearchCategoryCell.mm in Sources */, 3404754B1E081A4600C92850 /* AppInfo.mm in Sources */, 849CF73C1DE842290024A8A5 /* MWMMultilineLabel.mm in Sources */,