Не удается получить динамическое представление прокрутки, размер которого соответствует его содержимому, работающему

У меня возникла проблема с динамическим изменением размера прокрутки и прокруткой, чтобы она соответствовала всему моему контенту. Я делаю все это программно, так как считаю, что его проще всего использовать при работе с автоматической компоновкой. В любом случае, каждое решение, с которым я сталкивался в Интернете, похоже, не работает, и самое близкое, что я получил, было, когда я попробовал это. contentView.heightAnchor.constraint(equalTo: self.scrollView.frameLayoutGuide.heightAnchor).isActive = true Установка привязки высоты контекстного представления к направляющей макета фрейма представления прокрутки позволила мне прокручивать, но она все еще не достигла дна. Я чувствую, что должен что-то упускать из виду, но я не могу понять это для своей жизни. Вот мой код ниже. Спасибо. Также извините за то, как он отображается ниже, я не могу заставить его все поместиться в поле.

Изменить: перед публикацией этого я экспериментировал с встраиванием моего представления контента в представление стека, поэтому оно там, но я пробовал без стека, и это все равно не сработало.

Изменить 2: найдено решение и исправлено отображение кода.

import UIKit import Charts class ViewController: UIViewController, UIScrollViewDelegate, ChartViewDelegate { let scrollView = UIScrollView() let contentStackView = UIStackView() let contentView = UIView() var dealStack, customScoreStack, basicInfoStack: UIStackView! var thisListing = Listing() var priceDollarSign, dealIndicatorArrow, vehicleImage, customScoreLogo: UIImageView! var vehiclePrice, dealType, dealValueLbl, milesLbl, customScoreValue, customScoreTitle, basicCarInfo, distanceAndDealer, graphTitle, specTitle, insuranceCalcTitle, commentsTitle, similarListingsTitle: UILabel! var graphSwitchingSegment, yearSwitchingSegment1, yearSwitchingSegment2: UISegmentedControl! var carPrice = «», dealValue = «1», miles = «», year = «2021», make = «GMC», model = «YUKON», trim = «DENALI», distance = «20», dealerName = «Dealer» var graphState = true var graphData1, graphData2: String! lazy var graph1: LineChartView = { let chartView = LineChartView() return chartView }() lazy var graph2: LineChartView = { let chartView = LineChartView() return chartView }() var months: [String]! var yValues: [ChartDataEntry]! override func viewDidLoad() { super.viewDidLoad() months = [«Jan», «Feb», «Mar», «Apr», «May», «Jun», «Jul», «Aug», «Sep», «Oct», «Nov», «Dec»] yValues = [ ChartDataEntry(x: 1, y: 20.0), ChartDataEntry(x: 2, y: 4.0), ChartDataEntry(x: 3, y: 6.0), ChartDataEntry(x: 4, y: 3.0), ChartDataEntry(x: 5, y: 12.0), ChartDataEntry(x: 6, y: 16.0), ChartDataEntry(x: 7, y: 4.0), ChartDataEntry(x: 8, y: 18.0), ChartDataEntry(x: 9, y: 2.0), ChartDataEntry(x: 10, y: 4.0), ChartDataEntry(x: 11, y: 5.0), ChartDataEntry(x: 12, y: 4.0) ] self.scrollView.backgroundColor = .lightGray self.view.addSubview(scrollView) self.view.sendSubviewToBack(scrollView) self.scrollView.translatesAutoresizingMaskIntoConstraints = false self.scrollView.isScrollEnabled = true self.scrollView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor).isActive = true self.scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true self.scrollView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor).isActive = true self.scrollView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor).isActive = true self.scrollView.addSubview(contentStackView) self.contentStackView.translatesAutoresizingMaskIntoConstraints = false self.contentStackView.axis = .vertical self.contentStackView.topAnchor.constraint(equalTo: self.scrollView.topAnchor).isActive = true self.contentStackView.leadingAnchor.constraint(equalTo: self.scrollView.leadingAnchor).isActive = true self.contentStackView.trailingAnchor.constraint(equalTo: self.scrollView.trailingAnchor).isActive = true self.contentStackView.bottomAnchor.constraint(equalTo: self.scrollView.bottomAnchor).isActive = true self.contentStackView.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive = true contentStackView.addArrangedSubview(contentView) contentView.translatesAutoresizingMaskIntoConstraints = false contentView.topAnchor.constraint(equalTo: self.contentStackView.topAnchor).isActive = true contentView.leadingAnchor.constraint(equalTo: self.contentStackView.leadingAnchor).isActive = true contentView.trailingAnchor.constraint(equalTo: self.contentStackView.trailingAnchor).isActive = true contentView.bottomAnchor.constraint(equalTo: self.contentStackView.bottomAnchor).isActive = true contentView.widthAnchor.constraint(equalTo: self.contentStackView.widthAnchor).isActive = true //contentView.heightAnchor.constraint(equalTo: self.scrollView.frameLayoutGuide.heightAnchor).isActive = true contentView.sizeToFit() setUpView() graph1Setup() } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() scrollView.delegate = self print(«View Size: (self.view.frame.debugDescription) nScroll View Size: (self.scrollView.frame.debugDescription) nScroll Content View Size: (self.contentView.frame.debugDescription)») } override func viewDidAppear(_ animated: Bool) { // Test subview locations here: print(_SUBVIEW.frame.debugDescription) } @objc func graphSwitcher(_ segmentedControl: UISegmentedControl) { switch graphSwitchingSegment.selectedSegmentIndex { case 0: graphState = true print(«VALUE CHANGED») print(self.contentView.frame.debugDescription) case 1: graphState = false print(«VALUE CHANGED») default: graphState = true break } } func setUpView() { //Object Instantiation dealStack = UIStackView(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) dealStack.translatesAutoresizingMaskIntoConstraints = false dealStack.axis = .vertical dealStack.spacing = 1 dealStack.distribution = .fillProportionally customScoreStack = UIStackView(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) customScoreStack.translatesAutoresizingMaskIntoConstraints = false customScoreStack.axis = .vertical customScoreStack.spacing = 1 customScoreStack.distribution = .fillProportionally basicInfoStack = UIStackView(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) basicInfoStack.translatesAutoresizingMaskIntoConstraints = false basicInfoStack.axis = .vertical basicInfoStack.spacing = 2 basicInfoStack.distribution = .fillProportionally priceDollarSign = UIImageView(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) priceDollarSign.image = UIImage(named: «greenDollarsign») priceDollarSign.translatesAutoresizingMaskIntoConstraints = false dealIndicatorArrow = UIImageView(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) dealIndicatorArrow.image = UIImage(named: «greenUpArrow») dealIndicatorArrow.translatesAutoresizingMaskIntoConstraints = false vehicleImage = UIImageView(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) vehicleImage.image = UIImage(named: «audiA7») vehicleImage.translatesAutoresizingMaskIntoConstraints = false customScoreLogo = UIImageView(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) customScoreLogo.image = UIImage(named: «aladdinGenie») customScoreLogo.translatesAutoresizingMaskIntoConstraints = false customScoreTitle = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) customScoreTitle.text = «Genie Score:» customScoreTitle.textAlignment = .right customScoreTitle.translatesAutoresizingMaskIntoConstraints = false customScoreValue = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) customScoreValue.text = «VALUE_PLACE_HOLDER» customScoreValue.translatesAutoresizingMaskIntoConstraints = false vehiclePrice = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) let numberFormatter = NumberFormatter() numberFormatter.numberStyle = .decimal vehiclePrice.text = numberFormatter.string(from: NSNumber(value: thisListing.getDetails().returnCarPrice())) vehiclePrice.font = UIFont.systemFont(ofSize: 30, weight: .semibold) vehiclePrice.textAlignment = .left vehiclePrice.translatesAutoresizingMaskIntoConstraints = false dealType = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) dealType.text = thisListing.getDetails().returnDealRatingType().0 dealType.font = UIFont(name: dealType.font.fontName, size: 28) dealType.textColor = self.thisListing.getDetails().returnDealRatingType().1 dealType.adjustsFontSizeToFitWidth = true dealType.minimumScaleFactor = 0.8 dealType.numberOfLines = 0 dealType.textAlignment = .right dealType.translatesAutoresizingMaskIntoConstraints = false dealValueLbl = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) dealValueLbl.text = «$» + (numberFormatter.string(from: NSNumber(value: self.thisListing.getDetails().returnDealDiff()))!) + (self.thisListing.getDetails().returnDealDiff() > 0 ? » ABOVE»:» BELOW») dealValueLbl.font = UIFont(name: dealValueLbl.font.fontName, size: 19) dealValueLbl.adjustsFontSizeToFitWidth = true dealValueLbl.minimumScaleFactor = 0.8 dealValueLbl.numberOfLines = 0 dealValueLbl.textAlignment = .right dealValueLbl.translatesAutoresizingMaskIntoConstraints = false milesLbl = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) milesLbl.font = UIFont.systemFont(ofSize: 34, weight: .regular) milesLbl.textAlignment = .left milesLbl.adjustsFontSizeToFitWidth = true milesLbl.minimumScaleFactor = 0.8 milesLbl.text = «(numberFormatter.string(from: NSNumber(value: (self.miles as NSString).integerValue)) ?? «») Miles» milesLbl.translatesAutoresizingMaskIntoConstraints = false basicCarInfo = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) basicCarInfo.text = «(year) (make) (model) (trim)» basicCarInfo.font = UIFont.systemFont(ofSize: 20, weight: .semibold) basicCarInfo.adjustsFontSizeToFitWidth = true basicCarInfo.numberOfLines = 0 basicCarInfo.minimumScaleFactor = 0.8 basicCarInfo.textAlignment = .center basicCarInfo.translatesAutoresizingMaskIntoConstraints = false distanceAndDealer = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) distanceAndDealer.text = «(distance) miles away from you at (dealerName)» distanceAndDealer.font = UIFont.systemFont(ofSize: 20, weight: .regular) distanceAndDealer.adjustsFontSizeToFitWidth = true distanceAndDealer.numberOfLines = 0 distanceAndDealer.minimumScaleFactor = 0.8 distanceAndDealer.textAlignment = .center distanceAndDealer.translatesAutoresizingMaskIntoConstraints = false graphTitle = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) graphTitle.text = «Graphs» graphTitle.font = UIFont.systemFont(ofSize: 22, weight: .semibold) graphTitle.numberOfLines = 0 graphTitle.adjustsFontSizeToFitWidth = true graphTitle.minimumScaleFactor = 0.8 graphTitle.textAlignment = .center graphTitle.translatesAutoresizingMaskIntoConstraints = false graphSwitchingSegment = UISegmentedControl(items: [«Graph 1″,»Graph 2»]) graphSwitchingSegment.addTarget(self, action: #selector(graphSwitcher(_:)), for: .valueChanged) graphSwitchingSegment.selectedSegmentIndex = 0 graphSwitchingSegment.translatesAutoresizingMaskIntoConstraints = false graph1.frame = CGRect(x: 0, y: 0, width: 0, height: 0) graph1.noDataText = «OOPS NO DATA HERE!» graph1.noDataTextColor = .green graph1.backgroundColor = .white graph1.translatesAutoresizingMaskIntoConstraints = false yearSwitchingSegment1 = UISegmentedControl(items: [«Year 1″,»Year 2»]) yearSwitchingSegment1.addTarget(self, action: #selector(graphSwitcher(_:)), for: .valueChanged) yearSwitchingSegment1.selectedSegmentIndex = 0 yearSwitchingSegment1.translatesAutoresizingMaskIntoConstraints = false //Adds objects to the view self.contentView.addSubview(priceDollarSign) self.contentView.addSubview(dealStack) self.contentView.addSubview(customScoreStack) self.contentView.addSubview(basicInfoStack) self.contentView.addSubview(dealIndicatorArrow) self.contentView.addSubview(vehicleImage) self.contentView.addSubview(vehiclePrice) self.contentView.addSubview(milesLbl) self.contentView.addSubview(customScoreLogo) self.contentView.addSubview(graphTitle) self.contentView.addSubview(graphSwitchingSegment) self.contentView.addSubview(graph1) self.contentView.addSubview(yearSwitchingSegment1) dealStack.addArrangedSubview(dealType) dealStack.addArrangedSubview(dealValueLbl) customScoreStack.addArrangedSubview(customScoreTitle) customScoreStack.addArrangedSubview(customScoreValue) basicInfoStack.addArrangedSubview(basicCarInfo) basicInfoStack.addArrangedSubview(distanceAndDealer) //Object Constraints priceDollarSign.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 7).isActive = true priceDollarSign.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor, constant: 7).isActive = true priceDollarSign.widthAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.widthAnchor, multiplier: 0.1).isActive = true priceDollarSign.widthAnchor.constraint(greaterThanOrEqualToConstant: 40).isActive = true priceDollarSign.widthAnchor.constraint(lessThanOrEqualToConstant: 100).isActive = true priceDollarSign.heightAnchor.constraint(equalTo: priceDollarSign.widthAnchor).isActive = true priceDollarSign.heightAnchor.constraint(greaterThanOrEqualToConstant: 40).isActive = true priceDollarSign.heightAnchor.constraint(lessThanOrEqualToConstant: 100).isActive = true vehiclePrice.topAnchor.constraint(equalTo: priceDollarSign.topAnchor).isActive = true vehiclePrice.bottomAnchor.constraint(equalTo: priceDollarSign.bottomAnchor).isActive = true vehiclePrice.leadingAnchor.constraint(equalTo: priceDollarSign.trailingAnchor, constant: 8).isActive = true vehiclePrice.sizeToFit() vehiclePrice.layoutIfNeeded() dealStack.topAnchor.constraint(equalTo: priceDollarSign.topAnchor).isActive = true dealStack.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor, constant: -7).isActive = true dealStack.heightAnchor.constraint(equalTo: priceDollarSign.heightAnchor).isActive = true dealType.heightAnchor.constraint(equalTo: dealValueLbl.heightAnchor).isActive = true dealType.widthAnchor.constraint(equalTo: dealValueLbl.widthAnchor).isActive = true dealType.sizeToFit() dealType.layoutIfNeeded() dealValueLbl.sizeToFit() dealValueLbl.layoutIfNeeded() dealIndicatorArrow.topAnchor.constraint(equalTo: priceDollarSign.topAnchor).isActive = true dealIndicatorArrow.bottomAnchor.constraint(equalTo: priceDollarSign.bottomAnchor).isActive = true dealIndicatorArrow.trailingAnchor.constraint(equalTo: dealType.leadingAnchor, constant: -1).isActive = true dealIndicatorArrow.widthAnchor.constraint(equalTo: priceDollarSign.widthAnchor).isActive = true vehicleImage.topAnchor.constraint(equalTo: priceDollarSign.bottomAnchor, constant: 8).isActive = true vehicleImage.centerXAnchor.constraint(equalTo: self.contentView.centerXAnchor).isActive = true vehicleImage.widthAnchor.constraint(equalTo: self.contentView.widthAnchor).isActive = true vehicleImage.heightAnchor.constraint(equalTo: self.vehicleImage.widthAnchor, multiplier: 9/16).isActive = true vehicleImage.heightAnchor.constraint(lessThanOrEqualToConstant: self.view.frame.height * 0.3).isActive = true vehicleImage.contentMode = .scaleAspectFit milesLbl.topAnchor.constraint(equalTo: vehicleImage.bottomAnchor, constant: 8).isActive = true milesLbl.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 8).isActive = true milesLbl.sizeToFit() milesLbl.layoutIfNeeded() customScoreStack.topAnchor.constraint(equalTo: milesLbl.topAnchor).isActive = true customScoreStack.heightAnchor.constraint(equalTo: milesLbl.heightAnchor).isActive = true customScoreStack.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor, constant: -8).isActive = true customScoreLogo.topAnchor.constraint(equalTo: milesLbl.topAnchor).isActive = true customScoreLogo.trailingAnchor.constraint(equalTo: customScoreStack.leadingAnchor, constant: 1).isActive = true customScoreLogo.widthAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.widthAnchor, multiplier: 0.1).isActive = true customScoreLogo.widthAnchor.constraint(greaterThanOrEqualToConstant: 40).isActive = true customScoreLogo.widthAnchor.constraint(lessThanOrEqualToConstant: 100).isActive = true customScoreLogo.heightAnchor.constraint(equalTo: customScoreLogo.widthAnchor).isActive = true customScoreLogo.heightAnchor.constraint(greaterThanOrEqualToConstant: 40).isActive = true customScoreLogo.heightAnchor.constraint(lessThanOrEqualToConstant: 100).isActive = true basicInfoStack.topAnchor.constraint(equalTo: milesLbl.bottomAnchor, constant: 32).isActive = true basicInfoStack.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true basicInfoStack.widthAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.widthAnchor, constant: -10).isActive = true basicCarInfo.heightAnchor.constraint(equalTo: distanceAndDealer.heightAnchor).isActive = true graphTitle.topAnchor.constraint(equalTo: basicInfoStack.bottomAnchor, constant: 24).isActive = true graphTitle.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true graphTitle.widthAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.widthAnchor, constant: -16).isActive = true graphSwitchingSegment.topAnchor.constraint(equalTo: graphTitle.bottomAnchor, constant: 20).isActive = true graphSwitchingSegment.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true graphSwitchingSegment.widthAnchor.constraint(equalToConstant: self.view.frame.width).isActive = true graph1.topAnchor.constraint(equalTo: graphSwitchingSegment.bottomAnchor, constant: 2).isActive = true graph1.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true graph1.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true graph1.heightAnchor.constraint(equalTo: self.graph1.widthAnchor, multiplier: 12/16).isActive = true yearSwitchingSegment1.topAnchor.constraint(equalTo: graph1.bottomAnchor, constant: 100).isActive = true yearSwitchingSegment1.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true yearSwitchingSegment1.widthAnchor.constraint(equalToConstant: self.view.frame.width).isActive = true } func graph1Setup() { let dataSet = LineChartDataSet(entries: yValues, label: «Months») let data = LineChartData(dataSet: dataSet) graph1.data = data } func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) { print(entry) } }

Источник: ledsshop.ru

Стиль жизни - Здоровье!