Подгонка текста в UILabel - Swift - PullRequest
       14

Подгонка текста в UILabel - Swift

0 голосов
/ 22 сентября 2018

Я борюсь с подгонкой текста в UILabel.Я хочу, чтобы ширина UILabel была постоянной, но я хочу, чтобы размер шрифта текста изменился, чтобы весь текст мог поместиться в метке.Я в основном создаю строку меню с текстовыми элементами: сегодня, завтра, на этой неделе, на следующей неделе.Это моя настройка метки:

class MenuCell: BaseCell {

let dateLabel: UILabel = {
    let label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false
    label.backgroundColor = UIColor(red: 247/255, green: 199/255, blue: 199/255, alpha: 1)
    label.sizeToFit()
    label.textAlignment = .center
    label.adjustsFontForContentSizeCategory = true
    label.allowsDefaultTighteningForTruncation = true
    label.numberOfLines  =   2
    label.lineBreakMode  =  NSLineBreakMode.byTruncatingTail
    label.adjustsFontSizeToFitWidth    =   true
    label.minimumScaleFactor           =    10/UIFont.labelFontSize
    return label
}()

У меня есть конкретный размер высоты по ширине с помощью этой функции:

func collectionView(_ collectionView: UICollectionView, layout 
 collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: frame.width / 4, height: frame.height)

}

Я настроил эти ячейки:

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! MenuCell
    cell.dateLabel.text = labelnames[indexPath.item]


  cell.backgroundColor = UIColor(red: 247/255, green: 199/255, blue: 199/255, alpha: 1)

    return cell
}

В конце концовЧтобы добавить ячейки в представление, я делаю:

override func setupViews(){
super.setupViews()
addSubview(dateLabel)
dateLabel.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
}

Я помещаю весь этот вид целиком в файл моего другого контроллера представления прямо под панелью навигации:

lazy var menuBar: MenuBar = {
    let mb = MenuBar()
    mb.homeController = self
    return mb
}()
private func setupMenuBar() {
    view.addSubview(menuBar)
    view.addConstraintsWithFormat(format: "H:|[v0]|", views: menuBar)
    view.addConstraintsWithFormat(format: "V:|-64-[v0(50)]", views: menuBar)    
}

Но дляпочему-то текст, который у меня есть, не меняет размер шрифта, чтобы он помещался в ячейку UIlabel.Пример текста, который пытается уместиться: let labelnames = ["Todayyyyyyyyyy","Tomorrow", "This Week", "Next Week"] «Todayyyyyyyyyy» не меняет размер шрифта, чтобы соответствовать целиком.Какие другие атрибуты показывают, что я настраиваю, чтобы исправить мою проблему?

Ответы [ 2 ]

0 голосов
/ 22 сентября 2018

Вот как я бы это сделал (мне нравится использовать @IBDesignable, чтобы я мог также свободно использовать его в раскадровках)

extension UIFont {
    func sizeOfString (string: String, constrainedToWidth width: Double) -> CGSize {
        return NSString(string: string).boundingRect(with: CGSize(width: width, height: Double.greatestFiniteMagnitude),
                                                     options: NSStringDrawingOptions.usesLineFragmentOrigin,
                                                             attributes: [NSAttributedStringKey.font: self],
                                                             context: nil).size
    }
}

@IBDesignable public class TestLabel: UILabel {
    @IBInspectable public var autoResize: Bool = false {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var resizeStep: CGFloat = 1.0 {
        didSet {
            decorate()
        }
    }

    func decorate() {
        // Here you can change whatever you want

        var bestFontSize: CGFloat = 1
        var testedFontSize: CGSize = self.font.withSize(bestFontSize).sizeOfString(string: self.text!, constrainedToWidth: Double.greatestFiniteMagnitude)
        while testedFontSize.width < self.frame.width && testedFontSize.height < self.frame.height {
            bestFontSize += 1
            testedFontSize = self.font.withSize(bestFontSize).sizeOfString(string: self.text!, constrainedToWidth: Double.greatestFiniteMagnitude)
        }
        self.font = self.font.withSize(bestFontSize - self.resizeStep)
    }
}

Я только что проверил это на детской площадке, поэтому я не проверил полностьюон работал в раскадровке так, как я и предполагал, но он должен быть совершенно функциональным, хотя он не заботится о bounds или contentsRect, а просто показывает, как вы можете его использовать.

Тем не менее,не рекомендовал бы делать это с точки зрения дизайна.

0 голосов
/ 22 сентября 2018

ВАРИАНТ № 1 - АВТО НАСТРОЙКА

Установите размер шрифта большим и уменьшите его при необходимости, например:

label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.01

Выпросто нужно установить начальный размер, чтобы быть гигантским.Это только уменьшает, а не увеличивает.

Недостатком здесь является то, что если вы делаете что-то действительно большое, например:

label.font = UIFont.systemFont(ofSize: 500)
label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.0001

Высота метки будет основана на 500,по умолчанию.

ВАРИАНТ № 2 - ВРУЧНУЮ РЕГУЛИРОВКУ ДЛЯ ПОДСТАВКИ

func updateLabel(_ s: String, label: UILabel) {

    var size = 222 as CGFloat
    repeat {
        let textSize = s.size(withAttributes:[.font: UIFont.systemFont(ofSize:size)])
        if textSize.width <= label.frame.width {
            break
        }
        size -= 0.10

    } while (size > 4)
    label.font = UIFont.systemFont(ofSize: size)
    label.text = s
}

Быстрый пример: видео и исходный код .Верхняя метка использует Вариант № 1, а нижняя метка использует Вариант № 2.

Вы можете видеть, что вариант №2 работает лучше, чем управляемый системой способ.Возможно, он также требует больше ресурсов процессора, но, возможно, не имеет значения, выполняете ли вы это только один раз для каждой метки.

Возможно, ваш фрейм метки не соответствует размеру, который вы о нем думаете, потому что вытолько устанавливаем topAnchor .Вы также устанавливаете другие или делаете ограничение ширины или что-то?

Если метка должна заполнять ячейку, вы могли бы сделать что-то вроде этого:

override func setupViews(){
    super.setupViews()

    addSubview(dateLabel)
    dateLabel.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
    dateLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
    dateLabel.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
    dateLabel.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
}

Другое предложение будетчтобы запустить приложение в XCode и затем использовать инструмент отладчика представления - щелкните эту вещь:

view debugger

Это покажет в разобранном виде вашего экранав Xcode вместе с кадрами всех ваших просмотров.Проверьте, действительно ли размер этикетки соответствует вашим ожиданиям.

...