Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
65
iphone/Maps/UI/PlacePage/Views/DifficultyView.swift
Normal file
65
iphone/Maps/UI/PlacePage/Views/DifficultyView.swift
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
class DifficultyView: UIView {
|
||||
private let stackView = UIStackView()
|
||||
private var views:[UIView] = []
|
||||
var difficulty: ElevationDifficulty = .easy {
|
||||
didSet {
|
||||
updateView()
|
||||
}
|
||||
}
|
||||
var colors: [UIColor] = [.gray, .green, .orange, .red]
|
||||
{
|
||||
didSet {
|
||||
updateView()
|
||||
}
|
||||
}
|
||||
var emptyColor: UIColor = UIColor.gray {
|
||||
didSet {
|
||||
updateView()
|
||||
}
|
||||
}
|
||||
|
||||
private let bulletSize = CGSize(width: 10, height: 10)
|
||||
private let bulletSpacing: CGFloat = 5
|
||||
private let difficultyLevelCount = 3
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
initComponent()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
initComponent()
|
||||
}
|
||||
|
||||
private func initComponent() {
|
||||
self.addSubview(stackView)
|
||||
stackView.frame = bounds
|
||||
stackView.distribution = .fillEqually
|
||||
stackView.axis = .horizontal
|
||||
stackView.spacing = bulletSpacing
|
||||
stackView.alignment = .fill
|
||||
|
||||
for _ in 0..<difficultyLevelCount {
|
||||
let view = UIView()
|
||||
stackView.addArrangedSubview(view)
|
||||
view.layer.setCornerRadius(.custom(bulletSize.height / 2))
|
||||
views.append(view)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateView() {
|
||||
guard colors.count > difficulty.rawValue else {
|
||||
assertionFailure("No fill color")
|
||||
return
|
||||
}
|
||||
let fillColor = colors[difficulty.rawValue]
|
||||
for (idx, view) in views.enumerated() {
|
||||
if idx < difficulty.rawValue {
|
||||
view.backgroundColor = fillColor
|
||||
} else {
|
||||
view.backgroundColor = emptyColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
167
iphone/Maps/UI/PlacePage/Views/ExpandableLabel.swift
Normal file
167
iphone/Maps/UI/PlacePage/Views/ExpandableLabel.swift
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
final class ExpandableLabel: UIView {
|
||||
typealias OnExpandClosure = (() -> Void) -> Void
|
||||
|
||||
private let stackView = UIStackView()
|
||||
private let textView = UITextView()
|
||||
private let expandLabel = UILabel()
|
||||
|
||||
var onExpandClosure: OnExpandClosure?
|
||||
|
||||
var font = UIFont.systemFont(ofSize: 16) {
|
||||
didSet {
|
||||
textView.font = font
|
||||
expandLabel.font = font
|
||||
}
|
||||
}
|
||||
|
||||
var textColor = UIColor.black {
|
||||
didSet {
|
||||
textView.textColor = textColor
|
||||
}
|
||||
}
|
||||
|
||||
var expandColor = UIColor.systemBlue {
|
||||
didSet {
|
||||
expandLabel.textColor = expandColor
|
||||
}
|
||||
}
|
||||
|
||||
var text: String? {
|
||||
didSet {
|
||||
containerText = text
|
||||
textView.text = text
|
||||
if let text = text {
|
||||
isHidden = text.isEmpty
|
||||
} else {
|
||||
isHidden = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var attributedText: NSAttributedString? {
|
||||
didSet {
|
||||
containerText = attributedText?.string
|
||||
textView.attributedText = attributedText
|
||||
if let attributedText = attributedText {
|
||||
isHidden = attributedText.length == 0
|
||||
} else {
|
||||
isHidden = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var expandText = "More" {
|
||||
didSet {
|
||||
expandLabel.text = expandText
|
||||
}
|
||||
}
|
||||
|
||||
var numberOfLines = 2 {
|
||||
didSet {
|
||||
containerMaximumNumberOfLines = numberOfLines > 0 ? numberOfLines + 1 : 0
|
||||
}
|
||||
}
|
||||
|
||||
private var containerText: String?
|
||||
private var containerMaximumNumberOfLines = 2 {
|
||||
didSet {
|
||||
textView.textContainer.maximumNumberOfLines = containerMaximumNumberOfLines
|
||||
textView.invalidateIntrinsicContentSize()
|
||||
}
|
||||
}
|
||||
|
||||
private var oldWidth: CGFloat = 0
|
||||
|
||||
override func setContentHuggingPriority(_ priority: UILayoutPriority, for axis: NSLayoutConstraint.Axis) {
|
||||
super.setContentHuggingPriority(priority, for: axis)
|
||||
textView.setContentHuggingPriority(priority, for: axis)
|
||||
expandLabel.setContentHuggingPriority(priority, for: axis)
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
stackView.axis = .vertical
|
||||
stackView.alignment = .leading
|
||||
containerMaximumNumberOfLines = numberOfLines > 0 ? numberOfLines + 1 : 0
|
||||
textView.textContainer.lineFragmentPadding = 0
|
||||
textView.isScrollEnabled = false
|
||||
textView.isEditable = false
|
||||
textView.textContainerInset = .zero
|
||||
textView.contentMode = .topLeft
|
||||
textView.font = font
|
||||
textView.textColor = textColor
|
||||
textView.text = text
|
||||
textView.attributedText = attributedText
|
||||
textView.setContentHuggingPriority(contentHuggingPriority(for: .vertical), for: .vertical)
|
||||
textView.backgroundColor = .clear
|
||||
textView.dataDetectorTypes = [.link, .phoneNumber]
|
||||
expandLabel.setContentHuggingPriority(contentHuggingPriority(for: .vertical), for: .vertical)
|
||||
expandLabel.font = font
|
||||
expandLabel.textColor = expandColor
|
||||
expandLabel.text = expandText
|
||||
expandLabel.isHidden = true
|
||||
addSubview(stackView)
|
||||
|
||||
stackView.addArrangedSubview(textView)
|
||||
stackView.addArrangedSubview(expandLabel)
|
||||
stackView.alignToSuperview()
|
||||
let gr = UITapGestureRecognizer(target: self, action: #selector(onExpand(_:)))
|
||||
addGestureRecognizer(gr)
|
||||
}
|
||||
|
||||
@objc func onExpand(_ sender: UITapGestureRecognizer) {
|
||||
if expandLabel.isHidden { return }
|
||||
|
||||
let expandClosure = {
|
||||
UIView.animate(withDuration: kDefaultAnimationDuration) {
|
||||
self.containerMaximumNumberOfLines = 0
|
||||
self.expandLabel.isHidden = true
|
||||
self.stackView.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
if let onExpandClosure = onExpandClosure {
|
||||
onExpandClosure(expandClosure)
|
||||
} else {
|
||||
expandClosure()
|
||||
}
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
if oldWidth != bounds.width, let attributedText = attributedText?.mutableCopy() as? NSMutableAttributedString {
|
||||
attributedText.enumerateAttachments(estimatedWidth: bounds.width)
|
||||
self.attributedText = attributedText
|
||||
oldWidth = bounds.width
|
||||
}
|
||||
|
||||
guard containerMaximumNumberOfLines > 0,
|
||||
containerMaximumNumberOfLines != numberOfLines,
|
||||
let s = containerText,
|
||||
!s.isEmpty else {
|
||||
return
|
||||
}
|
||||
let textRect = s.boundingRect(with: CGSize(width: width, height: CGFloat.greatestFiniteMagnitude),
|
||||
options: .usesLineFragmentOrigin,
|
||||
attributes: [.font: font],
|
||||
context: nil)
|
||||
let lineHeight = font.lineHeight
|
||||
if Int(lineHeight * CGFloat(numberOfLines + 1)) >= Int(textRect.height) {
|
||||
expandLabel.isHidden = true
|
||||
containerMaximumNumberOfLines = 0
|
||||
} else {
|
||||
expandLabel.isHidden = false
|
||||
containerMaximumNumberOfLines = numberOfLines
|
||||
}
|
||||
layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
80
iphone/Maps/UI/PlacePage/Views/InfoView.swift
Normal file
80
iphone/Maps/UI/PlacePage/Views/InfoView.swift
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
final class InfoView: UIView {
|
||||
|
||||
private let stackView = UIStackView()
|
||||
private let imageView = UIImageView()
|
||||
private let titleLabel = UILabel()
|
||||
private lazy var imageViewWidthConstrain = imageView.widthAnchor.constraint(equalToConstant: 0)
|
||||
|
||||
init() {
|
||||
super.init(frame: .zero)
|
||||
self.setupView()
|
||||
self.layoutViews()
|
||||
}
|
||||
|
||||
convenience init(image: UIImage?, title: String) {
|
||||
self.init()
|
||||
self.set(image: image, title: title)
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
if #available(iOS 13.0, *), traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
|
||||
imageView.applyTheme()
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
private func setupView() {
|
||||
setStyle(.clearBackground)
|
||||
|
||||
stackView.axis = .horizontal
|
||||
stackView.distribution = .fill
|
||||
stackView.alignment = .center
|
||||
stackView.spacing = 16
|
||||
|
||||
titleLabel.setFontStyle(.regular16, color: .blackPrimary)
|
||||
titleLabel.lineBreakMode = .byWordWrapping
|
||||
titleLabel.numberOfLines = .zero
|
||||
|
||||
imageView.setStyle(.black)
|
||||
imageView.contentMode = .scaleAspectFit
|
||||
}
|
||||
|
||||
private func layoutViews() {
|
||||
addSubview(stackView)
|
||||
stackView.addArrangedSubview(imageView)
|
||||
stackView.addArrangedSubview(titleLabel)
|
||||
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
titleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.setContentHuggingPriority(.defaultHigh, for: .vertical)
|
||||
imageView.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
||||
titleLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
||||
NSLayoutConstraint.activate([
|
||||
stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
stackView.topAnchor.constraint(equalTo: topAnchor),
|
||||
stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
imageView.heightAnchor.constraint(equalToConstant: 24),
|
||||
imageViewWidthConstrain
|
||||
])
|
||||
updateImageWidth()
|
||||
}
|
||||
|
||||
private func updateImageWidth() {
|
||||
imageViewWidthConstrain.constant = imageView.image == nil ? 0 : 24
|
||||
imageView.isHidden = imageView.image == nil
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
func set(image: UIImage?, title: String) {
|
||||
imageView.image = image
|
||||
titleLabel.text = title
|
||||
updateImageWidth()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
final class TouchTransparentView: UIView {
|
||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
let view = super.hitTest(point, with: event)
|
||||
if view === self {
|
||||
return nil
|
||||
}
|
||||
return view
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue