Определение размера этикетки с помощью Autolayout - PullRequest
1 голос
/ 17 апреля 2019

Описание проблемы

У меня есть ярлык слева от графика в приложении для iOS. Мне удалось повернуть метку на 90 градусов, как показано ниже, используя код, скопированный в следующем разделе:

enter image description here

Однако, как только я изменю текст на «Скорость (км / ч):», метка станет шире, как показано ниже:

enter image description here

Компоновка

В конструкторе интерфейсов не установлены соответствующие ограничения. Единственные ограничения, установленные здесь: - вертикальное центрирование этикетки - правый, верхний и нижний края вида графика придерживаются правого, верхнего и нижнего края вида

Остальное задается в коде

enter image description here

Код

func setup(speedArray: [Float32]) {

    //Convert speed to Km/h from m/s
    let speedArrayKMH = speedArray.map({$0*3.6})

    //Draw Chart
    //This only styles the chart (colors, user interaction, etc...
    //no code in this fuction that affects layout)
    setupSpeedChart(speedArray: speedArrayKMH)

    //
    //  Customise speed label
    //
    //Label text
    chartTitleLabel.textAlignment = .center
    //Text color
    self.chartTitleLabel.textColor = BoxTextColor
    //Rotate
    chartTitleLabel.transform = CGAffineTransform(rotationAngle: CGFloat(-Double.pi/2))
    //Constrain
    let C1 = NSLayoutConstraint(item: chartTitleLabel, attribute: .leadingMargin, relatedBy: .equal, toItem: self, attribute: .leading, multiplier: 1, constant: 0)
    let C2 = NSLayoutConstraint(item: chartTitleLabel, attribute: .trailingMargin, relatedBy: .equal, toItem: speedLineChart, attribute: .leading, multiplier: 1, constant: 0)

    NSLayoutConstraint.activate([C1, C2])

}

Что я пробовал

Я пробовал несколько комбинаций построения и размера, в том числе:

  • исправление свойства кадра метки (высота и ширина)
  • добавление ограничения для ширины и высоты метки

ничего не работает

Например, добавление следующего ограничения для ширины метки дает:

let C3 = NSLayoutConstraint(item: chartTitleLabel, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 45)

enter image description here

Ответы [ 2 ]

1 голос
/ 17 апреля 2019

не хватает нескольких ключевых вещей сначала вы забыли использовать translateAutoReaizingMaskIntoConstraints

перейдите в раскадровку выберите вашу метку перейдите в инспектор под меткой есть автоусадка установите минимальный размер шрифта установите размер 11

затем выполните следующие действия: didload

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    myLabel.text = "speed in km"
    myLabel.textAlignment = .center
    myLabel.transform = CGAffineTransform(rotationAngle: CGFloat(-Double.pi/2))
    myLabel.translatesAutoresizingMaskIntoConstraints = false
    let c1 = NSLayoutConstraint(item: myLabel, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 200)
    let c2 = NSLayoutConstraint(item: myLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 60)

    let c3 = NSLayoutConstraint(item: myLabel, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: -60)
    let c4 = NSLayoutConstraint(item: myLabel, attribute: .centerY, relatedBy: .equal, toItem: myImageView, attribute: .centerY, multiplier: 1, constant: 0)

    NSLayoutConstraint.activate([c1, c2, c3, c4])

}

Я попытался обновить текст до нового текста с большим количеством символов, чем предыдущий, и я работал просто отлично

this is before changing text this is after changing the text

0 голосов
/ 17 апреля 2019

Проблема заключается в этой части описания transform в документации Apple: https://developer.apple.com/documentation/uikit/uiview/1622459-transform

В iOS 8.0 и более поздних версиях свойство transform не влияет на Auto Layout. Автоматический макет вычисляет прямоугольник выравнивания вида на основе его нетрансформированного фрейма.

Итак, когда вы изменяете текст метки, ваши ограничения связаны с нетрансформированным фреймом .

Исправление заключается в том, чтобы вставить этикетку в «контейнер» UIView и ограничить ширину контейнера до высоты высота до ширина этикетки.

Настройте xib следующим образом (я использую контрастные цвета фона, чтобы было удобно видеть кадры):

enter image description here

Обратите внимание, что я дал ограничениям ширины и высоты вида контейнера 80. Отредактируйте каждое из этих ограничений и установите их как "Заполнители":

enter image description here

Мы будем устанавливать новые ограничения в коде, поэтому они будут удалены во время сборки, но будут удовлетворять проверке макета IB.

В awakeFromNib() в своем пользовательском классе добавьте новые ограничения ширины и высоты и примените преобразование вращения:

override func awakeFromNib() {
    super.awakeFromNib()

    // set HUGGING priority on title label to REQUIRED for both axis
    chartTitleLabel.setContentHuggingPriority(.required, for: .horizontal)
    chartTitleLabel.setContentHuggingPriority(.required, for: .vertical)

    NSLayoutConstraint.activate([

        // constrain title container view WIDTH equal to title label HEIGHT
        // set the constant to add padding on left and right of rotated title label
        // here it is set to 12, which gives 6-pts padding on each side
        chartTitleContainerView.widthAnchor.constraint(equalTo: chartTitleLabel.heightAnchor, constant: 12.0),

        // constrain title container view HEIGHT equal to title label WIDTH
        chartTitleContainerView.heightAnchor.constraint(equalTo: chartTitleLabel.widthAnchor, constant: 0.0),

        ])

    // rotate the title label
    chartTitleLabel.transform = CGAffineTransform(rotationAngle: CGFloat(-Double.pi/2))

    // un-comment after development
    //      chartTitleLabel.backgroundColor = .clear
    //      chartTitleContainerView.backgroundColor = .clear

}

Теперь, в вашем setup() func (где, я предполагаю, вы добавляете «представление графика» в качестве подпредставления), добавьте ограничения для представления графика:

func setup(speedArray: [Float32]) {

    //Convert speed to Km/h from m/s
    let speedArrayKMH = speedArray.map({$0*3.6})

    // assuming setupSpeedChart() creates speedLineChart view and adds it to self

    //Draw Chart
    //This only styles the chart (colors, user interaction, etc...
    //no code in this fuction that affects layout)
    setupSpeedChart(speedArray: speedArrayKMH)

    NSLayoutConstraint.activate([

        // constrain chart view LEADING to title container view TRAILING
        speedLineChart.leadingAnchor.constraint(equalTo: chartTitleContainerView.trailingAnchor, constant: 0.0),

        // constrain chart view top, bottom and trailing to self
        speedLineChart.topAnchor.constraint(equalTo: topAnchor, constant: 0.0),
        speedLineChart.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 0.0),
        speedLineChart.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 0.0),

        ])

}

Это результат:

enter image description here

и с выключенными цветами "dev":

enter image description here

Теперь вы можете изменить текст метки заголовка, и он останется по центру по вертикали и горизонтали, без изменения горизонтального размера / интервала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...