根据 UIView 和 UITextView 的整体大小动态调整 UIScrollView contentSize
Dynamically adjust UIScrollView contentSize depending on the overall size of a UIView and UITextView
我有一个项目,其中有一个 viewController 并且在其中有一个滚动视图,其中有一个 UILabel 和一个 UITextView 作为子视图。每次打开应用程序时,我都会从 Google Firestore 数据库中检索数据,因此将 UILabel 更新为标题,将 UITextView 更新为文本 body。我已经设置了约束,一切都运行良好。但是,如果 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),
])
我尝试了很多方法,但似乎没有任何效果。
感谢大家抽出宝贵时间提前回复。
您很接近...但是您不必担心设置滚动视图的 .contentSize
。让 auto-layout 为您处理。
您遗漏的关键点是滚动视图子视图的 bottom 约束。
这是您的 class(带有示例标题和 body 文本),只需稍微修改即可使用。我加的评论应该说清楚了:
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),
])
}
}
我有一个项目,其中有一个 viewController 并且在其中有一个滚动视图,其中有一个 UILabel 和一个 UITextView 作为子视图。每次打开应用程序时,我都会从 Google Firestore 数据库中检索数据,因此将 UILabel 更新为标题,将 UITextView 更新为文本 body。我已经设置了约束,一切都运行良好。但是,如果 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),
])
我尝试了很多方法,但似乎没有任何效果。
感谢大家抽出宝贵时间提前回复。
您很接近...但是您不必担心设置滚动视图的 .contentSize
。让 auto-layout 为您处理。
您遗漏的关键点是滚动视图子视图的 bottom 约束。
这是您的 class(带有示例标题和 body 文本),只需稍微修改即可使用。我加的评论应该说清楚了:
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),
])
}
}