Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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) {}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
Loading…
Add table
Add a link
Reference in a new issue