[ios] Swift의 String을 기반으로 UILabel의 크기 파악
다른 문자열 길이를 기반으로 UILabel의 높이를 계산하려고합니다.
func calculateContentHeight() -> CGFloat{
var maxLabelSize: CGSize = CGSizeMake(frame.size.width - 48, CGFloat(9999))
var contentNSString = contentText as NSString
var expectedLabelSize = contentNSString.boundingRectWithSize(maxLabelSize, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont.systemFontOfSize(16.0)], context: nil)
print("\(expectedLabelSize)")
return expectedLabelSize.size.height
}
위는 높이를 결정하는 데 사용하는 현재 기능이지만 작동하지 않습니다. 도움을 주시면 감사하겠습니다. Objective C가 아닌 Swift에서 답을 제시합니다.
답변
확장명을 사용하십시오. String
스위프트 3
extension String {
func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
return ceil(boundingBox.height)
}
func width(withConstrainedHeight height: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
return ceil(boundingBox.width)
}
}
그리고 또한 NSAttributedString
(때때로 매우 유용합니다)
extension NSAttributedString {
func height(withConstrainedWidth width: CGFloat) -> CGFloat {
let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
let boundingBox = boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, context: nil)
return ceil(boundingBox.height)
}
func width(withConstrainedHeight height: CGFloat) -> CGFloat {
let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
let boundingBox = boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, context: nil)
return ceil(boundingBox.width)
}
}
스위프트 4
메소드 attributes
에서 값을 변경하십시오.extension String
…에서
[NSFontAttributeName: font]
에
[.font : font]
답변
여러 줄로 된 텍스트의 경우이 답변이 제대로 작동하지 않습니다. UILabel을 사용하여 다른 문자열 확장을 작성할 수 있습니다
extension String {
func height(constraintedWidth width: CGFloat, font: UIFont) -> CGFloat {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: .greatestFiniteMagnitude))
label.numberOfLines = 0
label.text = self
label.font = font
label.sizeToFit()
return label.frame.height
}
}
UILabel은 고정 너비를 가져오고 .numberOfLines는 0으로 설정됩니다. 텍스트를 추가하고 .sizeToFit ()를 호출하면 자동으로 올바른 높이로 조정됩니다.
코드는 Swift 3으로 작성되었습니다.
답변
여기 나를 위해 일하는 간단한 해결책이 있습니다 … 다른 다른 게시물과 비슷하지만 전화 할 필요는 포함되어 있지 않습니다. sizeToFit
이것은 Swift 5로 작성되었습니다.
let lbl = UILabel()
lbl.numberOfLines = 0
lbl.font = UIFont.systemFont(ofSize: 12) // make sure you set this correctly
lbl.text = "My text that may or may not wrap lines..."
let width = 100.0 // the width of the view you are constraint to, keep in mind any applied margins here
let height = lbl.systemLayoutSizeFitting(CGSize(width: width, height: UIView.layoutFittingCompressedSize.height), withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel).height
줄 바꿈 등을 처리합니다. 가장 우아한 코드는 아니지만 작업이 완료됩니다.
답변
extension String{
func widthWithConstrainedHeight(_ height: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: CGFloat.greatestFiniteMagnitude, height: height)
let boundingBox = self.boundingRect(with: constraintRect, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
return ceil(boundingBox.width)
}
func heightWithConstrainedWidth(_ width: CGFloat, font: UIFont) -> CGFloat? {
let constraintRect = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
return ceil(boundingBox.height)
}
}
답변
이것은 Swift 4.1 및 Xcode 9.4.1의 대답입니다.
//This is your label
let proNameLbl = UILabel(frame: CGRect(x: 0, y: 20, width: 300, height: height))
proNameLbl.text = "This is your text"
proNameLbl.font = UIFont.systemFont(ofSize: 17)
proNameLbl.numberOfLines = 0
proNameLbl.lineBreakMode = .byWordWrapping
infoView.addSubview(proNameLbl)
//Function to calculate height for label based on text
func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat {
let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.byWordWrapping
label.font = font
label.text = text
label.sizeToFit()
return label.frame.height
}
이제이 함수를 호출합니다
//Call this function
let height = heightForView(text: "This is your text", font: UIFont.systemFont(ofSize: 17), width: 300)
print(height)//Output : 41.0
답변
허용 된 답변은 고정 너비가 아니라 고정 된 높이에서 작동한다는 것을 알았습니다. 고정 높이의 경우 텍스트에 줄 바꿈이 없으면 너비를 한 줄에 모두 맞추십시오.
너비 함수는 높이 함수를 여러 번 호출하지만 빠른 계산이며 UITable 행의 함수를 사용하여 성능 문제를 발견하지 못했습니다.
extension String {
public func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [.font : font], context: nil)
return ceil(boundingBox.height)
}
public func width(withConstrainedHeight height: CGFloat, font: UIFont, minimumTextWrapWidth:CGFloat) -> CGFloat {
var textWidth:CGFloat = minimumTextWrapWidth
let incrementWidth:CGFloat = minimumTextWrapWidth * 0.1
var textHeight:CGFloat = self.height(withConstrainedWidth: textWidth, font: font)
//Increase width by 10% of minimumTextWrapWidth until minimum width found that makes the text fit within the specified height
while textHeight > height {
textWidth += incrementWidth
textHeight = self.height(withConstrainedWidth: textWidth, font: font)
}
return ceil(textWidth)
}
}
답변
레이블 텍스트 높이를 확인하고 작업 중입니다.
let labelTextSize = ((labelDescription.text)! as NSString).boundingRect(
with: CGSize(width: labelDescription.frame.width, height: .greatestFiniteMagnitude),
options: .usesLineFragmentOrigin,
attributes: [.font: labelDescription.font],
context: nil).size
if labelTextSize.height > labelDescription.bounds.height {
viewMoreOrLess.hide(byHeight: false)
viewLess.hide(byHeight: false)
}
else {
viewMoreOrLess.hide(byHeight: true)
viewLess.hide(byHeight: true)
}