Merge commit '05cc660641' into traffic

# Conflicts:
#	CMakeLists.txt
#	android/app/src/main/java/app/organicmaps/settings/SettingsPrefsFragment.java
#	android/sdk/src/main/cpp/app/organicmaps/sdk/Framework.hpp
#	android/sdk/src/main/cpp/app/organicmaps/sdk/OrganicMaps.cpp
#	android/sdk/src/main/cpp/app/organicmaps/sdk/util/Config.cpp
#	libs/indexer/data_source.hpp
#	libs/indexer/feature.hpp
#	libs/indexer/ftypes_matcher.hpp
#	libs/map/framework.cpp
#	libs/map/traffic_manager.cpp
#	libs/routing/absent_regions_finder.cpp
#	libs/routing/edge_estimator.hpp
#	libs/routing/index_router.cpp
#	libs/routing/index_router.hpp
#	libs/routing/routing_session.hpp
#	libs/routing_common/num_mwm_id.hpp
#	libs/traffic/traffic_info.cpp
#	qt/mainwindow.hpp
#	qt/preferences_dialog.cpp
#	tools/openlr/helpers.hpp
#	tools/openlr/openlr_decoder.cpp
#	tools/openlr/openlr_decoder.hpp
#	tools/openlr/openlr_stat/openlr_stat.cpp
#	tools/openlr/router.hpp
#	tools/openlr/score_candidate_paths_getter.cpp
#	tools/openlr/score_candidate_paths_getter.hpp
#	xcode/CoMaps.xcworkspace/contents.xcworkspacedata
This commit is contained in:
mvglasow
2025-09-10 21:22:40 +03:00
4644 changed files with 82377 additions and 85029 deletions

View File

@@ -159,14 +159,16 @@ final class CarPlayMapViewController: MWMViewController {
}
func updateVisibleViewPortState(_ state: CPViewPortState) {
viewPortState = state
switch viewPortState {
case .default:
updateVisibleViewPortToDefaultState()
case .preview:
updateVisibleViewPortToPreviewState()
case .navigation:
updateVisibleViewPortToNavigationState()
if CarPlayService.shared.isCarplayActivated {
viewPortState = state
switch viewPortState {
case .default:
updateVisibleViewPortToDefaultState()
case .preview:
updateVisibleViewPortToPreviewState()
case .navigation:
updateVisibleViewPortToNavigationState()
}
}
}

View File

@@ -21,7 +21,7 @@ final class ColorPicker: NSObject {
switch pickerType {
case .defaultColorPicker(let color):
if #available(iOS 14.0, *), !ProcessInfo.processInfo.isiOSAppOnMac {
if !ProcessInfo.processInfo.isiOSAppOnMac {
colorPickerViewController = defaultColorPickerViewController(with: color)
} else {
colorPickerViewController = bookmarksColorPickerViewController(with: BookmarkColor.bookmarkColor(from: color) ?? .none)

View File

@@ -9,11 +9,7 @@ final class DocumentPicker: NSObject {
completionHandler: @escaping URLsCompletionHandler) {
self.completionHandler = completionHandler
let documentPickerViewController: UIDocumentPickerViewController
if #available(iOS 14.0, *) {
documentPickerViewController = UIDocumentPickerViewController(forOpeningContentTypes: fileTypes.map(\.utType), asCopy: true)
} else {
documentPickerViewController = UIDocumentPickerViewController(documentTypes: fileTypes.map(\.typeIdentifier), in: .import)
}
documentPickerViewController = UIDocumentPickerViewController(forOpeningContentTypes: fileTypes.map(\.utType), asCopy: true)
documentPickerViewController.delegate = self
// TODO: Enable multiple selection when the multiple files parsing support will be added to the bookmark_manager.
documentPickerViewController.allowsMultipleSelection = false

View File

@@ -222,6 +222,31 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
return;
}
// Validation to make sure address features have a house number
if (!m_mapObject.CheckHouseNumberWhenIsAddress())
{
// Find indexPath for the house number cell and mark it as invalid
auto const sectionIt = std::find(m_sections.begin(), m_sections.end(), MWMEditorSectionAddress);
if (sectionIt != m_sections.end())
{
NSInteger const section = std::distance(m_sections.begin(), sectionIt);
auto const & cells = m_cells[MWMEditorSectionAddress];
auto const it = std::find(cells.begin(), cells.end(), MWMEditorCellTypeBuilding);
if (it != cells.end())
{
NSInteger const row = std::distance(cells.begin(), it);
NSIndexPath * indexPath = [NSIndexPath indexPathForRow:row inSection:section];
[self markCellAsInvalid:indexPath];
// Focus the text field to draw the user's attention.
MWMEditorTextTableViewCell * cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell.textField becomeFirstResponder];
}
}
// Stop the save process
return;
}
if ([self showPersonalInfoWarningAlertIfNeeded])
return;

View File

@@ -26,8 +26,8 @@ fileprivate struct DescriptionsViewModel {
final class ElevationProfilePresenter: NSObject {
private weak var view: ElevationProfileViewProtocol?
private var trackData: PlacePageTrackData
private let delegate: ElevationProfileViewControllerDelegate?
private weak var trackData: PlacePageTrackData?
private weak var delegate: ElevationProfileViewControllerDelegate?
private let bookmarkManager: BookmarksManager = .shared()
private let cellSpacing: CGFloat = 8
@@ -72,20 +72,21 @@ extension ElevationProfilePresenter: ElevationProfilePresenterProtocol {
}
func updateActivePointDistance(_ distance: Double) {
guard let view, !view.isChartViewInfoHidden else { return }
guard let view, view.canReceiveUpdates else { return }
view.setActivePointDistance(distance)
}
func updateMyPositionDistance(_ distance: Double) {
guard let view, !view.isChartViewInfoHidden else { return }
guard let view, view.canReceiveUpdates else { return }
view.setMyPositionDistance(distance)
}
func configure() {
view?.isChartViewHidden = false
let kMinPointsToDraw = 3
guard let profileData = trackData.elevationProfileData,
let kMinPointsToDraw = 2
guard let trackData = trackData,
let profileData = trackData.elevationProfileData,
let chartData,
chartData.points.count >= kMinPointsToDraw else {
view?.userInteractionEnabled = false
@@ -94,13 +95,13 @@ extension ElevationProfilePresenter: ElevationProfilePresenterProtocol {
view?.setChartData(ChartPresentationData(chartData, formatter: formatter))
view?.reloadDescription()
view?.userInteractionEnabled = true
guard !profileData.isTrackRecording else {
view?.isChartViewInfoHidden = true
return
}
view?.userInteractionEnabled = true
view?.setActivePointDistance(trackData.activePointDistance)
view?.setMyPositionDistance(trackData.myPositionDistance)
}

View File

@@ -6,6 +6,7 @@ protocol ElevationProfileViewProtocol: AnyObject {
var userInteractionEnabled: Bool { get set }
var isChartViewHidden: Bool { get set }
var isChartViewInfoHidden: Bool { get set }
var canReceiveUpdates: Bool { get }
func setChartData(_ data: ChartPresentationData)
func setActivePointDistance(_ distance: Double)
@@ -139,6 +140,10 @@ extension ElevationProfileViewController: ElevationProfileViewProtocol {
set { chartView.isChartViewInfoHidden = newValue }
}
var canReceiveUpdates: Bool {
chartView.chartData != nil
}
func setChartData(_ data: ChartPresentationData) {
chartView.chartData = data
}

View File

@@ -43,6 +43,9 @@ class OpeningHoursDayViewController: UIViewController {
class OpeningHoursViewController: UIViewController {
@IBOutlet var stackView: UIStackView!
@IBOutlet var checkDateLabel: UILabel!
@IBOutlet var checkDateLabelTopLayoutConstraint: NSLayoutConstraint!
@IBOutlet var checkDateLabelBottomLayoutConstraint: NSLayoutConstraint!
private var otherDaysViews: [OpeningHoursDayViewController] = []
@@ -56,6 +59,7 @@ class OpeningHoursViewController: UIViewController {
private var expanded = false
var openingHours: OpeningHours!
var openingHoursCheckDate: Date?
override func viewDidLoad() {
super.viewDidLoad()
@@ -79,6 +83,23 @@ class OpeningHoursViewController: UIViewController {
self.otherDaysViews.forEach { vc in
vc.view.isHidden = !self.expanded
}
if let checkDate = self.openingHoursCheckDate, self.expanded {
let checkDateFormatter = RelativeDateTimeFormatter()
checkDateFormatter.unitsStyle = .spellOut
checkDateFormatter.localizedString(for: checkDate, relativeTo: Date.now)
self.checkDateLabel.text = String(format: L("hours_confirmed_time_ago"), checkDateFormatter.localizedString(for: checkDate, relativeTo: Date.now))
NSLayoutConstraint.activate([self.checkDateLabelTopLayoutConstraint])
NSLayoutConstraint.activate([self.checkDateLabelBottomLayoutConstraint])
} else {
self.checkDateLabel.text = String()
NSLayoutConstraint.deactivate([self.checkDateLabelTopLayoutConstraint])
NSLayoutConstraint.deactivate([self.checkDateLabelBottomLayoutConstraint])
}
self.checkDateLabel.isHidden = !self.expanded
self.todayView.arrowImageView.transform = self.expanded ? CGAffineTransform(rotationAngle: -CGFloat.pi + 0.01)
: CGAffineTransform.identity
self.view.layoutIfNeeded()

View File

@@ -39,7 +39,7 @@ final class PlacePageEditBookmarkOrTrackViewController: UIViewController {
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if #available(iOS 13.0, *), traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
applyTheme()
}
}

View File

@@ -17,7 +17,7 @@ final class CircleImageButton: UIButton {
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if #available(iOS 13.0, *), traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
circleImageView.applyTheme()
}
}

View File

@@ -111,38 +111,21 @@ extension PlacePageHeaderViewController: PlacePageHeaderViewProtocol {
}
func showShareTrackMenu() {
if #available(iOS 14.0, *) {
// The menu will be shown by the shareButton itself
} else {
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let kmlAction = UIAlertAction(title: L("export_file"), style: .default) { [weak self] _ in
guard let self else { return }
self.presenter?.onExportTrackButtonPress(.text, from: self.shareButton)
}
let gpxAction = UIAlertAction(title: L("export_file_gpx"), style: .default) { [weak self] _ in
guard let self else { return }
self.presenter?.onExportTrackButtonPress(.gpx, from: self.shareButton)
}
alert.addAction(kmlAction)
alert.addAction(gpxAction)
present(alert, animated: true, completion: nil)
}
}
private func configureTrackSharingMenu() {
if #available(iOS 14.0, *) {
let menu = UIMenu(title: "", image: nil, children: [
UIAction(title: L("export_file"), image: nil, handler: { [weak self] _ in
guard let self else { return }
self.presenter?.onExportTrackButtonPress(.text, from: self.shareButton)
}),
UIAction(title: L("export_file_gpx"), image: nil, handler: { [weak self] _ in
guard let self else { return }
self.presenter?.onExportTrackButtonPress(.gpx, from: self.shareButton)
}),
])
shareButton.menu = menu
shareButton.showsMenuAsPrimaryAction = true
}
let menu = UIMenu(title: "", image: nil, children: [
UIAction(title: L("export_file"), image: nil, handler: { [weak self] _ in
guard let self else { return }
self.presenter?.onExportTrackButtonPress(.text, from: self.shareButton)
}),
UIAction(title: L("export_file_gpx"), image: nil, handler: { [weak self] _ in
guard let self else { return }
self.presenter?.onExportTrackButtonPress(.gpx, from: self.shareButton)
}),
])
shareButton.menu = menu
shareButton.showsMenuAsPrimaryAction = true
}
}

View File

@@ -159,6 +159,8 @@ class PlacePageInfoViewController: UIViewController {
private typealias Style = InfoItemView.Style
@IBOutlet var stackView: UIStackView!
@IBOutlet var checkDateLabel: UILabel!
@IBOutlet var checkDateLabelLayoutConstraint: NSLayoutConstraint!
private lazy var openingHoursViewController: OpeningHoursViewController = {
storyboard!.instantiateViewController(ofType: OpeningHoursViewController.self)
@@ -207,13 +209,8 @@ class PlacePageInfoViewController: UIViewController {
stackView.alignment = .fill
stackView.spacing = 0
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.addSeparator(.bottom)
view.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
stackView.topAnchor.constraint(equalTo: view.topAnchor),
stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
setupViews()
}
@@ -221,6 +218,7 @@ class PlacePageInfoViewController: UIViewController {
private func setupViews() {
if let openingHours = placePageInfoData.openingHours {
openingHoursViewController.openingHours = openingHours
openingHoursViewController.openingHoursCheckDate = placePageInfoData.checkDateOpeningHours
addChild(openingHoursViewController)
addToStack(openingHoursViewController.view)
openingHoursViewController.didMove(toParent: self)
@@ -313,7 +311,7 @@ class PlacePageInfoViewController: UIViewController {
}
if let atm = placePageInfoData.atm {
atmView = createInfoItem(NSLocalizedString(atm, tableName: "LocalizableTypes", bundle: Bundle.main, comment: String()), icon: UIImage(named: "ic_placepage_atm"))
atmView = createInfoItem(atm, icon: UIImage(named: "ic_placepage_atm"))
}
if let level = placePageInfoData.level {
@@ -436,7 +434,7 @@ class PlacePageInfoViewController: UIViewController {
})
}
if let panoramax = placePageInfoData.panoramax {
if let panoramax = placePageInfoData.panoramax {
panoramaxView = createInfoItem(L("panoramax_picture"),
icon: UIImage(named: "ic_placepage_panoramax"),
style: .link,
@@ -458,6 +456,19 @@ class PlacePageInfoViewController: UIViewController {
setupCoordinatesView()
setupOpenWithAppView()
if let checkDate = placePageInfoData.checkDate {
let checkDateFormatter = RelativeDateTimeFormatter()
checkDateFormatter.unitsStyle = .spellOut
checkDateFormatter.localizedString(for: checkDate, relativeTo: Date.now)
self.checkDateLabel.text = String(format: L("existence_confirmed_time_ago"), checkDateFormatter.localizedString(for: checkDate, relativeTo: Date.now))
checkDateLabel.isHidden = false
NSLayoutConstraint.activate([checkDateLabelLayoutConstraint])
} else {
checkDateLabel.text = String()
checkDateLabel.isHidden = true
NSLayoutConstraint.deactivate([checkDateLabelLayoutConstraint])
}
}
private func setupCoordinatesView() {
@@ -477,16 +488,15 @@ class PlacePageInfoViewController: UIViewController {
longPressHandler: { [weak self] in
self?.copyCoordinatesToPasteboard()
})
if #available(iOS 14.0, *) {
let menu = UIMenu(children: coordFormats.enumerated().map { (index, format) in
UIAction(title: format, handler: { [weak self] _ in
self?.setCoordinatesSelected(formatId: index)
self?.copyCoordinatesToPasteboard()
})
let menu = UIMenu(children: coordFormats.enumerated().map { (index, format) in
UIAction(title: format, handler: { [weak self] _ in
self?.setCoordinatesSelected(formatId: index)
self?.copyCoordinatesToPasteboard()
})
coordinatesView?.accessoryButton.menu = menu
coordinatesView?.accessoryButton.showsMenuAsPrimaryAction = true
}
})
coordinatesView?.accessoryButton.menu = menu
coordinatesView?.accessoryButton.showsMenuAsPrimaryAction = true
}
private func setCoordinatesSelected(formatId: Int) {

View File

@@ -199,8 +199,17 @@ final class PlacePagePreviewViewController: UIViewController {
let stringTimeInterval = getTimeIntervalString(minutes: minutesUntilOpen)
let stringTime = stringFromTime(nextTimeOpen)
var state: String = L("closed_now")
var stateColor = UIColor.BaseColors.red
let details: String?
if (minutesUntilOpen < 3 * 60) // Less than 3 hours
if (minutesUntilOpen < 15) { // Less than 15 min
state = String(format: L("opens_in"), stringTimeInterval)
stateColor = UIColor.BaseColors.yellow
details = stringTime
}
else if (minutesUntilOpen < 3 * 60) // Less than 3 hours
{
details = String(format: L("opens_in"), stringTimeInterval) + "" + stringTime
}
@@ -222,8 +231,8 @@ final class PlacePagePreviewViewController: UIViewController {
details = nil
}
setScheduleLabel(state: L("closed_now"),
stateColor: UIColor.BaseColors.red,
setScheduleLabel(state: state,
stateColor: stateColor,
details: details)
@unknown default:
@@ -254,6 +263,7 @@ final class PlacePagePreviewViewController: UIViewController {
NSAttributedString.Key.foregroundColor: UIColor.blackSecondaryText()])
attributedString.append(detailsString)
}
scheduleLabel.attributedText = attributedString
}
}

View File

@@ -4,6 +4,7 @@
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="Stack View standard spacing" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
@@ -391,16 +392,39 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="pmL-HT-I1N">
<rect key="frame" x="0.0" y="0.0" width="375" height="100"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="96"/>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="NMf-TU-1P1">
<rect key="frame" x="0.0" y="96" width="375" height="4"/>
<subviews>
<label userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WIw-cD-4aR">
<rect key="frame" x="18" y="4" width="339" height="0.0"/>
<color key="backgroundColor" name="Press Background Color"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" name="Press Background Color"/>
<constraints>
<constraint firstItem="WIw-cD-4aR" firstAttribute="leading" secondItem="NMf-TU-1P1" secondAttribute="leading" constant="18" id="1c4-qC-r5Q"/>
<constraint firstItem="WIw-cD-4aR" firstAttribute="top" secondItem="NMf-TU-1P1" secondAttribute="top" constant="4" id="4a9-bg-siG"/>
<constraint firstItem="WIw-cD-4aR" firstAttribute="top" secondItem="NMf-TU-1P1" secondAttribute="top" priority="750" id="btT-aI-fBS"/>
<constraint firstAttribute="trailing" secondItem="WIw-cD-4aR" secondAttribute="trailing" constant="18" id="hLS-Zu-Egy"/>
<constraint firstAttribute="bottom" secondItem="WIw-cD-4aR" secondAttribute="bottom" id="myR-Jq-0zU"/>
</constraints>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="g60-e9-U8G"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="pmL-HT-I1N" secondAttribute="bottom" id="0Xe-Gp-10C"/>
<constraint firstItem="NMf-TU-1P1" firstAttribute="top" secondItem="pmL-HT-I1N" secondAttribute="bottom" id="7CD-wN-QBE"/>
<constraint firstItem="g60-e9-U8G" firstAttribute="trailing" secondItem="NMf-TU-1P1" secondAttribute="trailing" id="HLm-Xn-oJO"/>
<constraint firstItem="NMf-TU-1P1" firstAttribute="leading" secondItem="g60-e9-U8G" secondAttribute="leading" id="R7d-jc-rKk"/>
<constraint firstAttribute="top" secondItem="pmL-HT-I1N" secondAttribute="top" id="THV-MF-4pC"/>
<constraint firstItem="pmL-HT-I1N" firstAttribute="leading" secondItem="uyH-Qn-86F" secondAttribute="leading" id="VNA-7u-TMS"/>
<constraint firstAttribute="trailing" secondItem="pmL-HT-I1N" secondAttribute="trailing" id="sUb-Fg-UED"/>
<constraint firstAttribute="bottom" secondItem="NMf-TU-1P1" secondAttribute="bottom" id="tde-KC-gmp"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="Background"/>
@@ -409,6 +433,8 @@
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<size key="freeformSize" width="375" height="100"/>
<connections>
<outlet property="checkDateLabel" destination="WIw-cD-4aR" id="pKw-Wb-XVW"/>
<outlet property="checkDateLabelLayoutConstraint" destination="4a9-bg-siG" id="wIH-MS-2Ic"/>
<outlet property="stackView" destination="pmL-HT-I1N" id="33x-d6-3Lw"/>
</connections>
</viewController>
@@ -526,18 +552,38 @@
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="mrt-5g-RRn">
<rect key="frame" x="0.0" y="0.0" width="375" height="100"/>
</stackView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lv7-Ig-hWB">
<rect key="frame" x="56" y="100" width="303" height="0.0"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<viewLayoutGuide key="safeArea" id="lM2-J8-T6c"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="mrt-5g-RRn" secondAttribute="bottom" id="5wi-9V-R6Z"/>
<constraint firstItem="lv7-Ig-hWB" firstAttribute="top" secondItem="mrt-5g-RRn" secondAttribute="bottom" constant="12" id="5wi-9V-R6Z"/>
<constraint firstAttribute="trailing" secondItem="lv7-Ig-hWB" secondAttribute="trailing" constant="16" id="Kit-DZ-e0h"/>
<constraint firstItem="mrt-5g-RRn" firstAttribute="leading" secondItem="QE6-Lg-X0g" secondAttribute="leading" id="NO1-zN-EiJ"/>
<constraint firstItem="lv7-Ig-hWB" firstAttribute="top" secondItem="mrt-5g-RRn" secondAttribute="bottom" priority="750" id="hGX-Xp-WTY"/>
<constraint firstAttribute="bottom" secondItem="lv7-Ig-hWB" secondAttribute="bottom" constant="12" id="iva-mv-Z6T"/>
<constraint firstAttribute="top" secondItem="mrt-5g-RRn" secondAttribute="top" id="oq2-uJ-EhG"/>
<constraint firstAttribute="bottom" secondItem="lv7-Ig-hWB" secondAttribute="bottom" priority="750" id="vV4-fA-p7B"/>
<constraint firstAttribute="trailing" secondItem="mrt-5g-RRn" secondAttribute="trailing" id="wG7-Td-jWS"/>
<constraint firstItem="lv7-Ig-hWB" firstAttribute="leading" secondItem="QE6-Lg-X0g" secondAttribute="leading" constant="56" id="wr7-Os-puB"/>
</constraints>
<variation key="default">
<mask key="constraints">
<exclude reference="iva-mv-Z6T"/>
<exclude reference="5wi-9V-R6Z"/>
</mask>
</variation>
</view>
<size key="freeformSize" width="375" height="100"/>
<connections>
<outlet property="checkDateLabel" destination="lv7-Ig-hWB" id="d36-WZ-S1Y"/>
<outlet property="checkDateLabelBottomLayoutConstraint" destination="iva-mv-Z6T" id="zmV-xd-yXQ"/>
<outlet property="checkDateLabelTopLayoutConstraint" destination="5wi-9V-R6Z" id="EG8-a3-s5L"/>
<outlet property="stackView" destination="mrt-5g-RRn" id="0xW-H9-lLi"/>
</connections>
</viewController>
@@ -1243,7 +1289,7 @@
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="lIJ-bh-coX" firstAttribute="leading" secondItem="Bn7-Ag-wuu" secondAttribute="leading" constant="56" id="WXv-gZ-ygJ"/>
<constraint firstAttribute="bottom" secondItem="lIJ-bh-coX" secondAttribute="bottom" constant="12" id="Wcq-WA-Qd8"/>
<constraint firstAttribute="bottom" secondItem="lIJ-bh-coX" secondAttribute="bottom" constant="12" id="g7V-FG-sWe"/>
<constraint firstAttribute="trailing" secondItem="lIJ-bh-coX" secondAttribute="trailing" constant="16" id="hw3-UC-uCp"/>
<constraint firstItem="lIJ-bh-coX" firstAttribute="top" secondItem="Bn7-Ag-wuu" secondAttribute="top" constant="12" id="tpq-hf-4gG"/>
</constraints>
@@ -1270,7 +1316,7 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="72"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="spW-XI-KSY" customClass="PlacePageHeaderView" customModule="CoMaps" customModuleProvider="target">
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="spW-XI-KSY">
<rect key="frame" x="0.0" y="62" width="375" height="10"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
@@ -1280,7 +1326,7 @@
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="PPNavigationShadowView"/>
</userDefinedRuntimeAttributes>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fqh-H3-eji" customClass="PlacePageHeaderView" customModule="CoMaps" customModuleProvider="target">
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fqh-H3-eji">
<rect key="frame" x="0.0" y="20" width="375" height="52"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Gdy-g5-gbM">
@@ -1404,6 +1450,12 @@
<image name="dialog_btn_press" width="280" height="44"/>
<image name="ic_arrow_gray_down" width="28" height="28"/>
<image name="ic_placepage_open_hours" width="28" height="28"/>
<namedColor name="Press Background Color">
<color red="0.96078431372549022" green="0.96078431372549022" blue="0.96078431372549022" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
<systemColor name="secondaryLabelColor">
<color red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="separatorColor">
<color red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.28999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>

View File

@@ -1,5 +1,6 @@
protocol PlacePageInteractorProtocol: AnyObject {
func viewWillAppear()
func viewWillDisappear()
func updateTopBound(_ bound: CGFloat, duration: TimeInterval)
}
@@ -19,12 +20,11 @@ class PlacePageInteractor: NSObject {
self.mapViewController = mapViewController
super.init()
addToBookmarksManagerObserverList()
subscribeOnTrackActivePointUpdates()
subscribeOnTrackActivePointUpdatesIfNeeded()
}
deinit {
removeFromBookmarksManagerObserverList()
unsubscribeFromTrackActivePointUpdates()
}
private func updatePlacePageIfNeeded() {
@@ -53,7 +53,8 @@ class PlacePageInteractor: NSObject {
}
}
private func subscribeOnTrackActivePointUpdates() {
private func subscribeOnTrackActivePointUpdatesIfNeeded() {
unsubscribeFromTrackActivePointUpdates()
guard placePageData.objectType == .track, let trackData = placePageData.trackData else { return }
bookmarksManager.setElevationActivePointChanged(trackData.trackId) { [weak self] distance in
self?.trackActivePointPresenter?.updateActivePointDistance(distance)
@@ -65,7 +66,6 @@ class PlacePageInteractor: NSObject {
}
private func unsubscribeFromTrackActivePointUpdates() {
guard placePageData.trackData?.onActivePointChangedHandler != nil else { return }
bookmarksManager.resetElevationActivePointChanged()
bookmarksManager.resetElevationMyPositionChanged()
}
@@ -89,6 +89,10 @@ extension PlacePageInteractor: PlacePageInteractorProtocol {
updatePlacePageIfNeeded()
}
func viewWillDisappear() {
unsubscribeFromTrackActivePointUpdates()
}
func updateTopBound(_ bound: CGFloat, duration: TimeInterval) {
mapViewController?.setPlacePageTopBound(bound, duration: duration)
}
@@ -215,7 +219,7 @@ extension PlacePageInteractor: PlacePageEditBookmarkOrTrackViewControllerDelegat
case .bookmark(let bookmarkData):
let bookmarkColor = BookmarkColor.bookmarkColor(from: color) ?? bookmarkData.color
MWMPlacePageManagerHelper.updateBookmark(placePageData, color: bookmarkColor, category: category)
case .track(let trackData):
case .track:
MWMPlacePageManagerHelper.updateTrack(placePageData, color: color, category: category)
}
}

View File

@@ -1,81 +1,81 @@
class PlacePageCommonLayout: NSObject, IPlacePageLayout {
private let distanceFormatter = DistanceFormatter.self
private let altitudeFormatter = AltitudeFormatter.self
private var placePageData: PlacePageData
private var interactor: PlacePageInteractor
private let storyboard: UIStoryboard
private var lastLocation: CLLocation?
weak var presenter: PlacePagePresenterProtocol?
fileprivate var lastLocation: CLLocation?
lazy var headerViewControllers: [UIViewController] = {
var headerViewControllers: [UIViewController] {
[headerViewController, previewViewController]
}()
}
lazy var bodyViewControllers: [UIViewController] = {
return configureViewControllers()
configureViewControllers()
}()
var actionBar: ActionBarViewController? {
return actionBarViewController
actionBarViewController
}
var navigationBar: UIViewController? {
return placePageNavigationViewController
placePageNavigationViewController
}
lazy var headerViewController: PlacePageHeaderViewController = {
PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .flexible)
}()
lazy var previewViewController: PlacePagePreviewViewController = {
private lazy var previewViewController: PlacePagePreviewViewController = {
let vc = storyboard.instantiateViewController(ofType: PlacePagePreviewViewController.self)
vc.placePagePreviewData = placePageData.previewData
return vc
} ()
}()
lazy var wikiDescriptionViewController: WikiDescriptionViewController = {
private lazy var wikiDescriptionViewController: WikiDescriptionViewController = {
let vc = storyboard.instantiateViewController(ofType: WikiDescriptionViewController.self)
vc.view.isHidden = true
vc.delegate = interactor
return vc
} ()
}()
lazy var editBookmarkViewController: PlacePageEditBookmarkOrTrackViewController = {
private lazy var editBookmarkViewController: PlacePageEditBookmarkOrTrackViewController = {
let vc = storyboard.instantiateViewController(ofType: PlacePageEditBookmarkOrTrackViewController.self)
vc.view.isHidden = true
vc.delegate = interactor
return vc
} ()
}()
lazy var infoViewController: PlacePageInfoViewController = {
private lazy var infoViewController: PlacePageInfoViewController = {
let vc = storyboard.instantiateViewController(ofType: PlacePageInfoViewController.self)
vc.placePageInfoData = placePageData.infoData
vc.delegate = interactor
return vc
} ()
}()
lazy var buttonsViewController: PlacePageButtonsViewController = {
private lazy var buttonsViewController: PlacePageButtonsViewController = {
let vc = storyboard.instantiateViewController(ofType: PlacePageButtonsViewController.self)
vc.buttonsData = placePageData.buttonsData!
vc.delegate = interactor
return vc
} ()
}()
lazy var actionBarViewController: ActionBarViewController = {
private 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
} ()
}()
lazy var placePageNavigationViewController: PlacePageHeaderViewController = {
private lazy var placePageNavigationViewController: PlacePageHeaderViewController = {
return PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .fixed)
} ()
}()
init(interactor: PlacePageInteractor, storyboard: UIStoryboard, data: PlacePageData) {
self.interactor = interactor
@@ -163,7 +163,6 @@ class PlacePageCommonLayout: NSObject, IPlacePageLayout {
}
}
// MARK: - PlacePageData async callbacks for loaders
extension PlacePageCommonLayout {

View File

@@ -17,25 +17,25 @@ class PlacePageTrackLayout: IPlacePageLayout {
placePageNavigationViewController
}
lazy var headerViewControllers: [UIViewController] = {
var headerViewControllers: [UIViewController] {
[headerViewController, previewViewController]
}()
}
lazy var headerViewController: PlacePageHeaderViewController = {
PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .flexible)
}()
lazy var previewViewController: PlacePagePreviewViewController = {
private lazy var previewViewController: PlacePagePreviewViewController = {
let vc = storyboard.instantiateViewController(ofType: PlacePagePreviewViewController.self)
vc.placePagePreviewData = placePageData.previewData
return vc
}()
lazy var placePageNavigationViewController: PlacePageHeaderViewController = {
private lazy var placePageNavigationViewController: PlacePageHeaderViewController = {
return PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .fixed)
}()
lazy var editTrackViewController: PlacePageEditBookmarkOrTrackViewController = {
private lazy var editTrackViewController: PlacePageEditBookmarkOrTrackViewController = {
let vc = storyboard.instantiateViewController(ofType: PlacePageEditBookmarkOrTrackViewController.self)
vc.view.isHidden = true
vc.delegate = interactor
@@ -49,7 +49,7 @@ class PlacePageTrackLayout: IPlacePageLayout {
return ElevationProfileBuilder.build(trackData: trackData, delegate: interactor)
}()
lazy var actionBarViewController: ActionBarViewController = {
private lazy var actionBarViewController: ActionBarViewController = {
let vc = storyboard.instantiateViewController(ofType: ActionBarViewController.self)
vc.placePageData = placePageData
vc.canAddStop = MWMRouter.canAddIntermediatePoint()

View File

@@ -5,7 +5,7 @@ final class PlacePageTrackRecordingLayout: IPlacePageLayout {
weak var presenter: PlacePagePresenterProtocol?
lazy var bodyViewControllers: [UIViewController] = {
return configureViewControllers()
configureViewControllers()
}()
var actionBar: ActionBarViewController? {
@@ -16,19 +16,19 @@ final class PlacePageTrackRecordingLayout: IPlacePageLayout {
placePageNavigationViewController
}
lazy var headerViewControllers: [UIViewController] = {
var headerViewControllers: [UIViewController] {
[headerViewController]
}()
}
lazy var headerViewController: PlacePageHeaderViewController = {
return PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .flexible)
PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .flexible)
}()
lazy var placePageNavigationViewController: PlacePageHeaderViewController = {
return PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .fixed)
private lazy var placePageNavigationViewController: PlacePageHeaderViewController = {
PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .fixed)
}()
lazy var elevationProfileViewController: ElevationProfileViewController? = {
private lazy var elevationProfileViewController: ElevationProfileViewController? = {
guard let trackData = placePageData.trackData else {
return nil
}
@@ -36,7 +36,7 @@ final class PlacePageTrackRecordingLayout: IPlacePageLayout {
delegate: interactor)
}()
lazy var actionBarViewController: ActionBarViewController = {
private lazy var actionBarViewController: ActionBarViewController = {
let vc = storyboard.instantiateViewController(ofType: ActionBarViewController.self)
vc.placePageData = placePageData
vc.canAddStop = MWMRouter.canAddIntermediatePoint()

View File

@@ -42,6 +42,9 @@ using namespace storage;
[MWMRouter stopRouting];
}
[MWMSearch clear];
[[[MapViewController sharedController] searchManager] close];
if ([MWMMapOverlayManager transitEnabled]) {
[MWMRouter setType:MWMRouterTypePublicTransport];
}
@@ -222,9 +225,11 @@ using namespace storage;
[[MapViewController sharedController].navigationController pushViewController:editBookmarkController animated:YES];
}
- (void)editTrack:(PlacePageData *)data {
if (data.objectType != PlacePageObjectTypeTrack) {
ASSERT_FAIL("editTrack called for non-track object");
- (void)editTrack:(PlacePageData *)data
{
if (data.objectType != PlacePageObjectTypeTrack)
{
LOG(LERROR, ("editTrack called for non-track object"));
return;
}
EditTrackViewController * editTrackController = [[EditTrackViewController alloc] initWithTrackId:data.trackData.trackId editCompletion:^(BOOL edited) {

View File

@@ -1,5 +1,5 @@
protocol PlacePageViewProtocol: AnyObject {
var interactor: PlacePageInteractorProtocol! { get set }
var interactor: PlacePageInteractorProtocol? { get set }
func setLayout(_ layout: IPlacePageLayout)
func closeAnimated(completion: (() -> Void)?)
@@ -35,7 +35,7 @@ final class PlacePageScrollView: UIScrollView {
stackView.distribution = .fill
return stackView
}()
var interactor: PlacePageInteractorProtocol!
var interactor: PlacePageInteractorProtocol?
var beginDragging = false
var rootViewController: MapViewController {
MapViewController.shared()!
@@ -58,13 +58,6 @@ final class PlacePageScrollView: UIScrollView {
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if #available(iOS 13.0, *) {
// See https://github.com/organicmaps/organicmaps/issues/6917 for the details.
} else if previousTraitCollection == nil {
scrollView.contentInset = alternativeSizeClass(iPhone: UIEdgeInsets(top: scrollView.height, left: 0, bottom: 0, right: 0),
iPad: UIEdgeInsets.zero)
updateSteps()
}
panGesture.isEnabled = alternativeSizeClass(iPhone: false, iPad: true)
previousTraitCollection = traitCollection
}
@@ -79,6 +72,11 @@ final class PlacePageScrollView: UIScrollView {
updatePreviewOffset()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
interactor?.viewWillDisappear()
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
// Update layout when the device was rotated but skip when the appearance was changed.
@@ -165,8 +163,7 @@ final class PlacePageScrollView: UIScrollView {
actionBarContainerView.layer.setCornerRadius(.modalSheet, maskedCorners: cornersToMask)
actionBarContainerView.layer.masksToBounds = true
// See https://github.com/organicmaps/organicmaps/issues/6917 for the details.
if #available(iOS 13.0, *), previousTraitCollection == nil {
if previousTraitCollection == nil {
scrollView.contentInset = alternativeSizeClass(iPhone: UIEdgeInsets(top: view.height, left: 0, bottom: 0, right: 0),
iPad: UIEdgeInsets.zero)
scrollView.layoutIfNeeded()
@@ -209,14 +206,21 @@ final class PlacePageScrollView: UIScrollView {
viewController.didMove(toParent: self)
if showSeparator {
viewController.view.addSeparator(.top)
viewController.view.addSeparator(.bottom)
if !(viewController is PlacePageInfoViewController) {
viewController.view.addSeparator(.bottom)
}
}
}
}
private func cleanupLayout() {
layout?.actionBar?.view.removeFromSuperview()
layout?.navigationBar?.view.removeFromSuperview()
guard let layout else { return }
let childViewControllers = [layout.actionBar, layout.navigationBar] + layout.headerViewControllers + layout.bodyViewControllers
childViewControllers.forEach {
$0?.willMove(toParent: nil)
$0?.view.removeFromSuperview()
$0?.removeFromParent()
}
headerStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
stackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
}
@@ -288,7 +292,7 @@ final class PlacePageScrollView: UIScrollView {
private func updateTopBound(_ bound: CGFloat, duration: TimeInterval) {
alternativeSizeClass(iPhone: {
interactor.updateTopBound(bound, duration: duration)
interactor?.updateTopBound(bound, duration: duration)
}, iPad: {})
}
}
@@ -332,6 +336,7 @@ extension PlacePageViewController: PlacePageViewProtocol {
@objc
func closeAnimated(completion: (() -> Void)? = nil) {
view.isUserInteractionEnabled = false
alternativeSizeClass(iPhone: {
self.scrollTo(CGPoint(x: 0, y: -self.scrollView.height + 1),
forced: true) {
@@ -361,7 +366,7 @@ extension PlacePageViewController: PlacePageViewProtocol {
extension PlacePageViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y < -scrollView.height + 1 && beginDragging {
rootViewController.dismissPlacePage()
closeAnimated()
}
onOffsetChanged(scrollView.contentOffset.y)

View File

@@ -61,11 +61,7 @@ final class PlaceholderView: UIView {
if let activityIndicator = activityIndicator {
activityIndicator.hidesWhenStopped = true
activityIndicator.startAnimating()
if #available(iOS 13.0, *) {
activityIndicator.style = .medium
} else {
activityIndicator.style = .gray
}
activityIndicator.style = .medium
}
titleLabel.text = title

View File

@@ -65,11 +65,9 @@ final class SearchOnMapHeaderView: UIView {
searchBar.setStyle(.defaultSearchBar)
searchBar.placeholder = L("search")
searchBar.showsCancelButton = false
if #available(iOS 13.0, *) {
searchBar.searchTextField.clearButtonMode = .always
searchBar.returnKeyType = .search
searchBar.searchTextField.enablesReturnKeyAutomatically = true
}
searchBar.searchTextField.clearButtonMode = .always
searchBar.returnKeyType = .search
searchBar.searchTextField.enablesReturnKeyAutomatically = true
}
private func setupCancelButton() {

View File

@@ -99,7 +99,7 @@ final class SearchOnMapViewController: UIViewController {
override func viewWillTransition(to size: CGSize, with coordinator: any UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if #available(iOS 14.0, *), ProcessInfo.processInfo.isiOSAppOnMac {
if ProcessInfo.processInfo.isiOSAppOnMac {
updateFrameOfPresentedViewInContainerView()
}
}

View File

@@ -23,6 +23,8 @@ final class SearchCategoriesViewController: MWMTableViewController {
tableView.setStyle(.background)
tableView.register(cell: SearchCategoryCell.self)
tableView.keyboardDismissMode = .onDrag
let footerHeight = (UIApplication.shared.connectedScenes.filter { $0.activationState == .foregroundActive }.first(where: { $0 is UIWindowScene }) as? UIWindowScene)?.keyWindow?.safeAreaInsets.bottom ?? 1
tableView.tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: footerHeight))
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

View File

@@ -43,7 +43,8 @@ final class SearchHistoryViewController: MWMViewController {
tableView.keyboardDismissMode = .onDrag
tableView.delegate = self
tableView.dataSource = self
tableView.tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 1))
let footerHeight = (UIApplication.shared.connectedScenes.filter { $0.activationState == .foregroundActive }.first(where: { $0 is UIWindowScene }) as? UIWindowScene)?.keyWindow?.safeAreaInsets.bottom ?? 1
tableView.tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: footerHeight))
view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false