![](/img/trans.png)
[英]UITapGestureRecognizer for UIView in Scroll View doesn't work
[英]UITapGestureRecognizer in custom UIView doesn't work
Swift 5/Xcode 12.4
我為我的自定義MarkerView
創建了一個 xib 文件 - 布局非常簡單:
- View
-- StackView
--- DotLabel
--- NameLabel
默認情況下, View
和StackView
在檢查器中都設置為“啟用用戶交互”。 DotLabel
和NameLabel
沒有,但勾選它們的框似乎並沒有真正改變任何東西。
在運行時,我在ViewController
中創建 MarkerViews(僅用於測試目的一個 atm)並將它們添加到已經包含圖像的ScrollView
(這可行):
override func viewDidAppear(_ animated: Bool) {
createMarkers()
setUpMarkers()
}
private func createMarkers() {
let marker = MarkerView()
marker.setUp("Some Text")
markers.append(marker)
scrollView.addSubview(marker)
marker.alpha = 0.0
}
private func setUpMarkers() {
for (i,m) in markers.enumerated() {
m.frame.origin = CGPoint(x: (i+1)*100,y: (i+1)*100)
m.alpha = 1.0
}
}
這些 MarkerViews 應該是可點擊的,所以我添加了一個UITapGestureRecognizer
但鏈接的 function 永遠不會被調用。 這是我完整的 MarkerView:
class MarkerView: UIView {
@IBOutlet weak var stackView: UIStackView!
@IBOutlet weak var dotLabel: UILabel!
@IBOutlet weak var nameLabel: UILabel!
let nibName = "MarkerView"
var contentView:UIView?
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() {
guard let view = loadViewFromNib() else { return }
view.frame = self.bounds
self.addSubview(view)
contentView = view
let gesture = UITapGestureRecognizer(target: self, action: #selector(self.clickedMarker))
self.addGestureRecognizer(gesture)
}
func loadViewFromNib() -> UIView? {
let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: nibName, bundle: bundle)
return nib.instantiate(withOwner: self, options: nil).first as? UIView
}
func setUp(_ name:String) {
nameLabel.text = name
nameLabel.sizeToFit()
stackView.sizeToFit()
}
@objc private func clickedMarker() {
print("Clicked Marker!")
}
}
其他問題建議在添加手勢識別器之前添加self.isUserInteractionEnabled = true
。 我什至為 StackView 和兩個標簽都啟用了它,並且還嘗試將手勢識別器添加到 ScrollView 但沒有任何幫助。
為什么手勢識別器不工作,我該如何解決這個問題?
編輯:根據 Sweeper 的建議,我的代碼現在如下所示:
class MarkerView: UIView, UIGestureRecognizerDelegate {
.....
func commonInit() {
guard let view = loadViewFromNib() else { return }
view.frame = self.bounds
let gesture = UITapGestureRecognizer(target: self, action: #selector(self.clickedMarker))
gesture.delegate = self
self.isUserInteractionEnabled = true
self.addGestureRecognizer(gesture)
self.addSubview(view)
contentView = view
}
.....
func gestureRecognizer(_: UIGestureRecognizer, _ otherGestureRecognizer: UIGestureRecognizer) -> Bool {
print("gestureRecognizer")
return true
}
}
“gestureRecognizer”永遠不會打印到控制台。
@Sweeper鏈接的問題的已接受答案下方的評論之一給出了一個很好的提示:
內容視圖的大小(記錄它)是多少?
print(self.frame.size)
print(contentView.frame.size)
在我的應用程序中都打印(0.0, 0.0)
。 UITapGestureRecognizer
附加到self
,因此即使它有效,也根本沒有可以點擊的區域讓它識別點擊。
解決方案:設置UITapGestureRecognizer
附加到的UIView
的大小:
stackView.layoutIfNeeded()
stackView.sizeToFit()
self.layoutIfNeeded()
self.sizeToFit()
對我不起作用,之后大小仍然是(0.0, 0.0)
。 相反,我直接設置self
的大小:
self.frame.size = stackView.frame.size
這也設置了contentView
的大小(因為它是MarkerView
的孩子),但當然也需要正確設置stackView
的大小。 您可以自己添加孩子的寬度/高度(包括間距/邊距)或簡單地調用:
stackView.layoutIfNeeded()
stackView.sizeToFit()
完成的代碼:
func setUp(_ name:String) {
nameLabel.text = name
//nameLabel.sizeToFit() //Not needed anymore
stackView.layoutIfNeeded() //Makes sure that the labels already use the proper size after updating the text
stackView.sizeToFit()
self.frame.size = stackView.frame.size
let gesture = UITapGestureRecognizer(target: self, action: #selector(self.onClickStackView))
self.addGestureRecognizer(gesture)
}
規格:
delegate
和覆蓋func gestureRecognizer(_: UIGestureRecognizer, _ otherGestureRecognizer: UIGestureRecognizer) -> Bool
總是返回true
,這可能是一個替代方案,但我沒有設法讓那個版本工作 - function 從來沒有叫。 如果有人知道該怎么做,請隨時將其發布為替代解決方案。UITapGestureRecognizer
,這在commonInit
中並不常見,因為標簽的文本和所有內容的大小還沒有在那里設置。 可以在附加識別器后添加更多文本,但如果使用上述代碼,則超出原始長度(在附加識別器時)的所有內容都將不可點擊。stackView
的),但可以簡單地將其設置為透明顏色。stackView
而不是self
的工作方式相同。 您甚至可以使用UILabel
,但默認情況下它們的“用戶交互已啟用”處於關閉狀態 - 首先在“屬性檢查器”(“視圖”部分中的復選框)或代碼( myLabel.isUserInteractionEnabled = true
)中啟用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.