Как создать отступ вокруг текста UILabel?

Я программно стилизую UILabel и не могу получить какие-либо отступы вокруг текста метки:

введите здесь описание изображения

Изучив множество потоков SO по этому вопросу (этот, в частности) Я думал, что нашел решение, но оно не влияет на этикетку. Я создал собственный класс для метки, который является подклассом UILabel:

// Swift 3 (I know, I know...)

class PublicationTypeBadge: UILabel {
    var textInsets = UIEdgeInsets.zero {
        didSet { invalidateIntrinsicContentSize() }
    }

    override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
        let insetRect = UIEdgeInsetsInsetRect(bounds, textInsets)
        let textRect = super.textRect(forBounds: insetRect, limitedToNumberOfLines: numberOfLines)
        let invertedInsets = UIEdgeInsets(top: -textInsets.top,
                                          left: -textInsets.left,
                                          bottom: -textInsets.bottom,
                                          right: -textInsets.right)
        return UIEdgeInsetsInsetRect(textRect, invertedInsets)
    }

    override func drawText(in rect: CGRect) {
        super.drawText(in: UIEdgeInsetsInsetRect(rect, textInsets))
    }
}

И я вызываю его так:

func setPubTypeBadge(publication: PublicationModel, indexPathRow: Int) {
    if let pubType = publication.publicationType,
        let pubEnum = PublicationType(rawValue: pubType) {
        pubTypeBadge.attributedText = pubEnum.getBadgeLabel(using: pubType)
    }

    let rect = pubTypeBadge.textRect(forBounds: pubTypeBadge.frame, limitedToNumberOfLines: 1)
    pubTypeBadge.drawText(in: rect)
    pubTypeBadge.layer.borderColor = UIColor.dsShade3.cgColor
    pubTypeBadge.layer.borderWidth = 1
    pubTypeBadge.layer.cornerRadius = 4
}

который абсолютно ничего не делает в отношении отступов/вставок. Мне просто нужно 6 пт слева/справа между текстом и границей и 4 пт сверху/снизу. Любая помощь очень ценится.


person Jim    schedule 14.11.2018    source источник


Ответы (2)


Приведенный ниже код делает то, что вы хотите (создайте новую игровую площадку LiveView и вставьте ее).

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

импорт UIKit импорт PlaygroundSupport

class MyViewController : UIViewController {
    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white

        let label = BorderedLabel()
        label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
        label.text = "Hello World!"
        label.textColor = .black
        // Border settings
        label.layer.cornerRadius = 4 
        label.layer.borderColor = UIColor.black.cgColor
        label.layer.borderWidth = 1
        label.sizeToFit() // Important

        view.addSubview(label)
        self.view = view
    }
}

class BorderedLabel: UILabel {
    var sidePadding = CGFloat(10) // Needed padding, add property observers

    override func sizeToFit() {
        super.sizeToFit()
        bounds.size.width += 2 * sidePadding
    }

    override func drawText(in rect: CGRect) {
        print(rect)
        super.drawText(in: rect.insetBy(dx: sidePadding, dy: 0))
        invalidateIntrinsicContentSize()
    }
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

Однако вы можете поиграть с этим решением и протестировать его или улучшить удобство и надежность (наряду с поддержкой Auto Layout).

person fewlinesofcode    schedule 14.11.2018
comment
Спасибо, @fewlinesofcode. Это, на самом деле, работает отлично. Мой UILabel находится на раскадровке, связанной с моим пользовательским классом, и имеет ограничения. Это то, что вы имеете в виду, говоря «поместить его в контейнер»? - person Jim; 14.11.2018
comment
Поместив в контейнер, я имел в виду обернуть его UIView. Но если это решение работает для вас - хорошо =) - person fewlinesofcode; 14.11.2018

Вы можете просто добавить пустое пространство до и после текста:

titleLabel.text = "\(itemName)"

person fullmoon    schedule 16.02.2020