如何动态调整 UITextView 的高度

Posted

技术标签:

【中文标题】如何动态调整 UITextView 的高度【英文标题】:How to dynamically adjust height of UITextView 【发布时间】:2016-07-30 22:59:09 【问题描述】:

所以我知道有几个类似我的帖子,但不是我想要的。所以这就是我想要完成的事情。我有一个看起来像这样的 ViewController。

当用户在UITextView 中输入文本时,当前有文本“描述”,我想动态更改UITextView 的高度,所以如果文本变成多行或离开屏幕用户可以滚动浏览整个视图及其内容。这是我的程序。

@IBOutlet var scrollView: UIScrollView!
var projectNameTextField: UITextField!
var projectCategoryLabel: UIButton!
var dueDateLabel: UIButton!
var projectDescription: UITextView!
var projectDescriptionFrame: CGRect!

override func viewDidAppear(animated: Bool) 
    super.viewDidAppear(animated)

    let scrollViewWidth = scrollView.frame.width
    scrollView.contentSize.width = scrollViewWidth

    let trallingSpace: CGFloat = 12.0
    let contentWidth = scrollViewWidth - (trallingSpace * 2.0)

    projectNameTextField = UITextField(frame: CGRect(x: trallingSpace, y: scrollViewContentHeight(), width: contentWidth, height: 40))
    projectNameTextField.placeholder = "Title"
    updateScrollView(withView: projectNameTextField)


    let categoryLabel = UILabel()
    categoryLabel.text = "Category"

    projectCategoryLabel = UIButton()
    projectCategoryLabel.setTitle("Art", forState: .Normal)
    projectCategoryLabel.setTitleColor(UIColor.blackColor(), forState: .Normal)

    let stackViewHCategory = UIStackView(frame: CGRect(x: trallingSpace, y: scrollViewContentHeight(), width: contentWidth, height: 40))
    stackViewHCategory.axis = .Horizontal
    stackViewHCategory.spacing = 8
    stackViewHCategory.addArrangedSubview(categoryLabel)
    stackViewHCategory.addArrangedSubview(projectCategoryLabel)
    updateScrollView(withView: stackViewHCategory)


    let dueDateTitle = UILabel()
    dueDateTitle.text = "Due Date"

    dueDateLabel = UIButton()
    dueDateLabel.setTitle("No Due Date", forState: .Normal)
    dueDateLabel.setTitleColor(UIColor.blackColor(), forState: .Normal)

    let stackViewHDueDate = UIStackView(frame: CGRect(x: trallingSpace, y: scrollViewContentHeight(), width: contentWidth, height: 40))
    stackViewHDueDate.axis = .Horizontal
    stackViewHDueDate.spacing = 8
    stackViewHDueDate.addArrangedSubview(dueDateTitle)
    stackViewHDueDate.addArrangedSubview(dueDateLabel)
    updateScrollView(withView: stackViewHDueDate)


    projectDescription = UITextView(frame: CGRect(x: trallingSpace, y: scrollViewContentHeight(), width: contentWidth, height: 40))
    projectDescription.text = "Description"

    projectDescription.delegate = self

    projectDescription.scrollEnabled = false
    projectDescription.font = projectDescription.font?.fontWithSize(14)

    updateScrollView(withView: projectDescription)

    projectDescriptionFrame = projectDescription.frame
    projectDescriptionFrame.size.height = projectDescription.contentSize.height
    projectDescription.frame = projectDescriptionFrame


func textViewDidChange(textView: UITextView) 

    projectDescriptionFrame.size.height = projectDescription.contentSize.height
    projectDescription.frame = projectDescriptionFrame

    var contentSizeheight = CGFloat()

    for (index, viewInScrollView) in scrollView.subviews.enumerate() 
        if index > 1 
            contentSizeheight += viewInScrollView.frame.height
        
    

    scrollView.contentSize.height = contentSizeheight



func updateScrollView(withView withView: UIView) 
    scrollView.addSubview(withView)
    scrollView.contentSize.height += withView.frame.height


func scrollViewContentHeight() -> CGFloat 

    var height = CGFloat()

    for (index, viewInScrollView) in scrollView.subviews.enumerate() 
        if index > 1 
            height += viewInScrollView.frame.height
        
    

    return height

我该怎么做才能调整UITextView 框架并更新UIScrollView.contentSize(不是UITextView),这样用户就可以滚动整个视图。我会说我想要一个 UI,就像你在 ios 邮件应用程序中发送新消息时一样。在那里,您可以滚动浏览电子邮件主题和消息正文。请帮我解决一下这个。我已经坚持了好几天了。

【问题讨论】:

【参考方案1】:

好的,我想通了。这是我所做的更改。

在全局属性中。

var oldProjectDescriptionHeight: CGFloat!

var projectDescriptionHeight: CGFloat! 
    willSet 
       oldProjectDescriptionHeight = projectDescriptionHeight
    

而在UITextViewDelegatetextViewDidChange

func textViewDidChange(textView: UITextView) 

    let fixedWidth = textView.frame.size.width
    textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
    let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
    var newFrame = textView.frame
    newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
    textView.frame = newFrame

    projectDescriptionHeight = newFrame.height

    scrollView.contentSize.height += projectDescriptionHeight - oldProjectDescriptionHeight

【讨论】:

以上是关于如何动态调整 UITextView 的高度的主要内容,如果未能解决你的问题,请参考以下文章

如何让 UITextView 根据内容动态调整自身大小

动态 UITableViewCell 高度内的动态 UITextView?

可变高度 UITextView

使用自动布局的 UITableView 中的动态 UITextView 高度?

iPad 上的 UIModalPresentationFormSheet。键盘出现时如何调整UITextView的高度

动态调整大小的视图定位