Вы можете приблизиться к тому, что вы хотите, изменив функцию loadSlides()
на:
func loadSlides() -> [UIView] {
// instantiate with a frame
let container1 = ScrollViewSlide(frame: scrollView.frame)
container1.mainImageForSubview.image = UIImage(named: "cricket1")
container1.mainLabel.text = "Container1"
// instantiate with a frame
let container2 = ScrollViewSlide(frame: scrollView.frame)
container2.mainImageForSubview.image = UIImage(named: "cricket2")
container2.mainLabel.text = "Container2"
// move container2 to the right of container1
container2.frame.origin.x = container1.frame.origin.x + container1.frame.size.width
// instantiate with a frame
let container3 = ScrollViewSlide(frame: scrollView.frame)
container3.mainImageForSubview.image = UIImage(named: "crisp_ocean")
container3.mainLabel.text = "Container3"
// move container3 to the right of container2
container3.frame.origin.x = container2.frame.origin.x + container2.frame.size.width
return [container1, container2, container3]
}
Однако, как я уже упоминал в комментариях, вам будет намного лучше в конечном итоге, узнав об автоматической компоновке.
Редактировать
Вот ваш код, модифицированный для использования автоматической компоновки вместо явных фреймов:
class ScrollViewSlide: UIView {
lazy var mainImageForSubview : UIImageView = {
let mI = UIImageView()
return mI
}()
lazy var mainLabel : UILabel = {
let mL = UILabel()
return mL
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupView() {
backgroundColor = .white
contentMode = .scaleAspectFit
addSubview(mainImageForSubview)
addSubview(mainLabel)
mainImageForSubview.translatesAutoresizingMaskIntoConstraints = false
mainLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
// constrain main image to all 4 sides
mainImageForSubview.topAnchor.constraint(equalTo: topAnchor),
mainImageForSubview.bottomAnchor.constraint(equalTo: bottomAnchor),
mainImageForSubview.leadingAnchor.constraint(equalTo: leadingAnchor),
mainImageForSubview.trailingAnchor.constraint(equalTo: trailingAnchor),
// constrain main label centered X and Y, height = 30
mainLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
mainLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
mainLabel.heightAnchor.constraint(equalToConstant: 30.0),
])
}
}
class SlidesViewController: UIViewController, UIScrollViewDelegate {
// MARK: - Properties
// using auto-layout, so no need for contentViewSize
//lazy var contentViewSize = CGSize(width: self.view.frame.width * 3, height: self.view.frame.height * 0.6)
// MARK: - Views
lazy var pageIndicator : UIPageControl = {
let pI = UIPageControl()
pI.frame = CGRect()
return pI
}()
lazy var scrollView : UIScrollView = {
let view = UIScrollView(frame: .zero)
view.backgroundColor = .white
view.delegate = self
return view
}()
lazy var stackView: UIStackView = {
let v = UIStackView()
v.axis = .horizontal
v.alignment = .fill
v.distribution = .fill
v.spacing = 0
return v
}()
// MARK: - View Controller Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view.backgroundColor = .white
view.addSubview(scrollView)
scrollView.addSubview(stackView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
stackView.translatesAutoresizingMaskIntoConstraints = false
let mySlides = loadSlides()
setUpViewsForScrollView(slides: mySlides)
loadPageIndicator(mySlides)
let v = view.safeAreaLayoutGuide
let g = scrollView.contentLayoutGuide
NSLayoutConstraint.activate([
// constrain scroll view to top, leading, trailing
scrollView.topAnchor.constraint(equalTo: v.topAnchor),
scrollView.leadingAnchor.constraint(equalTo: v.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: v.trailingAnchor),
// constrain scroll view height to 60% of view height
scrollView.heightAnchor.constraint(equalTo: v.heightAnchor, multiplier: 0.6),
// constrain stack view to all 4 sides of scroll view's contentLayoutGuide
stackView.topAnchor.constraint(equalTo: g.topAnchor),
stackView.bottomAnchor.constraint(equalTo: g.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
// constrain stack view height equal to scroll view height
stackView.heightAnchor.constraint(equalTo: scrollView.heightAnchor),
])
scrollView.isPagingEnabled = true
}
func loadSlides() -> [UIView] {
let container1 = ScrollViewSlide()
container1.mainImageForSubview.image = UIImage(named: "cricket1")
container1.mainLabel.text = "Container1"
let container2 = ScrollViewSlide()
container2.mainImageForSubview.image = UIImage(named: "cricket2")
container2.mainLabel.text = "Container2"
let container3 = ScrollViewSlide()
container3.mainImageForSubview.image = UIImage(named: "crisp_ocean")
container3.mainLabel.text = "Container3"
return [container1, container2, container3]
}
func setUpViewsForScrollView(slides : [UIView]) {
for container in slides {
stackView.addArrangedSubview(container)
container.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
}
}
func loadPageIndicator(_ mySlides : [UIView]) {
let myPageIndicator = pageIndicator
myPageIndicator.numberOfPages = mySlides.count
myPageIndicator.backgroundColor = .black
self.view.addSubview(myPageIndicator)
myPageIndicator.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
// width = 100, height = 30
myPageIndicator.widthAnchor.constraint(equalToConstant: 100.0),
myPageIndicator.heightAnchor.constraint(equalToConstant: 30.0),
// constrain top to 12-pts below bottom of scroll view
myPageIndicator.topAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 12.0),
// constrain centerX to centerX of scroll view
myPageIndicator.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor, constant: 0.0),
])
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageIndex = round(scrollView.contentOffset.x/view.frame.width)
pageIndicator.currentPage = Int(pageIndex)
}
}