Swift 将 GestureRecognizer 添加到 UIStackView 之上的视图
Swift add GestureRecognizer to View on top of UIStackView
我正在尝试将 GestureRecognizer 添加到 UIView,它是 UIStackView 的排列子视图。我已经试过了 this or this。我还尝试为 userInteraction 启用所有基础视图,但它没有用。
当我将手势识别器添加到作为 stackView 的父视图的 imageView 时,点击就起作用了。奇怪的是,当我点击 "bannerView" 时它也会被触发,它是 stackView 的子视图,因此位于 imageView 的顶部。
在 stackViews 的 arrangedSubview 上识别点击手势的正确方法是什么?
这是我的代码:
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
var imageView: UIImageView!
var bannerStackView: UIStackView!
var bannerView: UIView!
override func loadView() {
let view = UIView()
view.backgroundColor = .white
self.view = view
setupImageView()
setupBannerStackView()
setupConstraints()
}
func setupImageView() {
let image = UIImage(named: "Apple.jpeg")
imageView = UIImageView(image: image)
imageView.backgroundColor = .red
view.addSubview(imageView)
}
func setupBannerStackView() {
bannerStackView = UIStackView()
bannerStackView.axis = .vertical
bannerStackView.alignment = .leading
bannerStackView.distribution = .equalCentering
bannerStackView.isUserInteractionEnabled = true
bannerView = UIView()
bannerView.backgroundColor = .blue
bannerStackView.addArrangedSubview(bannerView)
imageView.addSubview(bannerStackView)
/*
Also tried this but didn't work
*/
// let tapGesture = UITapGestureRecognizer(target: self, action:
#selector(onBannerTapped))
// bannerView.isUserInteractionEnabled = true
// bannerView.isUserInteractionEnabled = true
// bannerView.addGestureRecognizer(tapGesture)
for bannerView in bannerStackView.arrangedSubviews {
let tapGesture = UITapGestureRecognizer(target: self, action:
#selector(onBannerTapped))
bannerView.isUserInteractionEnabled = true
bannerView.addGestureRecognizer(tapGesture)
}
}
@objc func onBannerTapped() {
print("Banner view tapped!")
}
func setupConstraints() {
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 200).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 200).isActive = true
bannerStackView.translatesAutoresizingMaskIntoConstraints = false
bannerStackView.topAnchor.constraint(equalTo: imageView.topAnchor, constant: 10).isActive = true
bannerStackView.leadingAnchor.constraint(equalTo: imageView.leadingAnchor).isActive = true
bannerView.translatesAutoresizingMaskIntoConstraints = false
bannerView.heightAnchor.constraint(equalToConstant: 30).isActive = true
bannerView.widthAnchor.constraint(equalToConstant: 80).isActive = true
}
}
.isUserInteractionEnabled
级联到子视图。因此,即使我在子视图上将其设置为 true,如果子视图的父视图(或其父视图,以及在层次结构中)将 .isUserInteractionEnabled
设置为 false
,子视图将不会获得触摸事件。
因此,首先要做的是检查 .isUserInteractionEnabled
层次结构中的每个视图。
在你的函数中,删除这一行:
bannerStackView.isUserInteractionEnabled = true
然后在创建 tapGesture
后添加这些行:
print("imageView isUserInteractionEnabled:", imageView.isUserInteractionEnabled)
print("bannerStackView isUserInteractionEnabled:", bannerStackView.isUserInteractionEnabled)
print("bannerView isUserInteractionEnabled:", bannerView.isUserInteractionEnabled)
所以看起来像这样:
func setupBannerStackView() {
bannerStackView = UIStackView()
bannerStackView.axis = .vertical
bannerStackView.alignment = .leading
bannerStackView.distribution = .equalCentering
// remove this line (comment-it out)
// bannerStackView.isUserInteractionEnabled = true
bannerView = UIView()
bannerView.backgroundColor = .blue
bannerStackView.addArrangedSubview(bannerView)
imageView.addSubview(bannerStackView)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(onBannerTapped))
bannerView.addGestureRecognizer(tapGesture)
print("view isUserInteractionEnabled:", view.isUserInteractionEnabled)
print("imageView isUserInteractionEnabled:", imageView.isUserInteractionEnabled)
print("bannerStackView isUserInteractionEnabled:", bannerStackView.isUserInteractionEnabled)
print("bannerView isUserInteractionEnabled:", bannerView.isUserInteractionEnabled)
}
你应该看到这个输出:
view isUserInteractionEnabled: true
imageView isUserInteractionEnabled: false
bannerStackView isUserInteractionEnabled: true
bannerView isUserInteractionEnabled: true
这告诉你....你只需要添加:
imageView.isUserInteractionEnabled = true
我正在尝试将 GestureRecognizer 添加到 UIView,它是 UIStackView 的排列子视图。我已经试过了 this or this。我还尝试为 userInteraction 启用所有基础视图,但它没有用。
当我将手势识别器添加到作为 stackView 的父视图的 imageView 时,点击就起作用了。奇怪的是,当我点击 "bannerView" 时它也会被触发,它是 stackView 的子视图,因此位于 imageView 的顶部。
在 stackViews 的 arrangedSubview 上识别点击手势的正确方法是什么?
这是我的代码:
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
var imageView: UIImageView!
var bannerStackView: UIStackView!
var bannerView: UIView!
override func loadView() {
let view = UIView()
view.backgroundColor = .white
self.view = view
setupImageView()
setupBannerStackView()
setupConstraints()
}
func setupImageView() {
let image = UIImage(named: "Apple.jpeg")
imageView = UIImageView(image: image)
imageView.backgroundColor = .red
view.addSubview(imageView)
}
func setupBannerStackView() {
bannerStackView = UIStackView()
bannerStackView.axis = .vertical
bannerStackView.alignment = .leading
bannerStackView.distribution = .equalCentering
bannerStackView.isUserInteractionEnabled = true
bannerView = UIView()
bannerView.backgroundColor = .blue
bannerStackView.addArrangedSubview(bannerView)
imageView.addSubview(bannerStackView)
/*
Also tried this but didn't work
*/
// let tapGesture = UITapGestureRecognizer(target: self, action:
#selector(onBannerTapped))
// bannerView.isUserInteractionEnabled = true
// bannerView.isUserInteractionEnabled = true
// bannerView.addGestureRecognizer(tapGesture)
for bannerView in bannerStackView.arrangedSubviews {
let tapGesture = UITapGestureRecognizer(target: self, action:
#selector(onBannerTapped))
bannerView.isUserInteractionEnabled = true
bannerView.addGestureRecognizer(tapGesture)
}
}
@objc func onBannerTapped() {
print("Banner view tapped!")
}
func setupConstraints() {
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 200).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 200).isActive = true
bannerStackView.translatesAutoresizingMaskIntoConstraints = false
bannerStackView.topAnchor.constraint(equalTo: imageView.topAnchor, constant: 10).isActive = true
bannerStackView.leadingAnchor.constraint(equalTo: imageView.leadingAnchor).isActive = true
bannerView.translatesAutoresizingMaskIntoConstraints = false
bannerView.heightAnchor.constraint(equalToConstant: 30).isActive = true
bannerView.widthAnchor.constraint(equalToConstant: 80).isActive = true
}
}
.isUserInteractionEnabled
级联到子视图。因此,即使我在子视图上将其设置为 true,如果子视图的父视图(或其父视图,以及在层次结构中)将 .isUserInteractionEnabled
设置为 false
,子视图将不会获得触摸事件。
因此,首先要做的是检查 .isUserInteractionEnabled
层次结构中的每个视图。
在你的函数中,删除这一行:
bannerStackView.isUserInteractionEnabled = true
然后在创建 tapGesture
后添加这些行:
print("imageView isUserInteractionEnabled:", imageView.isUserInteractionEnabled)
print("bannerStackView isUserInteractionEnabled:", bannerStackView.isUserInteractionEnabled)
print("bannerView isUserInteractionEnabled:", bannerView.isUserInteractionEnabled)
所以看起来像这样:
func setupBannerStackView() {
bannerStackView = UIStackView()
bannerStackView.axis = .vertical
bannerStackView.alignment = .leading
bannerStackView.distribution = .equalCentering
// remove this line (comment-it out)
// bannerStackView.isUserInteractionEnabled = true
bannerView = UIView()
bannerView.backgroundColor = .blue
bannerStackView.addArrangedSubview(bannerView)
imageView.addSubview(bannerStackView)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(onBannerTapped))
bannerView.addGestureRecognizer(tapGesture)
print("view isUserInteractionEnabled:", view.isUserInteractionEnabled)
print("imageView isUserInteractionEnabled:", imageView.isUserInteractionEnabled)
print("bannerStackView isUserInteractionEnabled:", bannerStackView.isUserInteractionEnabled)
print("bannerView isUserInteractionEnabled:", bannerView.isUserInteractionEnabled)
}
你应该看到这个输出:
view isUserInteractionEnabled: true
imageView isUserInteractionEnabled: false
bannerStackView isUserInteractionEnabled: true
bannerView isUserInteractionEnabled: true
这告诉你....你只需要添加:
imageView.isUserInteractionEnabled = true