//
import UIKit
class AutoSizingStringDrawer: UIView {
@NSCopying var attributedText = NSAttributedString() {
didSet {
self.setNeedsDisplay()
self.invalidateIntrinsicContentSize()
}
}
override func draw(_ rect: CGRect) {
self.attributedText.draw(with: rect, options: [.truncatesLastVisibleLine, .usesLineFragmentOrigin], context: nil)
}
override var intrinsicContentSize: CGSize {
let measuredSize = self.attributedText.boundingRect(
with: CGSize(width:self.bounds.width, height:10000),
options: [.truncatesLastVisibleLine, .usesLineFragmentOrigin],
context: nil).size
print("Drawer intrinsicContentSize:", measuredSize, "bounds:", bounds.size)
return CGSize(width: UIView.noIntrinsicMetric, height: measuredSize.height.rounded(.up) + 5)
}
var currentWidth: CGFloat = 0.0
override func layoutSubviews() {
super.layoutSubviews()
if currentWidth != bounds.width {
currentWidth = bounds.width
self.invalidateIntrinsicContentSize()
}
print("Drawer layoutSubviews bounds.size", bounds.size)
}
}
class MyLabel: UILabel {
override var intrinsicContentSize: CGSize {
let sz = super.intrinsicContentSize
print("MyLabel intrinsicContentSize:", sz, "bounds:", bounds.size)
return sz
}
override func layoutSubviews() {
super.layoutSubviews()
print("MyLabel layoutSubviews bounds.size:", bounds.size)
}
}
class StringDrawer: UIView {
@NSCopying var attributedText = NSAttributedString() {
didSet {
self.setNeedsDisplay()
self.invalidateIntrinsicContentSize()
}
}
override func draw(_ rect: CGRect) {
self.attributedText.draw(with: rect, options: [.truncatesLastVisibleLine, .usesLineFragmentOrigin], context: nil)
}
override var intrinsicContentSize: CGSize {
let measuredSize = self.attributedText.boundingRect(
with: CGSize(width:self.bounds.width, height:10000),
options: [.truncatesLastVisibleLine, .usesLineFragmentOrigin],
context: nil).size
print("Drawer intrinsicContentSize:", measuredSize, "bounds:", bounds.size)
return CGSize(width: UIView.noIntrinsicMetric, height: measuredSize.height.rounded(.up) + 5)
}
override func layoutSubviews() {
super.layoutSubviews()
print("Drawer layoutSubviews bounds.size", bounds.size)
}
}
class TestViewController: UIViewController {
let testDrawer: StringDrawer = StringDrawer()
let testLabel: MyLabel = MyLabel()
let testString = "enough text to cause word wrapping to test the intrinsic content size issue."
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .yellow
[testDrawer, testLabel].forEach { v in
v.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(v)
}
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
testDrawer.topAnchor.constraint(equalTo: g.topAnchor, constant: 100.0),
testDrawer.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
testDrawer.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
testLabel.topAnchor.constraint(equalTo: g.topAnchor, constant: 200.0),
testLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
testLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
])
testDrawer.backgroundColor = .cyan
testLabel.backgroundColor = .green
testLabel.numberOfLines = 0
let drawerString = NSAttributedString(string: "Drawer: " + testString, attributes: [
.foregroundColor : UIColor.darkText,
.font : UIFont(name: "Helvetica", size: 14)!
])
let labelString = NSAttributedString(string: "Label: " + testString, attributes: [
.foregroundColor : UIColor.darkText,
.font : UIFont(name: "Helvetica", size: 14)!
])
testDrawer.attributedText = drawerString
testLabel.attributedText = labelString
}
}
/*
Console output with iPhone 8 / 14.0 / Simulator
Drawer intrinsicContentSize: (513.59765625, 16.1) bounds: (0.0, 0.0)
MyLabel intrinsicContentSize: (65536.0, 16.5) bounds: (0.0, 0.0)
MyLabel intrinsicContentSize: (65536.0, 16.5) bounds: (0.0, 0.0)
MyLabel intrinsicContentSize: (335.0, 32.5) bounds: (0.0, 0.0)
MyLabel intrinsicContentSize: (65536.0, 16.5) bounds: (0.0, 0.0)
MyLabel intrinsicContentSize: (335.0, 32.5) bounds: (0.0, 0.0)
MyLabel layoutSubviews bounds.size: (335.0, 32.5)
MyLabel layoutSubviews bounds.size: (335.0, 32.5)
Drawer layoutSubviews bounds.size (335.0, 22.0)
*/
Comments
0 B
|👍
/👎