I've got a UIButton and a couple of TextEdit's in a UIView. UIView itself is in a UIScrollView. Somehow UIButton can not be pressed in the structure I mentioned. Look at the following code:
private lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.showsVerticalScrollIndicator = true
scrollView.showsHorizontalScrollIndicator = false
scrollView.backgroundColor = .systemBrown
scrollView.translatesAutoresizingMaskIntoConstraints = false
return scrollView
}()
private lazy var contentView: UIView = {
let contentView = UIView()
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.backgroundColor = .yellow
contentView.isUserInteractionEnabled = true
return contentView
}()
private lazy var logInButton: UIButton = {
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.addTarget(self, action: #selector(loggedIn), for: .touchUpInside)
return button
}()
Now the following code show's how I added UIScrollView to my ViewController, then UIView as a subview to UIScrollView and then UIButton as a subview to UIView.
view.addSubview(scrollView)
scrollView.addSubview(contentView)
let safeAreaGuide = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: safeAreaGuide.leadingAnchor),
scrollView.widthAnchor.constraint(equalTo: safeAreaGuide.widthAnchor),
scrollView.trailingAnchor.constraint(equalTo: safeAreaGuide.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: safeAreaGuide.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: safeAreaGuide.bottomAnchor)
])
NSLayoutConstraint.activate([
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
])
contentView.addSubview(logInButton)
NSLayoutConstraint.activate([
logInButton.topAnchor.constraint(equalTo: logInInputContainer.bottomAnchor, constant: 16),
logInButton.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
logInButton.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
logInButton.heightAnchor.constraint(equalToConstant: 50)
])
Somehow UIButton is placed correctly on the screen yet can not be pressed. As a workaround I've tried adding UIButton directly to UIScrollView and it actually fixes the problem. It made me think that adding contentView.isUserInteractionEnabled = true
would be a solution for the original task. It didn't help though.
What's the root of the issue and how to make objects placed in a UIView which is placed in UIScrollView interactable?
when I run your code you are taking the wrong constraints, I just edit your constraints you can replace your code with the following and test if it works for you, in this piece of code, I just add the background colour to the button just to check the button's appearance.
private lazy var logInButton: UIButton = {
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .systemRed
button.addTarget(self, action: #selector(loggedIn), for:
.touchUpInside)
return button
}()
and the other piece of code that I change is
view.addSubview(scrollView)
scrollView.addSubview(contentView)
contentView.addSubview(logInButton)
let safeAreaGuide = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo:
safeAreaGuide.leadingAnchor),
scrollView.widthAnchor.constraint(equalTo:
safeAreaGuide.widthAnchor),
scrollView.trailingAnchor.constraint(equalTo:
safeAreaGuide.trailingAnchor),
scrollView.topAnchor.constraint(equalTo:
safeAreaGuide.topAnchor),
scrollView.bottomAnchor.constraint(equalTo:
safeAreaGuide.bottomAnchor)
])
NSLayoutConstraint.activate([
contentView.leadingAnchor.constraint(equalTo:
scrollView.leadingAnchor),
contentView.widthAnchor.constraint(equalTo:
scrollView.widthAnchor),
contentView.trailingAnchor.constraint(equalTo:
scrollView.trailingAnchor),
contentView.topAnchor.constraint(equalTo:
scrollView.topAnchor),
contentView.bottomAnchor.constraint(equalTo:
scrollView.bottomAnchor),
])
NSLayoutConstraint.activate([
logInButton.topAnchor.constraint(equalTo:
contentView.topAnchor, constant: 16),
logInButton.leadingAnchor.constraint(equalTo:
contentView.leadingAnchor, constant: 16),
logInButton.trailingAnchor.constraint(equalTo:
contentView.trailingAnchor, constant: -16),
logInButton.bottomAnchor.constraint(equalTo:
contentView.bottomAnchor, constant: -16),
logInButton.heightAnchor.constraint(equalToConstant: 50),
])
and the reason you were unable to tap on the button is you are taking the wrong constraints and the button is going outside the content view so you are unable to tap. now the final output will look like:
[ Please open the below link and check the ScreenShot of Simulator ][1]
[1]: https://i.sstatic.net/9otvC.png