如何让UITextView根据文字的长度进行调整?

How to make UITextView adjust according to the length of text?

我有一个 ViewController,它有四个 UITextView 和四个 UILabel。我有他们每个人的文字,他们在一个数组中。我试图使 UITextViews 和 UILabels 彼此之间的距离相等,无论字段的长度如何。每次我尝试对 ViewController 应用约束时,它都会弄乱上面的所有内容(标签、文本视图等)。 ViewController 有滚动视图。下面是截图和代码:

import UIKit

class DetailViewController: UIViewController {

    var name = ""
    var img: UIImage?
    var desc = ""
    var healingProp = ""
    var spiritualProp = ""
    var emotionalProp = ""
    
    @IBOutlet weak var detailCrystalPhotoImageView: UIImageView!
   // about the crystal
    @IBOutlet weak var crystalDescriptionTextView: UITextView!
    @IBOutlet weak var backgroundInfoLabel: UILabel!
    // healing properties
    @IBOutlet weak var healingPropertiesLabel: UILabel!
    @IBOutlet weak var healingPropertiesInfoTextView: UITextView!
    @IBOutlet weak var scrollView: UIScrollView!
   // spiritual properties
    @IBOutlet weak var spiritualPropertiesLabel: UILabel!
    @IBOutlet weak var spiritualPropertiesInfoTextView: UITextView!
    // emotional properties
    @IBOutlet weak var emotionalPropertiesLabel: UILabel!
    @IBOutlet weak var emotionalPropertiesInfoTextView: UITextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // sets up scroll view
        scrollView.contentSize = CGSize(width: self.view.frame.width, height: self.view.frame.height+1000)
        
        // displays crystal title and crystal image
        title = name
        detailCrystalPhotoImageView.image = img
        
        // display background label and text
        backgroundInfoLabel.text = String("About " + name + " ℹ️")
        backgroundInfoLabel.font = UIFont.systemFont(ofSize: 24, weight: .light)
       
        // sets up crystal summary
        crystalDescriptionTextView.text = desc
        crystalDescriptionTextView.font = UIFont.systemFont(ofSize: 18, weight: .thin)
        
        // display healing properties label and text
        healingPropertiesLabel.text = String("Healing Properties ")
        healingPropertiesLabel.font = UIFont.systemFont(ofSize: 24, weight: .light)
        healingPropertiesInfoTextView.text = healingProp
        healingPropertiesInfoTextView.font = UIFont.systemFont(ofSize: 18, weight: .thin)
        healingPropertiesInfoTextView.sizeToFit()
        
        // display spiritual properties label and text
        spiritualPropertiesLabel.text = String("Spiritual Properties ️")
        spiritualPropertiesLabel.font = UIFont.systemFont(ofSize: 24, weight: .light)
        spiritualPropertiesInfoTextView.text = spiritualProp
        spiritualPropertiesInfoTextView.font = UIFont.systemFont(ofSize: 18, weight: .thin)
        
        //display emotional properties label and text
        emotionalPropertiesLabel.text = String("Emotional Properties ")
        emotionalPropertiesLabel.font = UIFont.systemFont(ofSize: 24, weight: .light)
        emotionalPropertiesInfoTextView.text = emotionalProp
        emotionalPropertiesInfoTextView.font = UIFont.systemFont(ofSize: 18, weight: .thin)
        
        
    }
}

子类是实现调整大小以适应特性的方法:

class DTextView: UITextView {

    @IBInspectable var maxHeight: CGFloat = 0
    @IBInspectable var enableAutoResizeToFitContent: Bool = false

    override func awakeFromNib() {
        super.awakeFromNib()
        
        NotificationCenter.default.addObserver(self, selector: #selector(DTextView.didChangeText(_:)), name:UITextView.textDidChangeNotification, object: self)
    }

    @objc func didChangeText(_ note: Notification) {
        // needed incase isScrollEnabled is set to true which stops automatically calling invalidateIntrinsicContentSize()
        invalidateIntrinsicContentSize()
    }

    override var intrinsicContentSize: CGSize {
        var size = super.intrinsicContentSize
        
        if size.height == UIView.noIntrinsicMetric {
            // force layout
            layoutManager.glyphRange(for: textContainer)
            size.height = layoutManager.usedRect(for: textContainer).height + textContainerInset.top + textContainerInset.bottom
        }
        
        if !enableAutoResizeToFitContent {
            if !isScrollEnabled {
                isScrollEnabled = true
            }
        } else {
            if maxHeight > 0.0 && size.height > maxHeight {
                size.height = maxHeight
            
                if !isScrollEnabled {
                    isScrollEnabled = true
                }
            } else if isScrollEnabled {
                isScrollEnabled = false
            }
        }
        
        return size
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

如果您将 maxHeight 属性 设置为 ZeroTextView 将自动调整大小以适应内容大小。

已应用约束:

  1. Greater or equal height constraint. (Minimum height: could be zero).
  2. Height constraint with a priority lower than the Content Hugging Priority.

两个约束应具有相同的常量值(请调查)