Добавление строки после разрыва строки - PullRequest
0 голосов
/ 16 июня 2020

enter image description here

Я хочу добиться этого (показано на рисунке выше) разрыва строки и конкатенации для NSAttributedString. Второй город, в данном случае Париж, должен начинаться сверху, но он начинается с правой стороны Германии, потому что Германия начинается с новой линии, поэтому Париж добавляется с правой стороны Германии, а не начинается сверху. Любая помощь будет принята с благодарностью.

Ниже мой код:

    /// Flight Attributed String
    var flightAttributedString = NSMutableAttributedString(string: "");

    /// From City
    let fromCityAttributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 10.0, weight: .medium)];
    let fromCity = NSMutableAttributedString(string: "\((self.route?.fromCity)!)  ", attributes: fromCityAttributes);

    /// From Country
    let fromCountryAttributes = [NSAttributedString.Key.foregroundColor : kAppSecondryIconColor, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 8.0)];
    let fromCountry = NSMutableAttributedString(string: "\n\((self.route?.fromCountry)!)", attributes: fromCountryAttributes);

    /// From City Complete
    fromCity.append(fromCountry);

    /// To City
    let toCityAttributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 10.0, weight: .medium)] as [NSAttributedString.Key : Any]
    let toCity = NSMutableAttributedString(string: "\((self.route?.toCity)!)  ", attributes: toCityAttributes);

    /// To Country
    let toCountryAttributes = [NSAttributedString.Key.foregroundColor : kAppSecondryIconColor, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 8.0)];
    let toCountry = NSMutableAttributedString(string: "\n\((self.route?.toCountry)!)", attributes: toCountryAttributes);

    /// To City Complete
    toCity.append(toCountry);
    // print("toCity.accessibilityFrame: \(toCity.accessibilityFrame)");

    /// Plain Icon
    let imgAttachment = NSTextAttachment()
    imgAttachment.image = UIImage(named: "iconAirplane.png")
    imgAttachment.bounds = CGRect(x: 0, y: -5, width: 25.0, height: 25.0)
    let imgAirplane = NSAttributedString(attachment: imgAttachment)

    /// Making Complete Flight String
    flightAttributedString.append(fromCity);
    flightAttributedString.append(imgAirplane);
    flightAttributedString.append(toCity);

    /// Draw the result in a lblFlight
    // self.lblFlight.lineBreakMode = .byWordWrapping;
    self.lblFlight.attributedText = flightAttributedString;

1 Ответ

0 голосов
/ 16 июня 2020

Я бы лично использовал здесь представления стека, это определенно даст вам больше гибкости.

Вот окончательный результат:

enter image description here

И реализация будет такой:

import UIKit

class ViewController: UIViewController {

    private let flightBoardView: FlightBoardView = {
        $0.translatesAutoresizingMaskIntoConstraints = false
        return $0
    }(FlightBoardView())

    override func viewDidLoad() {
        super.viewDidLoad()
        setup()
        view.backgroundColor = .white
    }

    private func setup() {
        setupViews()
        setupConstraints()
    }

    private func setupViews() {
        flightBoardView.set(fromCountry: "Germany", fromCity: "Frankfurt", toCountry: "France", toCity: "Paris")
        view.addSubview(flightBoardView)
    }

    private func setupConstraints() {
        flightBoardView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        flightBoardView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }
}

И ваш FlightBoardView может быть подклассом UIView (в случае, если вы хотите повторно использовать его где-нибудь позже в своем коде и избежать дублирования) и посмотрите вот так:

class FlightBoardView: UIView {

    private lazy var departureStackView: UIStackView = {
        $0.distribution = .fill
        $0.alignment = .leading
        $0.axis = .vertical
        $0.spacing = 5
        $0.translatesAutoresizingMaskIntoConstraints = false
        return $0
    }(UIStackView(arrangedSubviews: [fromCountryLabel, fromCityLabel]))

    private lazy var destinationStackView: UIStackView = {
        $0.distribution = .fill
        $0.alignment = .leading
        $0.axis = .vertical
        $0.spacing = 5
        $0.translatesAutoresizingMaskIntoConstraints = false
        return $0
    }(UIStackView(arrangedSubviews: [toCountryLabel, toCityLabel]))

    private lazy var containerStackView: UIStackView = {
        $0.distribution = .fill
        $0.alignment = .center
        $0.axis = .horizontal
        $0.spacing = 20
        $0.translatesAutoresizingMaskIntoConstraints = false
        return $0
    }(UIStackView(arrangedSubviews: [departureStackView, planeImageView, destinationStackView]))

    private let fromCountryLabel: UILabel = {
        $0.textColor = .black
        $0.font = UIFont.systemFont(ofSize: 30)
        $0.translatesAutoresizingMaskIntoConstraints = false
        return $0
    }(UILabel())

    private let fromCityLabel: UILabel = {
        $0.textColor = .lightGray
        $0.font = UIFont.systemFont(ofSize: 15)
        $0.translatesAutoresizingMaskIntoConstraints = false
        return $0
    }(UILabel())

    private let toCountryLabel: UILabel = {
        $0.textColor = .black
        $0.font = UIFont.systemFont(ofSize: 30)
        $0.translatesAutoresizingMaskIntoConstraints = false
        return $0
    }(UILabel())

    private let toCityLabel: UILabel = {
        $0.textColor = .lightGray
        $0.font = UIFont.systemFont(ofSize: 15)
        $0.translatesAutoresizingMaskIntoConstraints = false
        return $0
    }(UILabel())

    private let planeImageView: UIImageView = {
        $0.contentMode = .scaleAspectFit
        $0.image = UIImage(named: "airplane")?.withRenderingMode(.alwaysTemplate)
        $0.tintColor = .systemBlue
        $0.translatesAutoresizingMaskIntoConstraints = false
        return $0
    }(UIImageView())

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder: NSCoder) {
        fatalError()
    }

    private func setup() {
        addSubview(containerStackView)
        NSLayoutConstraint.activate([
            containerStackView.topAnchor.constraint(equalTo: topAnchor),
            containerStackView.leftAnchor.constraint(equalTo: leftAnchor),
            containerStackView.bottomAnchor.constraint(equalTo: bottomAnchor),
            containerStackView.rightAnchor.constraint(equalTo: rightAnchor),
            planeImageView.widthAnchor.constraint(equalToConstant: 50),
            planeImageView.heightAnchor.constraint(equalTo: planeImageView.widthAnchor),
        ])
    }

    func set(fromCountry: String, fromCity: String, toCountry: String, toCity: String) {
        fromCountryLabel.text = fromCountry
        fromCityLabel.text = fromCity
        toCountryLabel.text = toCountry
        toCityLabel.text = toCity
    }
}

Конечно, вы можете сделать то же самое с раскадровками и файлами xib, если хотите, но, по крайней мере, это дает вам рабочий пример, и вы можете настроить его в соответствии со своими потребностями.

Я также добавил метод set(fromCountry:fromCity:toCountry:toCity:), чтобы вы могли легко изменять данные из родительского представления.

...