【问题标题】:Dynamically adjust UIScrollView contentSize depending on the overall size of a UIView and UITextView根据 UIView 和 UITextView 的整体大小动态调整 UIScrollView contentSize
【发布时间】:2020-07-20 16:19:49
【问题描述】:

我有一个项目,它有一个 viewController,里面有一个滚动视图,它有一个 UILabel 和一个 UITextView 作为子视图。每次打开应用程序时,我都会从 Google Firestore 数据库中检索数据,因此将 UILabel 更新为标题,将 UITextView 更新为文本正文。我已经设置了约束,一切都运行良好。但是,如果 textView 的大小超出 UIViewController 视图的边界,我不知道如何计算 UIScrollView 的 contentView 高度,以便您可以向下滚动以阅读其余文本。我在底部也有一个 tabBar,这意味着滚动视图应该停止在它上面。

这是我的代码。

    import UIKit

class StoryViewController: UIViewController {

    var storyTitle = String()
    var storyBody = ""


    let titleLabel: UILabel = {
        let label = UILabel()
        label.textAlignment = .center
        label.numberOfLines = 0
        label.font = UIFont(name: "Arial-BoldMT", size: 28)
        label.textColor = UIColor.black
        label.translatesAutoresizingMaskIntoConstraints = false

        return label
    }()

    let textView: UITextView = {
        let textView = UITextView()
        textView.textAlignment = .left
        textView.isEditable = false
        textView.isSelectable = false
        textView.font = UIFont(name: "ArialMT", size: 19)
        textView.isScrollEnabled = false
        textView.translatesAutoresizingMaskIntoConstraints = false

        return textView
    }()

    let scrollView: UIScrollView = {
        let scrollingView = UIScrollView()
        scrollingView.translatesAutoresizingMaskIntoConstraints = false
        return scrollingView
    }()


    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationController?.navigationBar.shadowImage = UIImage()
        self.view.backgroundColor = UIColor.white


        titleLabel.text = storyTitle
        textView.text = storyBody.replacingOccurrences(of: "NL", with: "\n\n")
        textView.sizeToFit()

        scrollView.contentSize = CGSize(width: self.view.frame.width, height: textView.contentSize.height)

        view.addSubview(scrollView)

        scrollView.addSubview(titleLabel)
        scrollView.addSubview(textView)

        NSLayoutConstraint.activate([

        scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
        scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),


        titleLabel.leadingAnchor.constraint(equalTo: scrollView.readableContentGuide.leadingAnchor),
        titleLabel.trailingAnchor.constraint(equalTo: scrollView.readableContentGuide.trailingAnchor),
        titleLabel.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 16),
        titleLabel.bottomAnchor.constraint(equalTo: textView.topAnchor, constant: -16),
        titleLabel.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),


        textView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 16),
        textView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
        textView.leadingAnchor.constraint(equalTo: scrollView.readableContentGuide.leadingAnchor),
        textView.trailingAnchor.constraint(equalTo: scrollView.readableContentGuide.trailingAnchor),


        ])

我尝试了很多东西,但似乎没有任何效果。

提前感谢大家的时间和回复。

【问题讨论】:

    标签: ios swift uiscrollview uitextview


    【解决方案1】:

    你已经接近了......但你不必担心设置滚动视图的.contentSize。让自动布局为您处理。

    您缺少的关键点是滚动视图的子视图的底部约束。

    这是您的课程(带有示例标题和正文),只需稍作修改即可使用。我添加的cmets应该说清楚:

    class StoryViewController: UIViewController {
    
        var storyTitle = String()
        var storyBody = ""
    
        let titleLabel: UILabel = {
            let label = UILabel()
            label.textAlignment = .center
            label.numberOfLines = 0
            label.font = UIFont(name: "Arial-BoldMT", size: 28)
            label.textColor = UIColor.black
            label.translatesAutoresizingMaskIntoConstraints = false
    
            return label
        }()
    
        let textView: UITextView = {
            let textView = UITextView()
            textView.textAlignment = .left
            textView.isEditable = false
            textView.isSelectable = false
            textView.font = UIFont(name: "ArialMT", size: 19)
            textView.isScrollEnabled = false
            textView.translatesAutoresizingMaskIntoConstraints = false
    
            return textView
        }()
    
        let scrollView: UIScrollView = {
            let scrollingView = UIScrollView()
            scrollingView.translatesAutoresizingMaskIntoConstraints = false
            return scrollingView
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.navigationController?.navigationBar.shadowImage = UIImage()
            self.view.backgroundColor = UIColor.white
    
            // sample Title and Body
            storyTitle = "Example\nTitle Label"
    
            storyBody = ""
            storyBody += "UITextView:"
            storyBody += "NL"
            storyBody += "When a user taps a text view, a keyboard appears; when a user taps Return in the keyboard, the keyboard disappears and the text view can handle the input in an application-specific way. You can specify attributes, such as font, color, and alignment, that apply to all text in a text view."
            storyBody += "NL"
            storyBody += "UIScrollView:"
            storyBody += "NL"
            storyBody += "UIScrollView provides a mechanism to display content that is larger than the size of the application’s window and enables users to scroll within that content by making swiping gestures."
            storyBody += "NL"
            storyBody += "UILabel:"
            storyBody += "NL"
            storyBody += "A label can contain an arbitrary amount of text, but UILabel may shrink, wrap, or truncate the text, depending on the size of the bounding rectangle and properties you set. You can control the font, text color, alignment, highlighting, and shadowing of the text in the label."
            storyBody += "NL"
            storyBody += "UIButton:"
            storyBody += "NL"
            storyBody += "You can set the title, image, and other appearance properties of a button. In addition, you can specify a different appearance for each button state."
    
            titleLabel.text = storyTitle
            textView.text = storyBody.replacingOccurrences(of: "NL", with: "\n\n")
    
            // you do not need either of these two lines
            //textView.sizeToFit()
            //scrollView.contentSize = CGSize(width: self.view.frame.width, height: textView.contentSize.height)
    
            view.addSubview(scrollView)
    
            scrollView.addSubview(titleLabel)
            scrollView.addSubview(textView)
    
            NSLayoutConstraint.activate([
    
                scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
                scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
                scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
                scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
    
                // don't use .centerXAnchor constraints
                //titleLabel.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
                //textView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
    
                // don't need to set titleLabel bottom constraint
                //titleLabel.bottomAnchor.constraint(equalTo: textView.topAnchor, constant: -16),
    
                titleLabel.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 16),
                titleLabel.leadingAnchor.constraint(equalTo: scrollView.readableContentGuide.leadingAnchor),
                titleLabel.trailingAnchor.constraint(equalTo: scrollView.readableContentGuide.trailingAnchor),
    
                textView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 16),
                textView.leadingAnchor.constraint(equalTo: scrollView.readableContentGuide.leadingAnchor),
                textView.trailingAnchor.constraint(equalTo: scrollView.readableContentGuide.trailingAnchor),
    
                // set the textView's bottomAnchor to let auto-layout determine content size
                textView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
    
            ])
    
        }
    }
    

    【讨论】:

    • 非常感谢,我想知道为什么我之前没有考虑过这个问题。我试图找到最复杂的方法来完成这项工作,但看起来,“这是一个简单的解决方案。你改变了一件事,突然间你就改变了一切。” -丽贝卡·奥尼。
    猜你喜欢
    • 2012-11-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 2019-12-17
    • 2011-11-06
    • 2019-06-25
    • 1970-01-01
    相关资源
    最近更新 更多