How to implement a scrollView inside inputAccessoryView [Swift] - swift

In my swift app I'm working with inputActivityView, really hard, and my idea is to add a scroll view to this view with 2 subviews and paging enable.
Here's what I've done, I think the problem are constraints but I don't know how to solve it.
lazy var scrollView: UIScrollView = {
let sv = UIScrollView(frame: self.bounds)
sv.backgroundColor = .blue
sv.isPagingEnabled = true
sv.contentSize = .init(width: 2 * self.frame.width, height: 54)
return sv
}()
override init(frame: CGRect) { // the init of the customInputAccessoryView
super.init(frame: frame)
setup()
}
override var intrinsicContentSize: CGSize {
return .zero
}
func setup() {
backgroundColor = .red
autoresizingMask = .flexibleHeight
addSubview(scrollView)
scrollView.fillSuperview()
scrollView.heightAnchor.constraint(equalToConstant: 54).isActive = true
firstView = UIView(frame: .init(origin: .zero, size: .init(width: frame.width, height: 54)))
firstView.frame.origin = .zero
firstView.backgroundColor = .gray
firstView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(firstView)
secondView = UIView(frame: firstView.bounds)
secondView.frame.origin.x = frame.width
secondView.backgroundColor = .lightGray
secondView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(secondView)
addConstraints()
}
private func addConstraints() {
NSLayoutConstraint.activate([
firstView.widthAnchor.constraint(equalToConstant: frame.width),
firstView.heightAnchor.constraint(equalToConstant: 54)
])
}
How can I set the constraints for the subviews, because in this way appear only the first view, and I can't scroll to the second one.

Yes, you're missing some constraints.
First, no need to instantiate views with UIView(frame: ...) if you are then setting .translatesAutoresizingMaskIntoConstraints = false because the frame you just gave it will be ignored.
Second, if you have your constraints setup correctly, no need to set a scroll view's .contentSize
// don't do this
//sv.contentSize = .init(width: 2 * self.frame.width, height: 54)
Third, when configuring subviews of a scroll view, make sure your constraints define Top / Leading / Bottom / Trailing AND Width and Height.
Here's an edited version of your code to try:
class MyInputAccessoryView: UIView {
lazy var scrollView: UIScrollView = {
let sv = UIScrollView()
sv.backgroundColor = .blue
sv.isPagingEnabled = true
// no need for this
//sv.contentSize = .init(width: 2 * self.frame.width, height: 54)
return sv
}()
var firstView: UIView!
var secondView: UIView!
override init(frame: CGRect) { // the init of the customInputAccessoryView
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var intrinsicContentSize: CGSize {
return .zero
}
func setup() {
backgroundColor = .red
autoresizingMask = .flexibleHeight
addSubview(scrollView)
//scrollView.fillSuperview()
scrollView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: topAnchor),
scrollView.bottomAnchor.constraint(equalTo: bottomAnchor),
scrollView.leadingAnchor.constraint(equalTo: leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: trailingAnchor),
scrollView.heightAnchor.constraint(equalToConstant: 54),
])
//firstView = UIView(frame: .init(origin: .zero, size: .init(width: frame.width, height: 54)))
//firstView.frame.origin = .zero
firstView = UIView()
firstView.backgroundColor = .gray
firstView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(firstView)
//secondView = UIView(frame: firstView.bounds)
//secondView.frame.origin.x = frame.width
secondView = UIView()
secondView.backgroundColor = .lightGray
secondView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(secondView)
addConstraints()
}
private func addConstraints() {
NSLayoutConstraint.activate([
// make both subviews equal width and height to scrollView
firstView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
firstView.heightAnchor.constraint(equalTo: scrollView.heightAnchor),
secondView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
secondView.heightAnchor.constraint(equalTo: scrollView.heightAnchor),
// constrain firstView Leading and Top to scrollView contentLayoutGuide Leading and Top
firstView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
firstView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
// constrain secondView Leading to firstView Trailing
secondView.leadingAnchor.constraint(equalTo: firstView.trailingAnchor),
// constrain secondView Top / Bottom / Trailing Top to scrollView contentLayoutGuide Top / Bottom / Trailing
secondView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
secondView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
secondView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
])
}
}

Related

How to dynamically change UIStackView height based on content size?

I have a view below that I'm trying to dynamically change the height of based on the heights of the subviews in the content view. Currently, I'm setting the scrollView and contentView's contentSize with a static height of "screenHeight + 1000". What steps can I take to dynamically update the height property?
import Foundation
import UIKit
import TinyConstraints
class ViewController: UIViewController {
// MARK: - PROPERTIES
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
var contentViewSize = CGSize(width: screenWidth, height: screenHeight + 1000)
// MARK: - VIEW METHODS
override func viewDidLoad() {
super.viewDidLoad()
addSubviews()
constrainSubviews()
}
// MARK: - VIEW OBJECTS
lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView(frame: .zero)
scrollView.frame = view.bounds
scrollView.contentSize = contentViewSize
scrollView.autoresizingMask = .flexibleHeight
scrollView.showsHorizontalScrollIndicator = true
scrollView.bounces = true
return scrollView
}()
lazy var contentView: UIView = {
let contentView = UIView()
contentView.frame.size = contentViewSize
return contentView
}()
lazy var topView: UIStackView = { ... }()
lazy var nutritionView: UIStackView = { ... }()
lazy var ingredientsView: UIStackView = { ... }()
lazy var instructionsView: UIStackView = { ... }()
fileprivate func addSubviews() {
view.addSubview(scrollView)
scrollView.addSubview(contentView)
contentView.addSubview(topView)
contentView.addSubview(nutritionView)
contentView.addSubview(ingredientsView)
contentView.addSubview(instructionsView)
}
fileprivate func constrainSubviews() {
let stack = [topView, nutritionView, ingredientsView, instructionsView]
contentView.stack(stack, spacing: screenHeight * 0.03)
contentView.centerXToSuperview()
contentView.topToSuperview(offset: screenHeight * 0.04)
contentView.width(screenWidth * 0.8)
}
}
You should add a scroll view and inside that add and stackview, and inside the stack view add the views, and the scroll view will increase dynamically, like this code.
class ViewController: UIViewController {
let scrollView = UIScrollView()
lazy var contentStackView = UIStackView(arrangedSubviews: [getView(height: 500, color: .red),
getView(height: 600, color: .blue),
getView(height: 70, color: .gray),
getView(height: 80,color: .yellow)])
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.view.backgroundColor = .white
contentStackView.axis = .vertical
setupConstraints()
}
func setupConstraints() {
self.view.addSubview(scrollView)
self.scrollView.addSubview(contentStackView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
contentStackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: self.view.topAnchor),
scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
contentStackView.topAnchor.constraint(equalTo: self.scrollView.topAnchor),
contentStackView.leadingAnchor.constraint(equalTo: self.scrollView.leadingAnchor),
contentStackView.trailingAnchor.constraint(equalTo: self.scrollView.trailingAnchor),
contentStackView.bottomAnchor.constraint(equalTo: self.scrollView.bottomAnchor),
contentStackView.widthAnchor.constraint(equalTo: self.scrollView.widthAnchor)
])
}
func getView(height: Double, color: UIColor) -> UIView {
let view = UIView()
view.backgroundColor = color
view.translatesAutoresizingMaskIntoConstraints = false
view.heightAnchor.constraint(equalToConstant: height).isActive = true
return view
}
}

Unable to simultaneously satisfy constraints of InputAccessoryView

I have an InputAccessoryView with a single button in. However, I am getting the following output.
I have set up my InputAccessoryView in my ViewController as below;
lazy var customInputView: ButtonInputView = {
let frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 50)
let view = ButtonInputView(frame: frame)
view.doneButton.addTarget(self, action: #selector(signIn), for: .touchUpInside)
return view
}()
override var inputAccessoryView: UIView? {
return customInputView
}
Xcode is breaking the height constraint of 50 set in the frame of my view. Any reason why??
CUSTOM ACCESSORY INPUT VIEW CLASS
class ButtonInputView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setUpView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
lazy var doneButton: UIButton = {
let view = UIButton()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = Color.accent
view.setTitle("Done", for: .normal)
view.titleLabel?.font = Font.mainButton
view.layer.cornerRadius = 19
return view
}()
let separator: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .opaqueSeparator
return view
}()
private func setUpView() {
backgroundColor = Color.background
addSubview(doneButton)
addSubview(separator)
let separatorHeight = (1 / (UIScreen.main.scale))
if let titleLabelText = doneButton.titleLabel?.text {
doneButton.widthAnchor.constraint(equalToConstant: titleLabelText.width(usingFont: Font.mainButton) + 32).isActive = true
}
NSLayoutConstraint.activate([
separator.topAnchor.constraint(equalTo: topAnchor),
separator.leadingAnchor.constraint(equalTo: leadingAnchor),
separator.trailingAnchor.constraint(equalTo: trailingAnchor),
separator.heightAnchor.constraint(equalToConstant: separatorHeight),
doneButton.topAnchor.constraint(equalTo: separator.bottomAnchor, constant: 6),
doneButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
doneButton.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -6),
])
}
override var intrinsicContentSize: CGSize {
return CGSize.zero
}
override func didMoveToWindow() {
super.didMoveToWindow()
if #available(iOS 11.0, *) {
if let window = window {
bottomAnchor.constraint(lessThanOrEqualToSystemSpacingBelow: window.safeAreaLayoutGuide.bottomAnchor,
multiplier: 1.0).isActive = true
}
}
}
}

UIScrollView not scrolling w/ programmatic autolayout constraints

I am trying to understand how to use a UIScrollView programmatically.
When I give my content a size that does not fit on screen though, it does not scroll.
final class ProfileView: UIView {
private var isIpad: Bool {
return UIDevice.current.userInterfaceIdiom == .pad
}
private lazy var headerImageView: UIImageView = {
let iv = UIImageView(frame: .zero)
iv.translatesAutoresizingMaskIntoConstraints = false
iv.heightAnchor.constraint(equalToConstant: 600).isActive = true
iv.backgroundColor = .purple
return iv
}()
private lazy var profileImageView: UIImageView = {
let iv = UIImageView(frame: .zero)
iv.translatesAutoresizingMaskIntoConstraints = false
[iv.heightAnchor, iv.widthAnchor].forEach { $0.constraint(equalToConstant: 170).isActive = true }
iv.layer.cornerRadius = 170 / 2
iv.layer.borderColor = .white
iv.layer.borderWidth = 3
iv.layer.masksToBounds = true
iv.contentMode = .scaleAspectFill
iv.clipsToBounds = true
iv.backgroundColor = .red
return iv
}()
private(set) lazy var nameLabel: UILabel = {
let label = UILabel(frame: .zero)
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "Foo\nBar"
label.numberOfLines = 2
return label
}()
private lazy var contentScrollView: UIScrollView = {
let sv = UIScrollView(frame: .zero)
sv.translatesAutoresizingMaskIntoConstraints = false
return sv
}()
override init(frame: CGRect) {
super.init(frame: frame)
configureLayout()
}
required init?(coder: NSCoder) {
return nil
}
private func configureLayout() {
addSubview(contentScrollView)
[headerImageView, profileImageView, nameLabel].forEach { contentScrollView.addSubview($0) }
let compactConstraints = [
contentScrollView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
contentScrollView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
contentScrollView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor),
contentScrollView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),
headerImageView.topAnchor.constraint(equalTo: topAnchor),
headerImageView.leadingAnchor.constraint(equalTo: leadingAnchor),
headerImageView.trailingAnchor.constraint(equalTo: trailingAnchor),
profileImageView.centerYAnchor.constraint(equalTo: headerImageView.bottomAnchor),
profileImageView.centerXAnchor.constraint(equalTo: centerXAnchor),
nameLabel.topAnchor.constraint(equalTo: profileImageView.bottomAnchor, constant: 16),
nameLabel.centerXAnchor.constraint(equalTo: profileImageView.centerXAnchor),
]
NSLayoutConstraint.activate(compactConstraints)
}
}
This gives me the following -
The header image pushes the name label and avatar off screen and scrolling does not work.
I've read a bunch about giving the scroll view a huge offset so it scrolls, but that surely cannot be correct.
You need to create the constraints of all the subviews to the scrollView , add width constraint to the header img = profileview width and finally make bottom of label = bottom of the scrollview to make it infer it's height
let compactConstraints = [
contentScrollView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
contentScrollView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
contentScrollView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor),
contentScrollView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),
headerImageView.topAnchor.constraint(equalTo:contentScrollView.topAnchor),
headerImageView.leadingAnchor.constraint(equalTo:contentScrollView.leadingAnchor),
headerImageView.trailingAnchor.constraint(equalTo:contentScrollView.trailingAnchor),
headerImageView.widthAnchor.constraint(equalTo: self.widthAnchor) // add this
profileImageView.centerYAnchor.constraint(equalTo: headerImageView.bottomAnchor),
profileImageView.centerXAnchor.constraint(equalTo: centerXAnchor),
nameLabel.topAnchor.constraint(equalTo: profileImageView.bottomAnchor, constant: 16),
nameLabel.centerXAnchor.constraint(equalTo: profileImageView.centerXAnchor),
nameLabel.bottomAnchor.constraint(equalTo: contentScrollView.bottomAnchor) // and this
]

UIScrollview doesn't work once subviews added

I'm new to working with ScrollViews, and I'm doing it all programatically. I must be missing something super simple, but when I have no subviews, the scrollview shows up properly and scrolls up and down. But any time I add any subviews, the whole thing refuses to show up at all.
class DetailedPostScrollView: UIScrollView {
let topLabel: UILabel = {
let label = UILabel()
label.text = "this is the top"
return label
}()
let bottomLabel: UILabel = {
let label = UILabel()
label.text = "this is the bottom"
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentSize = CGSize(width: frame.width, height: 2000)
alwaysBounceVertical = true
addSubviewUsingAutoLayout(topLabel, bottomLabel)
topLabel.centerXAnchor.constrain(to: self.centerXAnchor)
topLabel.widthAnchor.constrain(to: 200)
topLabel.heightAnchor.constrain(to: 50)
topLabel.topAnchor.constrain(to: self.topAnchor, with: 100)
bottomLabel.centerXAnchor.constrain(to: self.centerXAnchor)
bottomLabel.widthAnchor.constrain(to: 200)
bottomLabel.heightAnchor.constrain(to: 50)
bottomLabel.bottomAnchor.constrain(to: self.bottomAnchor)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
And in my viewController, I instantiate and add the scroll view
let detailedPostScrollView = DetailedPostScrollView(frame: UIScreen.main.bounds)
detailedPostScrollView.backgroundColor = UIColor.purple
view.addSubviewUsingAutoLayout(detailedPostScrollView)
Again, I"m sure it's something super simple but I checked out all the questions and tutorial videos and couldn't see where I"m going wrong. Thanks for your help.
Edit: It seems to work fine when I do it all programmatically from a viewcontroller, as follows :
let scrollView: UIScrollView = {
let sv = UIScrollView()
sv.contentSize = CGSize(width: view.frame.width, height: 2000)
sv.backgroundColor = UIColor.purple
return sv
}()
view.addSubviewUsingAutoLayout(scrollView)
scrollView.topAnchor.constrain(to: view.topAnchor, with: 100)
scrollView.leadingAnchor.constrain(to: view.leadingAnchor)
scrollView.trailingAnchor.constrain(to: view.trailingAnchor)
scrollView.bottomAnchor.constrain(to: view.bottomAnchor)
let topLabel: UILabel = {
let label = UILabel()
label.text = "this is the top"
return label
}()
scrollView.addSubviewUsingAutoLayout(topLabel)
topLabel.centerXAnchor.constrain(to: scrollView.centerXAnchor)
topLabel.widthAnchor.constrain(to: 200)
topLabel.heightAnchor.constrain(to: 50)
topLabel.topAnchor.constrain(to: scrollView.topAnchor)
Something is off when I create a custom scrollview and instantiate that in my vc.
Try this :
class ViewController : UIViewController , UIScrollViewDelegate{
var scrollView : UIScrollView! ;
var containerView = UIView();
var contentSize : CGSize {
get {
return CGSize(width: view.frame.width, height: 2000);
}
}
override func viewDidLoad() {
super.viewDidLoad();
setupScrollView();
setupItems();
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews();
self.scrollView.frame = self.view.bounds;
containerView.frame = CGRect(x: 0, y: 0, width: contentSize.width, height: contentSize.height);
}
private func setupScrollView() {
scrollView = UIScrollView();
scrollView.delegate = self;
scrollView.backgroundColor = .white;
scrollView.contentSize = contentSize;
self.view.addSubview(scrollView);
containerView.backgroundColor = .purple;
self.scrollView.addSubview(containerView);
}
private func setupItems() {
let topButton = UIButton();
topButton.translatesAutoresizingMaskIntoConstraints = false;
topButton.setTitle("TOP BUTTON", for: .normal);
topButton.setTitleColor(.white, for: .normal);
self.containerView.addSubview(topButton);
let bottomTextField = UITextField();
bottomTextField.translatesAutoresizingMaskIntoConstraints = false;
bottomTextField.borderStyle = .roundedRect;
bottomTextField.placeholder = "BOTTOM TEXT FIELD";
self.containerView.addSubview(bottomTextField);
topButton.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true;
topButton.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 50).isActive = true;
topButton.widthAnchor.constraint(equalToConstant: 100).isActive = true;
topButton.heightAnchor.constraint(equalToConstant: 50).isActive = true;
bottomTextField.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true;
bottomTextField.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -50).isActive = true;
bottomTextField.widthAnchor.constraint(equalToConstant: 200).isActive = true;
bottomTextField.heightAnchor.constraint(equalToConstant: 40).isActive = true;
}
}
Set the scroll view frame to view bound in viewDidLayoutViews instead of using the layout , and add a container view as a subview for scroll view and set the size to same content size for scroll view again in viewDidLayoutViews so when ever user rotate the phone he get the correct width , and finally add all your views to container view .

UIScrollView showing subview not correctly

I'm trying to show simple custom view into scrollView. Here's my code :
struct scrollViewDataStruct {
let title: String?
let image: UIImage?
}
class ViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
var scrollViewData = [scrollViewDataStruct]()
override func viewDidLoad() {
super.viewDidLoad()
scrollViewData = [
scrollViewDataStruct(title: "First", image: #imageLiteral(resourceName: "iPhone 8 Copy 2")),
scrollViewDataStruct(title: "Second", image: #imageLiteral(resourceName: "iPhone 8 Copy 3"))
]
self.scrollView.backgroundColor = .yellow
scrollView.contentSize.width = self.scrollView.frame.width * CGFloat(scrollViewData.count)
var i = 0
for _ in scrollViewData {
let view = CustomView(frame: CGRect(x: self.scrollView.frame.width * CGFloat(i), y: 0, width: scrollView.frame.width, height: self.scrollView.frame.height))
self.scrollView.addSubview(view)
i += 1
}
// Do any additional setup after loading the view, typically from a nib.
}
}
class CustomView: UIView {
let imageView: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.backgroundColor = UIColor.blue
return imageView
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.addSubview(imageView)
imageView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
imageView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
imageView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
As you can see, the CustomView's frame = scrollView's frame but when i ran application it's not as I expected :
Then, in storyboard, i change device from iphone8 to iphone 8 plus and run again. It's show CustomView correctly. I have no idea, the scrollView is always correct but the CustomView is not .
Any suggest ?
Your problem is that you are accessing the frame of the scrollView before Auto Layout has run and established the size of the frame for the actual device. A quick fix is to move your setup code into an override of viewDidLayoutSubviews.
You have to be careful though, because unlike viewDidLoad, viewDidLayoutSubviews will run more than once, so you have to make sure you don't add your views multiple times.
// property - have we set up the views yet?
var setup = false
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if !setup {
scrollView.contentSize.width = self.scrollView.frame.width * CGFloat(scrollViewData.count)
var i = 0
for _ in scrollViewData {
let view = CustomView(frame: CGRect(x: self.scrollView.frame.width * CGFloat(i), y: 0, width: scrollView.frame.width, height: self.scrollView.frame.height))
self.scrollView.addSubview(view)
i += 1
}
setup = true
}
}
You should consider using constraints to place your views within your scrollView content instead of messing with the frame calculations, then Auto Layout would just automatically do the right thing.
In viewDidLoad, UI component will suppose to have the size you have taken in storyboard.
There are 2 ways to do this:
1. Use autoresizingMask property
autoresizingMask property will resize the view, if its containerView's frames changed
var i = 0
for _ in scrollViewData {
let view = CustomView(frame: CGRect(x: self.scrollView.frame.width * CGFloat(i), y: 0, width: scrollView.frame.width, height: self.scrollView.frame.height))
view.autoresizingMask = .flexibleHeight
self.scrollView.addSubview(view)
i += 1
}
2. Use fixed parameters, say UIScreen.main.bounds.size.height
Just update your code for custom view's height with reference to screen height rather than scroll view's height. It will work fine
var i = 0
let height = UIScreen.main.bounds.size.height
for _ in scrollViewData {
let view = CustomView(frame: CGRect(x: self.scrollView.frame.width * CGFloat(i), y: 0, width: scrollView.frame.width, height: height))
self.scrollView.addSubview(view)
i += 1
}