У меня есть следующий класс бронирования (UIView), который я создаю программно, но мне не удалось его прокрутить. Я требую, чтобы он прокручивался только вертикально. Я не использую UIStackView, поскольку представление, которое я на самом деле использую, немного сложнее, чем приведенный ниже код. Код, приведенный ниже, является упрощенной версией.
Я читал различные сообщения SO, где некоторые говорят, что вам нужно иметь представление внутри представления прокрутки, которое затем содержит все подпредставления (я в данный момент делаю это), другие люди говорят, что это не нужно. Некоторые говорят, что вам нужно вручную определить размер содержимого представления прокрутки, и снова, другие говорят, что вам не нужно этого делать! Что является правильным для каждого из этих пунктов? или это не имеет значения?
Когда я обновил UIScrollView, чтобы добавить все высоты представлений, я вижу, что индикатор вертикальной прокрутки перемещается вверх и вниз, но фактическое содержимое не перемещается!
Конечно, если ограничения установлены, представление прокрутки должно быть в состоянии рассчитать высоту?
У меня также были проблемы, когда представления растягивались по вертикали, и поэтому я добавлял в приоритете объятия контента, где я устанавливал ограничения.
Вот код: -
import UIKit
@IBDesignable
class Booking: UIView, UIScrollViewDelegate {
//Layout Items
let scrollView: UIScrollView = {
let view = UIScrollView()
view.translatesAutoresizingMaskIntoConstraints = false
view.showsVerticalScrollIndicator = true
view.showsHorizontalScrollIndicator = false
view.isScrollEnabled = true
return view
}()
let contentView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
//Header view and its children
let headerContentView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1)
return view
}()
let headerBookingLbl: UILabel = {
let view = UILabel()
view.translatesAutoresizingMaskIntoConstraints = false
view.textColor = UIColor.white
view.numberOfLines = 3
view.textAlignment = .center
view.text = "Title Title Title"
return view
}()
let aboutStack: UIStackView = {
let view = UIStackView()
view.isUserInteractionEnabled = true
view.translatesAutoresizingMaskIntoConstraints = false
view.axis = .horizontal
view.alignment = .fill
view.distribution = .fill
view.spacing = 5
view.backgroundColor = UIColor.clear
return view
}()
let aboutIcon: UIImageView = {
let view = UIImageView()
view.translatesAutoresizingMaskIntoConstraints = false
view.contentMode = .scaleAspectFit
view.clipsToBounds = true
view.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 0)
return view
}()
let aboutLbl: UILabel = {
let view = UILabel()
view.translatesAutoresizingMaskIntoConstraints = false
view.textColor = UIColor.white
view.text = "About Your Booking"
view.numberOfLines = 1
view.textAlignment = .natural
return view
}()
//body view
let haveABookingLbl: UILabel = {
let view = UILabel()
view.translatesAutoresizingMaskIntoConstraints = false
view.textColor = #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1)
view.text = "Already have a booking?"
view.numberOfLines = 0
view.textAlignment = .center
return view
}()
let enterABookingInfoLbl: UILabel = {
let view = UILabel()
view.translatesAutoresizingMaskIntoConstraints = false
view.textColor = #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1)
view.text = "Enter your ticket reference number to gain access to bonus content"
view.numberOfLines = 0
view.textAlignment = .center
return view
}()
let bookingReference: UITextField = {
let view = UITextField()
view.translatesAutoresizingMaskIntoConstraints = false
view.autocapitalizationType = .none
view.borderStyle = UITextField.BorderStyle.roundedRect
view.placeholder = "Ticket reference*"
return view
}()
let lastName: UITextField = {
let view = UITextField()
view.translatesAutoresizingMaskIntoConstraints = false
view.autocapitalizationType = .none
view.borderStyle = UITextField.BorderStyle.roundedRect
view.placeholder = "Last name*"
return view
}()
let submitBtn: UIButton = {
let view = UIButton()
view.translatesAutoresizingMaskIntoConstraints = false
view.setTitle("Submit", for: .normal)
view.backgroundColor = #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1)
return view
}()
let viewPrivacyPolicayLbl: UILabel = {
let view = UILabel()
view.translatesAutoresizingMaskIntoConstraints = false
view.isUserInteractionEnabled = true
view.textColor = UIColor.black
view.numberOfLines = 1
view.textAlignment = .center
//underline the text - use attributed string
let text = "view privacy policy"
let underlinedText = NSMutableAttributedString(string: text)
underlinedText.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: NSRange(location: 0, length: text.count))
view.attributedText = underlinedText
return view
}()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func layoutSubviews() {
super.layoutSubviews()
}
//This override should prevent issue where you can drag scrollview 1px left/right which shows a white area behind the poster.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
scrollView.contentOffset.x = 0
}
private func setup() {
print("setup()")
setupViews()
setupConstraints()
//scrollView.contentSize = contentView.bounds.size ?? is this needed? doesnt seem to work!
scrollView.delegate = self
}
private func setupViews() {
print("setupViews()")
//Add root scroll view
addSubview(scrollView)
scrollView.addSubview(contentView)
//header contents
contentView.addSubview(headerContentView)
headerContentView.addSubview(headerBookingLbl)
headerContentView.addSubview(aboutStack)
aboutStack.addArrangedSubview(aboutIcon)
aboutStack.addArrangedSubview(aboutLbl)
//body contents
contentView.addSubview(haveABookingLbl)
contentView.addSubview(enterABookingInfoLbl)
contentView.addSubview(bookingReference)
contentView.addSubview(lastName)
contentView.addSubview(submitBtn)
contentView.addSubview(viewPrivacyPolicayLbl)
} //setupViews
private func setupConstraints() {
print("setupConstraints()")
let scrollViewConstraints = [
scrollView.topAnchor.constraint(equalTo: topAnchor),
scrollView.bottomAnchor.constraint(equalTo: bottomAnchor),
scrollView.widthAnchor.constraint(equalTo: widthAnchor),
scrollView.centerXAnchor.constraint(equalTo: centerXAnchor),
contentView.centerXAnchor.constraint(equalTo: centerXAnchor),
contentView.widthAnchor.constraint(equalTo: widthAnchor),
contentView.topAnchor.constraint(equalTo: topAnchor),
contentView.bottomAnchor.constraint(equalTo: bottomAnchor),
]
NSLayoutConstraint.activate(scrollViewConstraints)
//header
let headerViewConstraints = [
//container
headerContentView.topAnchor.constraint(equalTo: topAnchor),
headerContentView.leadingAnchor.constraint(equalTo: leadingAnchor),
headerContentView.trailingAnchor.constraint(equalTo: trailingAnchor),
//headerBookingLbl
headerBookingLbl.topAnchor.constraint(equalTo: headerContentView.topAnchor, constant: 20),
headerBookingLbl.leadingAnchor.constraint(equalTo: headerContentView.leadingAnchor, constant: 20),
headerBookingLbl.trailingAnchor.constraint(equalTo: headerContentView.trailingAnchor, constant: -20),
//aboutStack
aboutStack.topAnchor.constraint(equalTo: headerBookingLbl.bottomAnchor, constant: 20),
aboutStack.centerXAnchor.constraint(equalTo: headerContentView.centerXAnchor),
aboutStack.bottomAnchor.constraint(equalTo: headerContentView.bottomAnchor, constant: -20)
]
NSLayoutConstraint.activate(headerViewConstraints)
headerBookingLbl.setContentHuggingPriority(UILayoutPriority(rawValue: 1000), for: .vertical)
//body
let bodyViewConstraints = [
//haveABookingLbl
haveABookingLbl.topAnchor.constraint(equalTo: headerContentView.bottomAnchor, constant: 30),
haveABookingLbl.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 60),
haveABookingLbl.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -60),
//enterABookingInfoLbl
enterABookingInfoLbl.centerXAnchor.constraint(equalTo: centerXAnchor),
enterABookingInfoLbl.topAnchor.constraint(equalTo: haveABookingLbl.bottomAnchor, constant: 15),
enterABookingInfoLbl.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 60),
enterABookingInfoLbl.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -60),
//bookingReference
bookingReference.heightAnchor.constraint(equalToConstant: 40),
bookingReference.centerXAnchor.constraint(equalTo: centerXAnchor),
bookingReference.topAnchor.constraint(equalTo: enterABookingInfoLbl.bottomAnchor, constant: 15),
bookingReference.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 60),
bookingReference.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -60),
//lastName
lastName.heightAnchor.constraint(equalToConstant: 40),
lastName.centerXAnchor.constraint(equalTo: centerXAnchor),
lastName.topAnchor.constraint(equalTo: bookingReference.bottomAnchor, constant: 15),
lastName.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 60),
lastName.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -60),
//submitBtn
submitBtn.centerXAnchor.constraint(equalTo: centerXAnchor),
submitBtn.topAnchor.constraint(equalTo: lastName.bottomAnchor, constant: 15),
submitBtn.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 60),
submitBtn.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -60),
viewPrivacyPolicayLbl.centerXAnchor.constraint(equalTo: centerXAnchor),
viewPrivacyPolicayLbl.topAnchor.constraint(equalTo: submitBtn.bottomAnchor, constant: 15),
viewPrivacyPolicayLbl.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 60),
viewPrivacyPolicayLbl.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -60),
//viewPrivacyPolicayLbl.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -20)
]
NSLayoutConstraint.activate(bodyViewConstraints)
//Set hugging priority to prevent said items from being made larger than their intrinsic size
haveABookingLbl.setContentHuggingPriority(UILayoutPriority(rawValue: 1000), for: .vertical)
enterABookingInfoLbl.setContentHuggingPriority(UILayoutPriority(rawValue: 1000), for: .vertical)
submitBtn.setContentHuggingPriority(UILayoutPriority(rawValue: 1000), for: .vertical)
viewPrivacyPolicayLbl.setContentHuggingPriority(UILayoutPriority(rawValue: 1000), for: .vertical)
} //setupConstraints
}