IOS UIView -Unterklasse wird das alte falsche Rekt in Zeichnung (_ RECT: CGRECT) trotz der korrekten Größe in Intrinsicc
Posted: 19 May 2025, 01:12
Ich versuche, mein eigenes benutzerdefiniertes Etikett als Unterklasse von UIView zu erstellen :
Ich platziere es in einem UitableViewCell :
Dies macht meine volle Ansicht jedoch nicht:
Code: Select all
import UIKit
class MyLabel: UIView {
private var preferredMaxLayoutWidth: CGFloat? = nil
var attributedText : NSAttributedString? {
didSet{
setupTextKit()
preferredMaxLayoutWidth = nil
invalidateIntrinsicContentSize()
setNeedsDisplay()
}
}
private let layoutManager = NSLayoutManager()
private let textContainer = NSTextContainer(size: .zero)
private var textStorage : NSTextStorage?
override func draw(_ rect: CGRect) {
super.draw(rect)
print("draw!!! rect: \(rect), preferredMaxLayoutWidth: \(preferredMaxLayoutWidth)")
guard let attributedText = attributedText, attributedText.length > 0 else {
return
}
attributedText.draw(with: bounds, options: [.usesLineFragmentOrigin], context: nil)
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit(){
contentMode = .redraw
backgroundColor = .red.withAlphaComponent(0.2)
textContainer.lineFragmentPadding = 0
textContainer.maximumNumberOfLines = 0 // 0 means no limit
textContainer.lineBreakMode = .byWordWrapping
textContainer.layoutManager = layoutManager
layoutManager.addTextContainer(textContainer)
}
private func setupTextKit() {
textStorage?.removeLayoutManager(layoutManager)
if let attributedText = attributedText {
textStorage = NSTextStorage(attributedString: attributedText)
textStorage?.addLayoutManager(layoutManager)
layoutManager.textStorage = textStorage
} else {
textStorage = nil
}
}
override func layoutSubviews() {
super.layoutSubviews()
print("layoutSubviews: \(bounds.size), \(preferredMaxLayoutWidth)")
if preferredMaxLayoutWidth != bounds.width {
print("preferredMaxLayoutWidth is different from bounds.width")
preferredMaxLayoutWidth = bounds.width
invalidateIntrinsicContentSize()
setNeedsDisplay()
} else {
print("preferredMaxLayoutWidth is same as bounds.width")
}
}
override var intrinsicContentSize: CGSize {
guard let currentTextStorage = textStorage, currentTextStorage.length > 0 else {
return .zero
}
var calculationWidth: CGFloat
if let pMLW = preferredMaxLayoutWidth {
calculationWidth = pMLW
} else {
calculationWidth = CGFloat.greatestFiniteMagnitude
}
print("preferredMaxLayoutWidth: \(preferredMaxLayoutWidth), calculationWidth: \(calculationWidth)")
textContainer.size = CGSize(width: calculationWidth, height: CGFloat.greatestFiniteMagnitude)
layoutManager.ensureLayout(for: textContainer)
let usedRect = layoutManager.usedRect(for: textContainer)
print("usedRect: \(usedRect)")
return usedRect.size
}
}
Code: Select all
import UIKit
import SnapKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let tableView = UITableView(frame: .zero, style: .plain)
let records = ["Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. "]
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(Cell.self, forCellReuseIdentifier: "Cell")
view.addSubview(tableView)
tableView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
tableView.dataSource = self
tableView.delegate = self
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
records.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! Cell
cell.label.attributedText = NSAttributedString(string: records[indexPath.row], attributes: [.foregroundColor: UIColor.label, .font: UIFont.systemFont(ofSize: 18)])
return cell
}
}
class Cell: UITableViewCell {
let label = MyLabel()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(label)
label.snp.makeConstraints { make in
make.edges.equalToSuperview().inset(10)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}