삽입물을 수용하도록 UILabel 크기 조정
바코드를 스캔하는 화면을 만들고 있으며 UILabels
밝은 배경에 대한 가시성을 높이기 위해 일부 뒤에 반투명 화면을 배치해야합니다 .
이제 화면은 다음과 같습니다.
UILabel
반투명 상자를 얻기 위해의 배경색을 설정하고 있습니다. 또한 이 접근 방식을 사용하여 UILabel
의 가장자리 UILabel
와 텍스트 사이에 패딩을 설정할 수 있도록 사용자 지정 하위 클래스를 만들었습니다 .
위의 화면에서 볼 수 있듯이 UILabel
패딩을 고려하여의 크기가 올바르게 조정되지 않습니다. "패딩"은 레이블의 너비를 변경하지 않고 텍스트를 이동하여 텍스트가 잘 리도록합니다.
이 두 레이블 모두 임의 길이의 텍스트를 포함 UILabel
하며 동적으로 크기를 조정하려면 이 필요합니다 .
UILabel
레이블의 너비를 늘리고 패딩을 고려하려면 어떤 방법을 재정의 할 수 있습니까?
다음은 크기를 올바르게 계산하는 레이블 클래스입니다. 게시 된 코드는 스위프트 3,하지만 당신은 또한 다운로드 할 수 있습니다 스위프트 2 또는 목표 - C 버전.
어떻게 작동합니까?
적절한 textRect를 계산하면 모든 sizeToFit
자동 레이아웃 항목이 예상대로 작동합니다. 트릭은 먼저 삽입을 뺀 다음 원래 레이블 경계를 계산하고 마지막으로 삽입을 다시 추가하는 것입니다.
암호
class NRLabel : 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))
}
}
선택 사항 : 인터페이스 빌더 지원
스토리 보드에서 텍스트 삽입을 설정하려면 다음 확장을 사용하여 Interface Builder 지원을 활성화 할 수 있습니다.
@IBDesignable
extension NRLabel {
// currently UIEdgeInsets is no supported IBDesignable type,
// so we have to fan it out here:
@IBInspectable
var leftTextInset: CGFloat {
set { textInsets.left = newValue }
get { return textInsets.left }
}
// Same for the right, top and bottom edges.
}
이제 IB에서 편리하게 삽입을 설정 한 다음 ⌘ =를 눌러 레이블 크기를 맞출 수 있습니다.
부인 성명:
모든 코드는 공개 도메인에 있습니다. 원하는대로하십시오.
다음은 UILabel 텍스트 주위에 추가 패딩을 만드는 UILabel 하위 클래스의 Swift 버전입니다 (@Nikolai의 답변과 동일).
class EdgeInsetLabel : UILabel {
var edgeInsets:UIEdgeInsets = UIEdgeInsetsZero
override func textRectForBounds(bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
var rect = super.textRectForBounds(UIEdgeInsetsInsetRect(bounds, edgeInsets), limitedToNumberOfLines: numberOfLines)
rect.origin.x -= edgeInsets.left
rect.origin.y -= edgeInsets.top
rect.size.width += (edgeInsets.left + edgeInsets.right);
rect.size.height += (edgeInsets.top + edgeInsets.bottom);
return rect
}
override func drawTextInRect(rect: CGRect) {
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, edgeInsets))
}
}
Nikolai의 코드를 기반으로 한 C # 버전 (Xamarin에 유용함)은 다음과 같습니다.
public class UIEdgeableLabel : UILabel
{
public UIEdgeableLabel() : base() { }
public UIEdgeableLabel(NSCoder coder) : base(coder) { }
public UIEdgeableLabel(CGRect frame) : base(frame) { }
protected UIEdgeableLabel(NSObjectFlag t) : base(t) { }
private UIEdgeInsets _edgeInset = UIEdgeInsets.Zero;
public UIEdgeInsets EdgeInsets
{
get { return _edgeInset; }
set
{
_edgeInset = value;
this.InvalidateIntrinsicContentSize();
}
}
public override CGRect TextRectForBounds(CGRect bounds, nint numberOfLines)
{
var rect = base.TextRectForBounds(EdgeInsets.InsetRect(bounds), numberOfLines);
return new CGRect(x: rect.X - EdgeInsets.Left,
y: rect.Y - EdgeInsets.Top,
width: rect.Width + EdgeInsets.Left + EdgeInsets.Right,
height: rect.Height + EdgeInsets.Top + EdgeInsets.Bottom);
}
public override void DrawText(CGRect rect)
{
base.DrawText(this.EdgeInsets.InsetRect(rect));
}
}
Nikolai Ruhe의 Swift 5 버전 답변 :
extension UIEdgeInsets {
func apply(_ rect: CGRect) -> CGRect {
return rect.inset(by: self)
}
}
class EdgeInsetLabel: UILabel {
var textInsets = UIEdgeInsets.zero {
didSet { invalidateIntrinsicContentSize() }
}
override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
let insetRect = bounds.inset(by: 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 textRect.inset(by: invertedInsets)
}
override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: textInsets))
}}
Nikolai Ruhe 의 답변 외에도 크기 변경을 올바르게 다시 계산하려면 자동 레이아웃에 대한 고유 콘텐츠 크기를 무효화해야합니다. 응용 프로그램 수명주기 동안 edgeInsets를 변경하면이 문제를 알 수 있습니다.
class NRLabel: UILabel {
var edgeInsets = UIEdgeInsetsZero {
didSet {
self.invalidateIntrinsicContentSize()
}
}
...
}
Here is an example of what I used for a simple 10 unit padding on the left and right of the label with rounded corners. Just set the label text to center it's self and make it's class IndentedLabel and the rest takes care of itself. To modify the padding just scale up or down rect.size.width += (x)
class IndentedLabel: UILabel {
var edgeInsets:UIEdgeInsets = UIEdgeInsetsZero
override func textRectForBounds(bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
var rect = super.textRectForBounds(UIEdgeInsetsInsetRect(bounds, edgeInsets), limitedToNumberOfLines: numberOfLines)
rect.size.width += 20;
return rect
}
override func drawTextInRect(rect: CGRect) {
self.clipsToBounds = true
self.layer.cornerRadius = 3
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, edgeInsets))
}
}
Here's a quick, hacky way to do it that you can understand more quickly. It's not as robust as Nikolai's, but it gets the job done. I did this when I was trying to fit my text in my UILabel within a UITableViewCell:
- Set a width constraint for the UILabel
- Connect the constraint via IBOutlet onto your code, either VC (custom cell class if you're doing an expanding table view cell)
- Create a variable for the actual size of the text, then add the insets + the width size to the constraint and update the view:
let messageTextSize: CGSize = (messageText as NSString).sizeWithAttributes([ NSFontAttributeName: UIFont.systemFontOfSize(14.0)]) cell.widthConstraint.constant = messageTextSize.width + myInsetsOrWhatever
아직 광범위하게 테스트하지 않았으므로 추가 한 정확한 CGFloat 값을 가지고 놀아야 할 수도 있습니다. 올바른 크기가 정확히 너비와 삽입물이 아니라는 것을 알았습니다. 그것보다 조금 더 큽니다. 이렇게하면 UILabel의 너비가 항상 최소한 텍스트 크기 이상이됩니다.
참고 URL : https://stackoverflow.com/questions/21167226/resizing-a-uilabel-to-accommodate-insets
'developer tip' 카테고리의 다른 글
UITableViewCell 선택된 행의 텍스트 색상 변경 (0) | 2020.11.29 |
---|---|
Chart.js-Y 축 서식 지정 (0) | 2020.11.29 |
Dock 아이콘을 숨기는 방법 (0) | 2020.11.29 |
jQuery UI 자동 완성-마우스를 올리면 메뉴가 사라집니다. (0) | 2020.11.29 |
/ in vi 검색 및 바꾸기? (0) | 2020.11.29 |