'How to make a dynamic change in the height of the ScrollView on which the TableView is added? Swift
Friends, I need help, I spent 2 days on solving this issue. I need to make my ScrollView dynamically change its height based on the amount of text I add to the tableView. The problem is that if I don't strictly set the scroll.contentSize.height height, then the ability to scroll the screen is disabled.
private let scrollView: UIScrollView = {
let scroll = UIScrollView()
scroll.contentSize.height = 4000
scroll.backgroundColor = UIColor.white
scroll.translatesAutoresizingMaskIntoConstraints = false
return scroll
}()
func setConstraints() {
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
NSLayoutConstraint.activate([
headLabel.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
headLabel.topAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 45)
])
NSLayoutConstraint.activate([
ellipseBabyImage.topAnchor.constraint(equalTo: stackViewName.bottomAnchor, constant: 75),
ellipseBabyImage.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
ellipseBabyImage.heightAnchor.constraint(equalToConstant: 131.3),
ellipseBabyImage.widthAnchor.constraint(equalToConstant: 145)
])
NSLayoutConstraint.activate([
goButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
goButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -40),
goButton.leadingAnchor.constraint(equalTo: view.leadingAnchor,constant: 20),
goButton.trailingAnchor.constraint(equalTo: view.trailingAnchor,constant: -20),
goButton.heightAnchor.constraint(equalToConstant: 48)
])
NSLayoutConstraint.activate([
characterLabel.topAnchor.constraint(equalTo: ellipseBabyImage.bottomAnchor, constant: 68.35),
characterLabel.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor)
])
NSLayoutConstraint.activate([
stackViewName.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
stackViewName.topAnchor.constraint(equalTo: headLabel.topAnchor,constant: 44),
])
NSLayoutConstraint.activate([
leftBlockStack.topAnchor.constraint(equalTo: fullNameLabel.topAnchor, constant: 60),
leftBlockStack.leftAnchor.constraint(equalTo: view.leftAnchor,constant: 28),
leftBlockStack.rightAnchor.constraint(equalTo: ellipseBabyImage.leftAnchor,constant: -10)
])
NSLayoutConstraint.activate([
rightBlockStack.topAnchor.constraint(equalTo: fullNameLabel.topAnchor, constant: 60),
rightBlockStack.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -28),
rightBlockStack.leftAnchor.constraint(equalTo: ellipseBabyImage.rightAnchor,constant: 10)
])
NSLayoutConstraint.activate([
arrayStackCharacteristicOne.topAnchor.constraint(equalTo: characterLabel.bottomAnchor,constant: 16),
arrayStackCharacteristicOne.centerXAnchor.constraint(equalTo: view.centerXAnchor),
arrayStackCharacteristicOne.leftAnchor.constraint(equalTo: scrollView.leftAnchor,constant: 22),
healthProgressView.heightAnchor.constraint(equalToConstant: 5),
healthProgressView.widthAnchor.constraint(equalToConstant: 90),
willpowerProgressView.heightAnchor.constraint(equalToConstant: 5),
willpowerProgressView.widthAnchor.constraint(equalToConstant: 90),
luckProgressView.heightAnchor.constraint(equalToConstant: 5),
luckProgressView.widthAnchor.constraint(equalToConstant: 90),
])
NSLayoutConstraint.activate([
arrayStackCharacteristicTwo.topAnchor.constraint(equalTo: arrayStackCharacteristicOne.bottomAnchor,constant: 16),
arrayStackCharacteristicTwo.centerXAnchor.constraint(equalTo: view.centerXAnchor),
arrayStackCharacteristicTwo.leftAnchor.constraint(equalTo: scrollView.leftAnchor,constant: 22),
talentProgressView.heightAnchor.constraint(equalToConstant: 5),
talentProgressView.widthAnchor.constraint(equalToConstant: 90),
successProgressView.heightAnchor.constraint(equalToConstant: 5),
successProgressView.widthAnchor.constraint(equalToConstant: 90),
creationProgressView.heightAnchor.constraint(equalToConstant: 5),
creationProgressView.widthAnchor.constraint(equalToConstant: 90),
])
NSLayoutConstraint.activate([
descriptionView.topAnchor.constraint(equalTo: arrayStackCharacteristicTwo.topAnchor, constant: 50),
descriptionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
descriptionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
descriptionView.bottomAnchor.constraint(equalTo: view.bottomAnchor,constant: 0),
])
class DescriptionView: UIView {
private let characteristicModel = CharacteristicModel()
private let descriptionIdentifier = "CELL"
private let tableView: UITableView = {
let tableView = UITableView(frame: .zero, style: .grouped)
tableView.backgroundColor = .none
tableView.bounces = false
tableView.separatorStyle = .none
tableView.showsVerticalScrollIndicator = false
tableView.isScrollEnabled = false
tableView.translatesAutoresizingMaskIntoConstraints = false
return tableView
}()
override init(frame: CGRect) {
super.init(frame: frame)
setDelegates()
setupViews()
setupConstraints()
tableView.sizeToFit()
tableView.register(DescriptionTableViewCell.self, forCellReuseIdentifier: "CELL")
}
required init?(coder: NSCoder) {
fatalError()
}
private func setDelegates() {
tableView.delegate = self
tableView.dataSource = self
}
private func setupViews() {
addSubview(tableView)
translatesAutoresizingMaskIntoConstraints = false
}
}
//MARK: - UI TableViewDataSource
extension DescriptionView: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
characteristicModel.title.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CELL",for: indexPath) as! DescriptionTableViewCell
let descriptionTitle = characteristicModel.title[indexPath.row]
let descriptionText = characteristicModel.description[indexPath.row]
var content = cell.defaultContentConfiguration()
content.textProperties.color = UIColor(red: 0.729, green: 0.443, blue: 0.443, alpha: 1)
content.textProperties.alignment = .center
content.textProperties.font = UIFont(name: "Lato-SemiBold", size: 22) ?? .systemFont(ofSize: 22)
content.text = descriptionTitle
content.secondaryText = descriptionText
content.secondaryTextProperties.font = UIFont(name: "Lato-SemiBold", size: 16) ?? .systemFont(ofSize: 16)
content.secondaryTextProperties.alignment = .justified
cell.contentConfiguration = content
return cell
}
}
extension DescriptionView {
private func setupConstraints() {
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: topAnchor,constant: 5),
tableView.leadingAnchor.constraint(equalTo: leadingAnchor,constant: 5),
tableView.trailingAnchor.constraint(equalTo: trailingAnchor,constant: -5),
tableView.bottomAnchor.constraint(equalTo: bottomAnchor,constant: -5)
])
}
}





I tried to use different approaches that I found on the Internet, but unfortunately I could not solve it. Either scroll is disabled for me, or the scroll width does not change automatically.
The screenshot shows that I use a tableView for the text that will be automatically added from the API, everything else is uiScrollView. tableView should have scroll disabled and scrollView should scroll to the end of the text The application should look like this.
Solution 1:[1]
Set your scrollview and tableview height to 0 and try adding this to your viewcontroller. you can update the height of the scrollview through viewDidLayoutSubviews.
override func viewDidLayoutSubviews() {
DispatchQueue.main.async {
self.scrollView.contentSize.height = self.descriptionView.tableView.contentSize.height + otherViews.frame.height
}
}
you can also add an observer to the tableview whenever it updates its contentsize
override func viewDidLoad() {
descriptionView.tableView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if let obj = object as? UITableView {
if obj == descriptionView.tableView && keyPath == "contentSize" {
if let newSize = change?[.newKey] as? CGSize {
descriptionView.tableViewHeightConstraint.constant = newSize.height
view.layoutIfNeeded()
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Nazca Elroux |
