swift 自定义上下文菜单 previewprovider 无法点击里面的任何视图(使用点击手势)
swift custom context menu previewprovider can not click any view inside(using tapgesture)
我正在处理类似消息的反应,这就是我所做的(使用 contextMenu 中的 customProvider)
下面是我向 customProvider 控制器添加表情符号操作时的代码
private func addReactionList(_ items : [Reaction]) -> UIView{
let reactionView = UIView()
var arrangedSubviews: [UIView] = []
for reaction in items {
let imgView = UIImageView(image: AppUtils.reactionToImage(reaction: reaction))
imgView.isUserInteractionEnabled = true
imgView.frame = CGRect(x: 0, y: 0, width: iconHeight, height: iconHeight)
imgView.layer.cornerRadius = (imgView.frame.height) / 2
imgView.layer.masksToBounds = true
imgView.layer.borderColor = UIColor.clear.cgColor
imgView.layer.borderWidth = 0
imgView.contentMode = .scaleAspectFit
imgView.restorationIdentifier = reaction.Type
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(_:)))
tapGesture.delegate = self
tapGesture.numberOfTapsRequired = 1
tapGesture.delaysTouchesBegan = true
tapGesture.cancelsTouchesInView = false
imgView.isUserInteractionEnabled = true
imgView.addGestureRecognizer(tapGesture)
arrangedSubviews.append(imgView)
}
let stackView = UIStackView(arrangedSubviews: arrangedSubviews)
stackView.distribution = .fillEqually
stackView.spacing = padding
stackView.layoutMargins = UIEdgeInsets(top: padding, left: padding, bottom: padding, right: padding)
stackView.isLayoutMarginsRelativeArrangement = true
let width = (CGFloat(items.count) * iconHeight) + (CGFloat(items.count+1) * padding)
reactionView.frame = CGRect(x: 0, y: 0, width: width, height: iconHeight + 2 * padding)
reactionView.layer.cornerRadius = 12
reactionView.addSubview(stackView)
stackView.frame = reactionView.frame
stackView.isUserInteractionEnabled = false
reactionView.isUserInteractionEnabled = false
return reactionView
}
然后我将其添加到自定义提供程序 vc:
let actionsReacts = addReactionList(likeReactions)
let emojiReacts = addReactionList(emojiReactions)
if let snap = customView.snapshotView(afterScreenUpdates: true) as UIView?{
view.addSubview(snap)
view.addSubview(actionsReacts)
view.addSubview(emojiReacts)
let maxWidth = snap.frame.size.width >= actionsReacts.frame.size.width ? snap.frame.size.width : actionsReacts.frame.size.width
var currentSnapFrame = snap.frame
currentSnapFrame = CGRect(Int((maxWidth - snap.frame.size.width)) / 2, 0 , Int(snap.frame.size.width), Int(snap.frame.size.height))
snap.frame = currentSnapFrame
var currentActionsReactFrame = actionsReacts.frame
currentActionsReactFrame = CGRect(0, Int(snap.frame.size.height), Int(actionsReacts.frame.size.width), Int(actionsReacts.frame.size.height))
actionsReacts.frame = currentActionsReactFrame
var currentEmojiReactFrame = actionsReacts.frame
currentEmojiReactFrame = CGRect(0, Int(snap.frame.size.height) + Int(emojiReacts.frame.size.height), Int(emojiReacts.frame.size.width), Int(emojiReacts.frame.size.height))
emojiReacts.frame = currentEmojiReactFrame
preferredContentSize = CGSize(width: maxWidth, height: snap.frame.size.height + actionsReacts.frame.size.height + emojiReacts.frame.size.height)
}
但手势无法触发,我尝试将img更改为按钮,但仍然无法点击
@objc func handleTapGesture(_ sender : UITapGestureRecognizer){
let tappedImage = sender.view as! UIImageView
let reactionType = tappedImage.restorationIdentifier ?? ""
onSelectedReaction?(reactionType)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
我不知道为什么我不能点击任何地方,即使我试图添加手势点击到 viewcontroller 视图。谁能解释一下?提前致谢
我换了新的VC 英雄动画,好无聊,但这是我现在最好的选择
我试图根据您提供的内容重建您的演示应用程序,但我仍然不清楚您的代码是什么或它的行为方式。
有一件事我注意到您正在创建 n
手势识别器并将每个手势识别器连接到图像视图。
请尝试使用 1 个手势识别器。将它挂接到您的父视图,并在点击事件时,获取正在点击的子视图。
一些代码:
let tap = UITapGestureRecognizer(target: self, action: #selector(self.onViewTap))
parentView.addGestureRecognizer(tap)
@objc func onViewTap(_ sender: UITapGestureRecognizer) {
let point = sender.location(in: containerView)
if let hitSubview = parentView.hitTest(point, with: nil) {
// check which subview (imageView) is being hit by checking its tag or similar
}
我正在处理类似消息的反应,这就是我所做的(使用 contextMenu 中的 customProvider)
下面是我向 customProvider 控制器添加表情符号操作时的代码
private func addReactionList(_ items : [Reaction]) -> UIView{
let reactionView = UIView()
var arrangedSubviews: [UIView] = []
for reaction in items {
let imgView = UIImageView(image: AppUtils.reactionToImage(reaction: reaction))
imgView.isUserInteractionEnabled = true
imgView.frame = CGRect(x: 0, y: 0, width: iconHeight, height: iconHeight)
imgView.layer.cornerRadius = (imgView.frame.height) / 2
imgView.layer.masksToBounds = true
imgView.layer.borderColor = UIColor.clear.cgColor
imgView.layer.borderWidth = 0
imgView.contentMode = .scaleAspectFit
imgView.restorationIdentifier = reaction.Type
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(_:)))
tapGesture.delegate = self
tapGesture.numberOfTapsRequired = 1
tapGesture.delaysTouchesBegan = true
tapGesture.cancelsTouchesInView = false
imgView.isUserInteractionEnabled = true
imgView.addGestureRecognizer(tapGesture)
arrangedSubviews.append(imgView)
}
let stackView = UIStackView(arrangedSubviews: arrangedSubviews)
stackView.distribution = .fillEqually
stackView.spacing = padding
stackView.layoutMargins = UIEdgeInsets(top: padding, left: padding, bottom: padding, right: padding)
stackView.isLayoutMarginsRelativeArrangement = true
let width = (CGFloat(items.count) * iconHeight) + (CGFloat(items.count+1) * padding)
reactionView.frame = CGRect(x: 0, y: 0, width: width, height: iconHeight + 2 * padding)
reactionView.layer.cornerRadius = 12
reactionView.addSubview(stackView)
stackView.frame = reactionView.frame
stackView.isUserInteractionEnabled = false
reactionView.isUserInteractionEnabled = false
return reactionView
}
然后我将其添加到自定义提供程序 vc:
let actionsReacts = addReactionList(likeReactions)
let emojiReacts = addReactionList(emojiReactions)
if let snap = customView.snapshotView(afterScreenUpdates: true) as UIView?{
view.addSubview(snap)
view.addSubview(actionsReacts)
view.addSubview(emojiReacts)
let maxWidth = snap.frame.size.width >= actionsReacts.frame.size.width ? snap.frame.size.width : actionsReacts.frame.size.width
var currentSnapFrame = snap.frame
currentSnapFrame = CGRect(Int((maxWidth - snap.frame.size.width)) / 2, 0 , Int(snap.frame.size.width), Int(snap.frame.size.height))
snap.frame = currentSnapFrame
var currentActionsReactFrame = actionsReacts.frame
currentActionsReactFrame = CGRect(0, Int(snap.frame.size.height), Int(actionsReacts.frame.size.width), Int(actionsReacts.frame.size.height))
actionsReacts.frame = currentActionsReactFrame
var currentEmojiReactFrame = actionsReacts.frame
currentEmojiReactFrame = CGRect(0, Int(snap.frame.size.height) + Int(emojiReacts.frame.size.height), Int(emojiReacts.frame.size.width), Int(emojiReacts.frame.size.height))
emojiReacts.frame = currentEmojiReactFrame
preferredContentSize = CGSize(width: maxWidth, height: snap.frame.size.height + actionsReacts.frame.size.height + emojiReacts.frame.size.height)
}
但手势无法触发,我尝试将img更改为按钮,但仍然无法点击
@objc func handleTapGesture(_ sender : UITapGestureRecognizer){
let tappedImage = sender.view as! UIImageView
let reactionType = tappedImage.restorationIdentifier ?? ""
onSelectedReaction?(reactionType)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
我不知道为什么我不能点击任何地方,即使我试图添加手势点击到 viewcontroller 视图。谁能解释一下?提前致谢
我换了新的VC 英雄动画,好无聊,但这是我现在最好的选择
我试图根据您提供的内容重建您的演示应用程序,但我仍然不清楚您的代码是什么或它的行为方式。
有一件事我注意到您正在创建 n
手势识别器并将每个手势识别器连接到图像视图。
请尝试使用 1 个手势识别器。将它挂接到您的父视图,并在点击事件时,获取正在点击的子视图。
一些代码:
let tap = UITapGestureRecognizer(target: self, action: #selector(self.onViewTap))
parentView.addGestureRecognizer(tap)
@objc func onViewTap(_ sender: UITapGestureRecognizer) {
let point = sender.location(in: containerView)
if let hitSubview = parentView.hitTest(point, with: nil) {
// check which subview (imageView) is being hit by checking its tag or similar
}