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),
])
}
}