提问人:Vladimir Kovalev 提问时间:11/6/2023 最后编辑:HangarRashVladimir Kovalev 更新时间:11/10/2023 访问量:29
UIButton不响应使用UIScrollView触摸的ViewController
UIButtons do not respond to touched on ViewController with UIScrollView
问:
我正在开发嵌入了UIScrollView的ViewController。我有:view -> scrollView -> contentView (UIView) -> backgroundImageView -> SettingsItemsView (UIView) -> UIButtons。因此,在 SettingsItemsView 内的 UIButtons 上添加目标后,它们都不会响应触摸。由于UIScrollView,很可能存在冲突,但我没有设法解决它。提前致谢!代码已附上
控制器
final class SettingsViewController: ViewController {
var viewModel: SettingsViewModel!
private let scrollView: UIScrollView = {
let sv = UIScrollView()
sv.alwaysBounceVertical = true
sv.delaysContentTouches = false
return sv
}()
private let contentView: UIView = {
let view = UIView()
return view
}()
private let backgroundImageView: UIImageView = {
let iv = UIImageView()
iv.image = Asset.Images.settingsBackground.image
iv.contentMode = .scaleToFill
iv.isUserInteractionEnabled = true
iv.clipsToBounds = true
return iv
}()
private let settingsItemsView: SettingsItemsView = {
let view = SettingsItemsView()
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let titleLabel = UILabel()
titleLabel.text = "Settings"
if let font = FontFamily.JosefinSans.semiBold.font(size: 24) {
titleLabel.font = font
}
titleLabel.textColor = Asset.Colors.white.color
navigationItem.titleView = titleLabel
}
override func arrangeSubviews() {
super.arrangeSubviews()
view.addSubview(backgroundImageView)
backgroundImageView.addSubview(scrollView)
scrollView.addSubview(contentView)
contentView.addSubview(settingsItemsView)
}
override func setupViewConstraints() {
super.setupViewConstraints()
scrollView.translatesAutoresizingMaskIntoConstraints = false
contentView.translatesAutoresizingMaskIntoConstraints = false
backgroundImageView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
backgroundImageView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
backgroundImageView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
backgroundImageView.topAnchor.constraint(equalTo: view.topAnchor),
backgroundImageView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
settingsItemsView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
settingsItemsView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
settingsItemsView.widthAnchor.constraint(equalToConstant: 343),
settingsItemsView.heightAnchor.constraint(equalToConstant: 350),
settingsItemsView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 40)
])
}
}
设置查看
final class SettingsItemsView: UIView {
// Temporary image
private var tempImage = UIImage(systemName: "apple.logo")
private lazy var items: [SettingsItem] = [
SettingsItem(option: SettingsOptions.privacy),
SettingsItem(option: SettingsOptions.termsOfUse),
SettingsItem(option: SettingsOptions.feedback),
SettingsItem(option: SettingsOptions.share),
SettingsItem(option: SettingsOptions.rate),
]
private func configureOptions() -> [SettingsItemButton] {
var options: [SettingsItemButton] = []
for item in items {
let button = SettingsItemButton(image: item.option.image!, name: item.option.name, option: item.option)
button.clipsToBounds = true
button.backgroundColor = .clear
button.addTarget(self, action: #selector(testTapped(_:)), for: .touchUpInside)
button.isUserInteractionEnabled = true
options.append(button)
}
return options
}
@objc func testTapped(_ sender: SettingsItemButton) {
print("Tapped: \(sender)")
}
private let stackView: UIStackView = {
let stack = UIStackView()
stack.axis = .vertical
stack.distribution = .equalCentering
stack.spacing = 0
return stack
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupView()
}
private func setupView() {
addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.topAnchor.constraint(equalTo: topAnchor).isActive = true
stackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
setupStyle()
addSubviews()
}
private func addSubviews() {
configureOptions().forEach { stackView.addArrangedSubview($0) }
}
private func setupStyle() {
backgroundColor = Asset.Colors.tabBarBackground.color
layer.cornerRadius = 22
clipsToBounds = true
}
}
按钮
final class SettingsItemButton: UIButton {
var option: SettingsOptions!
private let itemImage: UIImageView = {
let btn = UIImageView()
btn.tintColor = Asset.Colors.white.color
btn.contentMode = .scaleAspectFill
btn.backgroundColor = .blue
return btn
}()
private let itemCheckMark: UIImageView = {
let btn = UIImageView()
btn.image = Asset.Images.arrowRight.image
btn.tintColor = Asset.Colors.white.color
btn.backgroundColor = .blue
return btn
}()
private let itemName: UILabel = {
let label = UILabel()
if let customFont = FontFamily.Outfit.medium.font(size: 17) {
label.font = customFont
}
label.textColor = Asset.Colors.white.color
label.backgroundColor = .blue
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupSubviews()
setupConstraints()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
convenience init(image: UIImage, name: String, option: SettingsOptions) {
self.init(frame: .zero)
configure(image: image, name: name, option: option)
}
func configure(image: UIImage, name: String, option: SettingsOptions) {
self.option = option
itemImage.image = image
itemName.text = name
}
func setupConstraints() {
itemImage.translatesAutoresizingMaskIntoConstraints = false
itemName.translatesAutoresizingMaskIntoConstraints = false
itemCheckMark.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
itemImage.centerYAnchor.constraint(equalTo: centerYAnchor),
itemImage.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 24),
itemImage.heightAnchor.constraint(equalToConstant: 24),
itemImage.widthAnchor.constraint(equalToConstant: 24),
itemName.centerYAnchor.constraint(equalTo: centerYAnchor),
itemName.leadingAnchor.constraint(equalTo: itemImage.trailingAnchor, constant: 16),
itemCheckMark.centerYAnchor.constraint(equalTo: centerYAnchor),
itemCheckMark.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
itemCheckMark.heightAnchor.constraint(equalToConstant: 32),
itemCheckMark.widthAnchor.constraint(equalToConstant: 24)
])
}
func setupSubviews() {
addSubview(itemImage)
addSubview(itemName)
addSubview(itemCheckMark)
}
}
我尝试使用 UICollectionView 而不是 UIStackView。但是单元格上没有按钮,单元本身也对触摸没有反应。我还尝试将不同层上的isUserInteractionEnabled属性设置为false,以防止一些冲突。
答:
0赞
DonMag
11/10/2023
#1
在挖掘您的代码并进行一些编辑以使其运行之后......
您的按钮不会响应点击,因为包含它们的堆栈视图超出了其超级视图的边界。
在你的,你没有身高。如果设置:SettingsViewController
contentView
.clipsToBounds = true
private let contentView: UIView = {
let view = UIView()
// set clips to bounds true
view.clipsToBounds = true
return view
}()
并运行该应用程序,您甚至不会再看到按钮。
如果添加此行:
NSLayoutConstraint.activate([
settingsItemsView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
settingsItemsView.widthAnchor.constraint(equalToConstant: 343),
settingsItemsView.heightAnchor.constraint(equalToConstant: 350),
settingsItemsView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 40),
// add this line
settingsItemsView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -20.0),
])
你现在将有一个高度......你会再次看到按钮......您现在可以点击它们。contentView
评论
SettingsViewModel
SettingsItem
SettingsItem