Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 13:58:55 +01:00
parent 4af19165ec
commit 68073add76
12458 changed files with 12350765 additions and 2 deletions

View file

@ -0,0 +1,194 @@
@objc(MWMBaseRoutePreviewStatus)
final class BaseRoutePreviewStatus: SolidTouchView {
@IBOutlet private weak var errorBox: UIView!
@IBOutlet private weak var resultsBox: UIView!
@IBOutlet private weak var heightBox: UIView!
@IBOutlet private weak var manageRouteBox: UIView!
@IBOutlet weak var manageRouteBoxBackground: UIView! {
didSet {
manageRouteBoxBackground.setStyle(.blackOpaqueBackground)
}
}
@IBOutlet private weak var errorLabel: UILabel!
@IBOutlet private weak var resultLabel: UILabel!
@IBOutlet private weak var arriveLabel: UILabel?
@IBOutlet private weak var heightProfileImage: UIImageView!
@IBOutlet private weak var heightProfileElevationHeight: UILabel?
@IBOutlet private weak var manageRouteButtonRegular: UIButton! {
didSet {
configManageRouteButton(manageRouteButtonRegular)
}
}
@IBOutlet private weak var manageRouteButtonCompact: UIButton? {
didSet {
configManageRouteButton(manageRouteButtonCompact!)
}
}
@IBOutlet private weak var saveRouteAsTrackButtonRegular: UIButton! {
didSet {
configSaveRouteAsTrackButton(saveRouteAsTrackButtonRegular)
}
}
@IBOutlet private weak var saveRouteAsTrackButtonCompact: UIButton! {
didSet {
configSaveRouteAsTrackButton(saveRouteAsTrackButtonCompact)
}
}
@IBOutlet private var errorBoxBottom: NSLayoutConstraint!
@IBOutlet private var resultsBoxBottom: NSLayoutConstraint!
@IBOutlet private var heightBoxBottom: NSLayoutConstraint!
@IBOutlet private var manageRouteBoxBottom: NSLayoutConstraint!
@IBOutlet private var heightBoxBottomManageRouteBoxTop: NSLayoutConstraint!
@objc weak var ownerView: UIView!
weak var navigationInfo: MWMNavigationDashboardEntity?
static let elevationAttributes: [NSAttributedString.Key: Any] =
[
.foregroundColor: UIColor.linkBlue(),
.font: UIFont.medium14()
]
var elevation: NSAttributedString? {
didSet {
updateResultsLabel()
}
}
private var isVisible = false {
didSet {
addView()
isHidden = !isVisible
}
}
private func addView() {
guard superview != ownerView else { return }
ownerView.addSubview(self)
let lg = ownerView.safeAreaLayoutGuide
leadingAnchor.constraint(equalTo: lg.leadingAnchor).isActive = true
trailingAnchor.constraint(equalTo: lg.trailingAnchor).isActive = true
bottomAnchor.constraint(equalTo: lg.bottomAnchor).isActive = true
ownerView.layoutIfNeeded()
}
private func updateHeight() {
DispatchQueue.main.async {
self.animateConstraints(animations: {
self.errorBoxBottom.isActive = !self.errorBox.isHidden
self.resultsBoxBottom.isActive = !self.resultsBox.isHidden
self.heightBoxBottom.isActive = !self.heightBox.isHidden
self.heightBoxBottomManageRouteBoxTop.isActive = !self.heightBox.isHidden
self.manageRouteBoxBottom.isActive = !self.manageRouteBox.isHidden
})
}
}
private func configManageRouteButton(_ button: UIButton) {
button.setImagePadding(8)
button.setTitle(L("planning_route_manage_route"), for: .normal)
}
private func configSaveRouteAsTrackButton(_ button: UIButton) {
button.setImagePadding(8)
button.setTitle(L("save"), for: .normal)
button.setTitle(L("saved"), for: .disabled)
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
updateManageRouteVisibility()
updateHeight()
updateResultsLabel()
}
private func updateManageRouteVisibility() {
let isCompact = traitCollection.verticalSizeClass == .compact
manageRouteBox.isHidden = isCompact || resultsBox.isHidden
manageRouteButtonCompact?.isHidden = !isCompact
saveRouteAsTrackButtonCompact.isHidden = !isCompact
}
@objc func hide() {
isVisible = false
}
@objc func showError(message: String) {
isVisible = true
errorBox.isHidden = false
resultsBox.isHidden = true
heightBox.isHidden = true
manageRouteBox.isHidden = true
errorLabel.text = message
updateHeight()
}
@objc func showReady() {
isVisible = true
errorBox.isHidden = true
resultsBox.isHidden = false
elevation = nil
if MWMRouter.hasRouteAltitude() {
heightBox.isHidden = false
MWMRouter.routeAltitudeImage(for: heightProfileImage.frame.size,
completion: { image, totalAscent, totalDescent in
self.heightProfileImage.image = image
if let totalAscent = totalAscent, let totalDescent = totalDescent {
self.elevation = NSAttributedString(string: "\(totalAscent)\(totalDescent)", attributes: BaseRoutePreviewStatus.elevationAttributes)
}
})
} else {
heightBox.isHidden = true
}
setRouteAsTrackButtonEnabled(true)
updateManageRouteVisibility()
updateHeight()
}
@objc func setRouteSaved(_ isSaved: Bool) {
setRouteAsTrackButtonEnabled(!isSaved)
}
private func setRouteAsTrackButtonEnabled(_ isEnabled: Bool) {
saveRouteAsTrackButtonRegular.isEnabled = isEnabled
saveRouteAsTrackButtonCompact.isEnabled = isEnabled
}
private func updateResultsLabel() {
guard let info = navigationInfo else { return }
if let result = info.estimate().mutableCopy() as? NSMutableAttributedString {
if let elevation = self.elevation {
result.append(MWMNavigationDashboardEntity.estimateDot())
result.append(elevation)
}
resultLabel.attributedText = result
}
}
@objc func onNavigationInfoUpdated(_ info: MWMNavigationDashboardEntity) {
navigationInfo = info
updateResultsLabel()
arriveLabel?.text = String(format: L("routing_arrive"), arguments: [info.arrival])
}
override var sideButtonsAreaAffectDirections: MWMAvailableAreaAffectDirections {
return .bottom
}
override var visibleAreaAffectDirections: MWMAvailableAreaAffectDirections {
return .bottom
}
override var widgetsAreaAffectDirections: MWMAvailableAreaAffectDirections {
return .bottom
}
}

View file

@ -0,0 +1,93 @@
@objc(MWMTransportRoutePreviewStatus)
final class TransportRoutePreviewStatus: SolidTouchView {
@IBOutlet private weak var etaLabel: UILabel!
@IBOutlet private weak var stepsCollectionView: TransportTransitStepsCollectionView!
@IBOutlet private weak var stepsCollectionViewHeight: NSLayoutConstraint!
@IBOutlet private weak var stepsCollectionScrollView: UIScrollView?
@objc weak var ownerView: UIView!
weak var navigationInfo: MWMNavigationDashboardEntity?
private var isVisible = false {
didSet {
guard isVisible != oldValue else { return }
if isVisible {
addView()
} else {
self.removeFromSuperview()
}
}
}
private func addView() {
guard superview != ownerView else { return }
ownerView.addSubview(self)
let lg = ownerView.safeAreaLayoutGuide
leadingAnchor.constraint(equalTo: lg.leadingAnchor).isActive = true
trailingAnchor.constraint(equalTo: lg.trailingAnchor).isActive = true
bottomAnchor.constraint(equalTo: lg.bottomAnchor).isActive = true
}
@objc func hide() {
isVisible = false
}
@objc func showReady() {
isVisible = true
updateHeight()
}
@objc func onNavigationInfoUpdated(_ info: MWMNavigationDashboardEntity, prependDistance: Bool) {
navigationInfo = info
if (prependDistance) {
let labelText = NSMutableAttributedString(string: NSLocalizedString("placepage_distance", comment: "") + ": ")
labelText.append(info.estimate())
etaLabel.attributedText = labelText
}
else {
etaLabel.attributedText = info.estimate()
}
stepsCollectionView.steps = info.transitSteps
stepsCollectionView.isHidden = info.transitSteps.isEmpty
stepsCollectionScrollView?.isHidden = info.transitSteps.isEmpty
}
private func updateHeight() {
guard stepsCollectionViewHeight.constant != stepsCollectionView.contentSize.height else { return }
DispatchQueue.main.async {
self.animateConstraints(animations: {
self.stepsCollectionViewHeight.constant = self.stepsCollectionView.contentSize.height
})
if let sv = self.stepsCollectionScrollView {
let bottomOffset = CGPoint(x: 0, y: sv.contentSize.height - sv.bounds.size.height)
sv.setContentOffset(bottomOffset, animated: true)
}
}
}
override func layoutSubviews() {
super.layoutSubviews()
updateHeight()
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
updateHeight()
}
override var sideButtonsAreaAffectDirections: MWMAvailableAreaAffectDirections {
return .bottom
}
override var visibleAreaAffectDirections: MWMAvailableAreaAffectDirections {
return .bottom
}
override var widgetsAreaAffectDirections: MWMAvailableAreaAffectDirections {
return .bottom
}
}

View file

@ -0,0 +1,35 @@
final class TransportRuler: TransportTransitCell {
enum Config {
static var backgroundColor: UIColor { return UIColor.blackOpaque() }
static var imageColor: UIColor { return UIColor.blackSecondaryText() }
static var labelTextColor: UIColor { return .black }
static let labelTextFont = UIFont.bold12()
static let labelTrailing: CGFloat = 8
}
@IBOutlet private weak var background: UIView! {
didSet {
background.layer.setCornerRadius(.buttonSmall)
background.backgroundColor = Config.backgroundColor
}
}
@IBOutlet private weak var label: UILabel! {
didSet {
label.textColor = Config.labelTextColor
label.font = Config.labelTextFont
}
}
override class func estimatedCellSize(step: MWMRouterTransitStepInfo) -> CGSize {
let defaultSize = super.estimatedCellSize(step: step)
let labelText = step.distance + " " + step.distanceUnits;
let labelSize = labelText.size(width: CGFloat.greatestFiniteMagnitude, font: Config.labelTextFont, maxNumberOfLines: 1)
return CGSize(width: labelSize.width + Config.labelTrailing, height: defaultSize.height)
}
override func config(step: MWMRouterTransitStepInfo) {
label.isHidden = step.distance.isEmpty && step.distanceUnits.isEmpty
label.text = step.distance + " " + step.distanceUnits
}
}

View file

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="TransportRuler" customModule="CoMaps" customModuleProvider="target" propertyAccessControl="all">
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zFu-7m-DoW">
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="450" verticalCompressionResistancePriority="450" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="E5p-F1-lok">
<rect key="frame" x="-25.5" y="0.0" width="41.5" height="20"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="E5p-F1-lok" secondAttribute="trailing" priority="750" id="5NZ-eM-6di"/>
<constraint firstAttribute="bottom" secondItem="E5p-F1-lok" secondAttribute="bottom" id="Gu9-KZ-D9R"/>
<constraint firstAttribute="trailing" secondItem="E5p-F1-lok" secondAttribute="trailing" priority="250" constant="4" id="YNn-8w-SmG"/>
<constraint firstItem="E5p-F1-lok" firstAttribute="top" secondItem="zFu-7m-DoW" secondAttribute="top" id="ZPx-f9-8LV"/>
<constraint firstAttribute="height" constant="20" id="nQ0-T1-CvV"/>
</constraints>
</view>
</subviews>
</view>
<viewLayoutGuide key="safeArea" id="UN7-Tp-qio"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="zFu-7m-DoW" secondAttribute="bottom" id="3wL-hq-d5s"/>
<constraint firstItem="zFu-7m-DoW" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="JMg-4a-h4Z"/>
<constraint firstItem="zFu-7m-DoW" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="MOo-JD-4vU"/>
<constraint firstAttribute="trailing" secondItem="zFu-7m-DoW" secondAttribute="trailing" id="gmg-yt-uVD"/>
</constraints>
<size key="customSize" width="744" height="20"/>
<connections>
<outlet property="background" destination="zFu-7m-DoW" id="fh8-Ss-FeL"/>
<outlet property="label" destination="E5p-F1-lok" id="rsx-8D-Hvq"/>
</connections>
<point key="canvasLocation" x="612.79999999999995" y="48.575712143928037"/>
</collectionViewCell>
</objects>
</document>

View file

@ -0,0 +1,11 @@
class TransportTransitCell: UICollectionViewCell {
enum Config {
static let cellSize = CGSize(width: 20, height: 20)
}
class func estimatedCellSize(step _: MWMRouterTransitStepInfo) -> CGSize {
return Config.cellSize
}
func config(step _: MWMRouterTransitStepInfo) {}
}

View file

@ -0,0 +1,77 @@
final class TransportTransitFlowLayout: UICollectionViewLayout {
enum Config {
static let lineSpacing = CGFloat(8)
static let separator = TransportTransitSeparator.self
static let separatorKind = toString(separator)
static let separatorSize = CGSize(width: 16, height: 20)
static let minimumCellWidthAfterShrink = CGFloat(56)
}
private var cellsLayoutAttrs = [UICollectionViewLayoutAttributes]()
private var decoratorsLayoutAttrs = [UICollectionViewLayoutAttributes]()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
register(Config.separator, forDecorationViewOfKind: Config.separatorKind)
}
override var collectionViewContentSize: CGSize {
let width = collectionView?.frame.width ?? 0
let height = cellsLayoutAttrs.reduce(0) { return max($0, $1.frame.maxY) }
return CGSize(width: width, height: height)
}
override func prepare() {
super.prepare()
let cv = collectionView as! TransportTransitStepsCollectionView
let section = 0
let width = cv.width
var x = CGFloat(0)
var y = CGFloat(0)
cellsLayoutAttrs = []
decoratorsLayoutAttrs = []
for item in 0 ..< cv.numberOfItems(inSection: section) {
let ip = IndexPath(item: item, section: section)
if item != 0 {
let sepAttr = UICollectionViewLayoutAttributes(forDecorationViewOfKind: Config.separatorKind, with: ip)
sepAttr.frame = CGRect(origin: CGPoint(x: x, y: y), size: Config.separatorSize)
decoratorsLayoutAttrs.append(sepAttr)
x += Config.separatorSize.width
}
var cellSize = cv.estimatedCellSize(item: item)
let spaceLeft = width - x - Config.separatorSize.width
let minimumSpaceRequired = min(cellSize.width, Config.minimumCellWidthAfterShrink)
if spaceLeft < minimumSpaceRequired {
x = 0
y += Config.separatorSize.height + Config.lineSpacing
} else {
cellSize.width = min(cellSize.width, spaceLeft)
}
let cellAttr = UICollectionViewLayoutAttributes(forCellWith: ip)
cellAttr.frame = CGRect(origin: CGPoint(x: x, y: y), size: cellSize)
cellsLayoutAttrs.append(cellAttr)
x += cellSize.width
}
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return cellsLayoutAttrs.first(where: { $0.indexPath == indexPath })
}
override func layoutAttributesForDecorationView(ofKind _: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return decoratorsLayoutAttrs.first(where: { $0.indexPath == indexPath })
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var layoutAttrs = cellsLayoutAttrs.filter { $0.frame.intersects(rect) }
layoutAttrs.append(contentsOf: decoratorsLayoutAttrs.filter { $0.frame.intersects(rect) })
return layoutAttrs
}
}

View file

@ -0,0 +1,18 @@
final class TransportTransitIntermediatePoint: TransportTransitCell {
enum Config {
static var imageColor: UIColor { return UIColor.primary() }
}
@IBOutlet private weak var image: UIImageView!
override func config(step: MWMRouterTransitStepInfo) {
super.config(step: step)
let i = step.intermediateIndex + 1
// TODO: Properly support more than 20 icons.
var iconName = "route-point-20"
if (i >= 1 && i < 20) {
iconName = "route-point-" + String(i)
}
image.image = #imageLiteral(resourceName: iconName)
image.tintColor = Config.imageColor
}
}

View file

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="TransportTransitIntermediatePoint" customModule="CoMaps" customModuleProvider="target" propertyAccessControl="all">
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="route-point-1" translatesAutoresizingMaskIntoConstraints="NO" id="kZf-7J-OZ5">
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<color key="tintColor" red="0.1215686275" green="0.59999999999999998" blue="0.32156862749999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="OkK-UD-TWr"/>
<constraint firstAttribute="height" constant="20" id="n8x-xG-gUb"/>
</constraints>
</imageView>
</subviews>
</view>
<constraints>
<constraint firstItem="kZf-7J-OZ5" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="5rb-Q4-qua"/>
<constraint firstAttribute="bottom" secondItem="kZf-7J-OZ5" secondAttribute="bottom" id="5uG-SP-l0m"/>
<constraint firstItem="kZf-7J-OZ5" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="KiE-6N-4Jp"/>
<constraint firstAttribute="trailing" secondItem="kZf-7J-OZ5" secondAttribute="trailing" id="mJI-lD-bsw"/>
</constraints>
<viewLayoutGuide key="safeArea" id="Aa6-gi-Bkw"/>
<size key="customSize" width="490" height="20"/>
<connections>
<outlet property="image" destination="kZf-7J-OZ5" id="b9M-uB-XoA"/>
</connections>
<point key="canvasLocation" x="270" y="54"/>
</collectionViewCell>
</objects>
<resources>
<image name="route-point-1" width="24" height="24"/>
</resources>
</document>

View file

@ -0,0 +1,21 @@
final class TransportTransitPedestrian: TransportTransitCell {
enum Config {
static var backgroundColor: UIColor { return UIColor.blackOpaque() }
static var imageColor: UIColor { return UIColor.blackSecondaryText() }
}
@IBOutlet private weak var background: UIView! {
didSet {
background.layer.setCornerRadius(.buttonSmall)
background.backgroundColor = Config.backgroundColor
}
}
@IBOutlet private weak var image: UIImageView! {
didSet {
image.image = UIImage(resource: .icWalk)
image.tintColor = Config.imageColor
image.contentMode = .scaleAspectFit
}
}
}

View file

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="TransportTransitPedestrian" customModule="CoMaps" customModuleProvider="target" propertyAccessControl="all">
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Shb-td-cXL">
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" insetsLayoutMarginsFromSafeArea="NO" image="ic_walk" translatesAutoresizingMaskIntoConstraints="NO" id="9hI-Y9-uRa">
<rect key="frame" x="3" y="3" width="14" height="14"/>
<constraints>
<constraint firstAttribute="width" constant="14" id="EeL-qS-rKg"/>
<constraint firstAttribute="height" constant="14" id="WCk-l4-hQF"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="9hI-Y9-uRa" firstAttribute="centerY" secondItem="Shb-td-cXL" secondAttribute="centerY" id="IkJ-Yh-48o"/>
<constraint firstAttribute="height" constant="20" id="hEu-YE-u8j"/>
<constraint firstAttribute="width" constant="20" id="pxM-8S-VsE"/>
<constraint firstItem="9hI-Y9-uRa" firstAttribute="centerX" secondItem="Shb-td-cXL" secondAttribute="centerX" id="vZX-k3-HmM"/>
</constraints>
</view>
</subviews>
</view>
<constraints>
<constraint firstAttribute="trailing" secondItem="Shb-td-cXL" secondAttribute="trailing" id="JRQ-z7-d3U"/>
<constraint firstAttribute="bottom" secondItem="Shb-td-cXL" secondAttribute="bottom" id="nDY-rn-9J0"/>
<constraint firstItem="Shb-td-cXL" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="pu1-LW-wkd"/>
<constraint firstItem="Shb-td-cXL" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="ymH-iI-Ify"/>
</constraints>
<viewLayoutGuide key="safeArea" id="gmH-YP-0pW"/>
<size key="customSize" width="227" height="20"/>
<connections>
<outlet property="background" destination="Shb-td-cXL" id="YAM-iA-NYW"/>
<outlet property="image" destination="9hI-Y9-uRa" id="9i8-eW-XWO"/>
</connections>
<point key="canvasLocation" x="137.5" y="54"/>
</collectionViewCell>
</objects>
<resources>
<image name="ic_walk" width="24" height="24"/>
</resources>
</document>

View file

@ -0,0 +1,23 @@
final class TransportTransitSeparator: UICollectionReusableView {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
let image = UIImageView(image: #imageLiteral(resourceName: "ic_arrow"))
image.setStyle(.black)
image.contentMode = .scaleAspectFit
addSubview(image)
}
override func layoutSubviews() {
super.layoutSubviews()
subviews.first!.frame = bounds
}
}

View file

@ -0,0 +1,59 @@
final class TransportTransitStepsCollectionView: UICollectionView {
var steps: [MWMRouterTransitStepInfo] = [] {
didSet {
reloadData()
}
}
override var frame: CGRect {
didSet {
collectionViewLayout.invalidateLayout()
}
}
override var bounds: CGRect {
didSet {
collectionViewLayout.invalidateLayout()
}
}
override func awakeFromNib() {
super.awakeFromNib()
dataSource = self
[TransportTransitIntermediatePoint.self, TransportTransitPedestrian.self,
TransportTransitTrain.self, TransportRuler.self].forEach {
register(cellClass: $0)
}
}
private func cellClass(item: Int) -> TransportTransitCell.Type {
let step = steps[item]
switch step.type {
case .intermediatePoint: return TransportTransitIntermediatePoint.self
case .pedestrian: return TransportTransitPedestrian.self
case .train: fallthrough
case .subway: fallthrough
case .lightRail: fallthrough
case .monorail: return TransportTransitTrain.self
case .ruler: return TransportRuler.self
}
}
func estimatedCellSize(item: Int) -> CGSize {
return cellClass(item: item).estimatedCellSize(step: steps[item])
}
}
extension TransportTransitStepsCollectionView: UICollectionViewDataSource {
func collectionView(_: UICollectionView, numberOfItemsInSection _: Int) -> Int {
return steps.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let item = indexPath.item
let cellClass = self.cellClass(item: item)
let cell = collectionView.dequeueReusableCell(withCellClass: cellClass, indexPath: indexPath) as! TransportTransitCell
cell.config(step: steps[item])
return cell
}
}

View file

@ -0,0 +1,52 @@
final class TransportTransitTrain: TransportTransitCell {
enum Config {
static var labelTextColor: UIColor { return .white }
static let labelTextFont = UIFont.bold12()
static let labelTrailing: CGFloat = 4
}
@IBOutlet private weak var background: UIView! {
didSet {
background.layer.setCornerRadius(.buttonSmall)
}
}
@IBOutlet private weak var image: UIImageView!
@IBOutlet private weak var label: UILabel! {
didSet {
label.textColor = Config.labelTextColor
label.font = Config.labelTextFont
}
}
@IBOutlet private weak var labelTrailing: NSLayoutConstraint! {
didSet {
labelTrailing.constant = Config.labelTrailing
}
}
@IBOutlet private var emptyNumberTrailingOffset: NSLayoutConstraint!
override class func estimatedCellSize(step: MWMRouterTransitStepInfo) -> CGSize {
let defaultSize = super.estimatedCellSize(step: step)
let labelSize = step.number.size(width: CGFloat.greatestFiniteMagnitude, font: Config.labelTextFont, maxNumberOfLines: 1)
return CGSize(width: defaultSize.width + labelSize.width + Config.labelTrailing, height: defaultSize.height)
}
override func config(step: MWMRouterTransitStepInfo) {
switch step.type {
case .intermediatePoint: fallthrough
case .pedestrian: fatalError()
case .train: image.image = #imageLiteral(resourceName: "ic_20px_route_planning_train")
case .subway: image.image = #imageLiteral(resourceName: "ic_20px_route_planning_metro")
case .lightRail: image.image = #imageLiteral(resourceName: "ic_20px_route_planning_lightrail")
case .monorail: image.image = #imageLiteral(resourceName: "ic_20px_route_planning_monorail")
case .ruler: fatalError()
}
background.backgroundColor = step.color
emptyNumberTrailingOffset.isActive = step.number.isEmpty
label.isHidden = step.number.isEmpty
label.text = step.number
}
}

View file

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="TransportTransitTrain" customModule="CoMaps" customModuleProvider="target" propertyAccessControl="all">
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kDc-o2-JUp">
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="9d1-PP-h28">
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<constraints>
<constraint firstAttribute="width" secondItem="9d1-PP-h28" secondAttribute="height" multiplier="1:1" id="g45-u1-mQs"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="450" verticalCompressionResistancePriority="450" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0Eo-0D-mup">
<rect key="frame" x="20" y="0.0" width="0.0" height="20"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="9d1-PP-h28" firstAttribute="top" secondItem="kDc-o2-JUp" secondAttribute="top" id="3Nm-tA-OCb"/>
<constraint firstItem="0Eo-0D-mup" firstAttribute="leading" secondItem="9d1-PP-h28" secondAttribute="trailing" id="3sb-9G-W6c"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="0Eo-0D-mup" secondAttribute="trailing" priority="750" id="5NZ-eM-6di"/>
<constraint firstAttribute="bottom" secondItem="0Eo-0D-mup" secondAttribute="bottom" id="Gu9-KZ-D9R"/>
<constraint firstAttribute="trailing" secondItem="0Eo-0D-mup" secondAttribute="trailing" priority="250" constant="4" id="YNn-8w-SmG"/>
<constraint firstItem="0Eo-0D-mup" firstAttribute="top" secondItem="kDc-o2-JUp" secondAttribute="top" id="ZPx-f9-8LV"/>
<constraint firstItem="9d1-PP-h28" firstAttribute="leading" secondItem="kDc-o2-JUp" secondAttribute="leading" id="cQu-Lg-9xy"/>
<constraint firstAttribute="bottom" secondItem="9d1-PP-h28" secondAttribute="bottom" id="m4N-mH-YaE"/>
<constraint firstAttribute="trailing" secondItem="9d1-PP-h28" secondAttribute="trailing" id="mCa-Ah-9Xz"/>
<constraint firstAttribute="height" constant="20" id="nQ0-T1-CvV"/>
</constraints>
</view>
</subviews>
</view>
<constraints>
<constraint firstAttribute="bottom" secondItem="kDc-o2-JUp" secondAttribute="bottom" id="3wL-hq-d5s"/>
<constraint firstItem="kDc-o2-JUp" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="JMg-4a-h4Z"/>
<constraint firstItem="kDc-o2-JUp" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="MOo-JD-4vU"/>
<constraint firstAttribute="trailing" secondItem="kDc-o2-JUp" secondAttribute="trailing" id="gmg-yt-uVD"/>
</constraints>
<viewLayoutGuide key="safeArea" id="UN7-Tp-qio"/>
<size key="customSize" width="744" height="20"/>
<connections>
<outlet property="background" destination="kDc-o2-JUp" id="fh8-Ss-FeL"/>
<outlet property="emptyNumberTrailingOffset" destination="mCa-Ah-9Xz" id="k8k-Ca-u6s"/>
<outlet property="image" destination="9d1-PP-h28" id="Kpo-zR-osU"/>
<outlet property="label" destination="0Eo-0D-mup" id="Z15-fa-Wkx"/>
<outlet property="labelTrailing" destination="YNn-8w-SmG" id="lL1-5q-mjx"/>
</connections>
<point key="canvasLocation" x="383" y="54"/>
</collectionViewCell>
</objects>
</document>