Don_Mag

For Matt

Oct 21st, 2020 (edited)
679
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2.  
  3. import UIKit
  4.  
  5. class AutoSizingStringDrawer: UIView {
  6.     @NSCopying var attributedText = NSAttributedString() {
  7.         didSet {
  8.             self.setNeedsDisplay()
  9.             self.invalidateIntrinsicContentSize()
  10.         }
  11.     }
  12.    
  13.     override func draw(_ rect: CGRect) {
  14.         self.attributedText.draw(with: rect, options: [.truncatesLastVisibleLine, .usesLineFragmentOrigin], context: nil)
  15.     }
  16.    
  17.     override var intrinsicContentSize: CGSize {
  18.         let measuredSize = self.attributedText.boundingRect(
  19.             with: CGSize(width:self.bounds.width, height:10000),
  20.             options: [.truncatesLastVisibleLine, .usesLineFragmentOrigin],
  21.             context: nil).size
  22.         print("Drawer intrinsicContentSize:", measuredSize, "bounds:", bounds.size)
  23.         return CGSize(width: UIView.noIntrinsicMetric, height: measuredSize.height.rounded(.up) + 5)
  24.     }
  25.    
  26.     var currentWidth: CGFloat = 0.0
  27.     override func layoutSubviews() {
  28.         super.layoutSubviews()
  29.         if currentWidth != bounds.width {
  30.             currentWidth = bounds.width
  31.             self.invalidateIntrinsicContentSize()
  32.         }
  33.         print("Drawer layoutSubviews bounds.size", bounds.size)
  34.     }
  35.    
  36. }
  37.  
  38. class MyLabel: UILabel {
  39.    
  40.     override var intrinsicContentSize: CGSize {
  41.         let sz = super.intrinsicContentSize
  42.         print("MyLabel intrinsicContentSize:", sz, "bounds:", bounds.size)
  43.         return sz
  44.     }
  45.    
  46.     override func layoutSubviews() {
  47.         super.layoutSubviews()
  48.         print("MyLabel layoutSubviews bounds.size:", bounds.size)
  49.     }
  50.  
  51. }
  52.  
  53. class StringDrawer: UIView {
  54.     @NSCopying var attributedText = NSAttributedString() {
  55.         didSet {
  56.             self.setNeedsDisplay()
  57.             self.invalidateIntrinsicContentSize()
  58.         }
  59.     }
  60.    
  61.     override func draw(_ rect: CGRect) {
  62.         self.attributedText.draw(with: rect, options: [.truncatesLastVisibleLine, .usesLineFragmentOrigin], context: nil)
  63.     }
  64.    
  65.     override var intrinsicContentSize: CGSize {
  66.         let measuredSize = self.attributedText.boundingRect(
  67.             with: CGSize(width:self.bounds.width, height:10000),
  68.             options: [.truncatesLastVisibleLine, .usesLineFragmentOrigin],
  69.             context: nil).size
  70.         print("Drawer intrinsicContentSize:", measuredSize, "bounds:", bounds.size)
  71.         return CGSize(width: UIView.noIntrinsicMetric, height: measuredSize.height.rounded(.up) + 5)
  72.     }
  73.    
  74.     override func layoutSubviews() {
  75.         super.layoutSubviews()
  76.         print("Drawer layoutSubviews bounds.size", bounds.size)
  77.     }
  78.    
  79. }
  80.  
  81. class TestViewController: UIViewController {
  82.    
  83.     let testDrawer: StringDrawer = StringDrawer()
  84.     let testLabel: MyLabel = MyLabel()
  85.    
  86.     let testString = "enough text to cause word wrapping to test the intrinsic content size issue."
  87.    
  88.     override func viewDidLoad() {
  89.         super.viewDidLoad()
  90.        
  91.         view.backgroundColor = .yellow
  92.        
  93.         [testDrawer, testLabel].forEach { v in
  94.             v.translatesAutoresizingMaskIntoConstraints = false
  95.             view.addSubview(v)
  96.         }
  97.        
  98.         let g = view.safeAreaLayoutGuide
  99.        
  100.         NSLayoutConstraint.activate([
  101.             testDrawer.topAnchor.constraint(equalTo: g.topAnchor, constant: 100.0),
  102.             testDrawer.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
  103.             testDrawer.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
  104.            
  105.             testLabel.topAnchor.constraint(equalTo: g.topAnchor, constant: 200.0),
  106.             testLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
  107.             testLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
  108.         ])
  109.        
  110.         testDrawer.backgroundColor = .cyan
  111.        
  112.         testLabel.backgroundColor = .green
  113.         testLabel.numberOfLines = 0
  114.        
  115.         let drawerString = NSAttributedString(string: "Drawer: " + testString, attributes: [
  116.             .foregroundColor : UIColor.darkText,
  117.             .font : UIFont(name: "Helvetica", size: 14)!
  118.         ])
  119.        
  120.         let labelString = NSAttributedString(string: "Label: " + testString, attributes: [
  121.             .foregroundColor : UIColor.darkText,
  122.             .font : UIFont(name: "Helvetica", size: 14)!
  123.         ])
  124.        
  125.         testDrawer.attributedText = drawerString
  126.         testLabel.attributedText = labelString
  127.        
  128.     }
  129.    
  130. }
  131.  
  132. /*
  133. Console output with iPhone 8 / 14.0 / Simulator
  134.  
  135. Drawer intrinsicContentSize: (513.59765625, 16.1) bounds: (0.0, 0.0)
  136. MyLabel intrinsicContentSize: (65536.0, 16.5) bounds: (0.0, 0.0)
  137. MyLabel intrinsicContentSize: (65536.0, 16.5) bounds: (0.0, 0.0)
  138. MyLabel intrinsicContentSize: (335.0, 32.5) bounds: (0.0, 0.0)
  139. MyLabel intrinsicContentSize: (65536.0, 16.5) bounds: (0.0, 0.0)
  140. MyLabel intrinsicContentSize: (335.0, 32.5) bounds: (0.0, 0.0)
  141. MyLabel layoutSubviews bounds.size: (335.0, 32.5)
  142. MyLabel layoutSubviews bounds.size: (335.0, 32.5)
  143. Drawer layoutSubviews bounds.size (335.0, 22.0)
  144.  
  145. */
  146.  
RAW Paste Data