英文:
Why does UITapGestureRecognizer not work properly for cell images in Swift collection view?
问题
我已为集合视图单元格图像添加了UITapGestureRecognizer,如下所示:
代码:使用此代码,如果我点击两个单元格图像,则两者都会显示。在这里,如果我点击第二个单元格图像,如何将第一个图像从前景中移除?
在这里,当我在newImageView之外(但在集合视图上)点击时,touchesBegan
不会被调用。是否有解决方法?
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FriendCollectionViewCell.cellId, for: indexPath) as! FriendCollectionViewCell
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(cellTappedMethod(_:)))
cell.profileImageView?.gestureRecognizers?.removeAll()
cell.profileImageView.isUserInteractionEnabled = true
cell.profileImageView.tag = indexPath.row
cell.profileImageView.addGestureRecognizer(tapGestureRecognizer)
return cell
}
@objc func cellTappedMethod(_ sender: UITapGestureRecognizer) {
let imageView = sender.view as! UIImageView
let newImageView = UIImageView(image: imageView.image)
newImageView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width * 0.7, height: 300.0)
UIView.animate(withDuration: 0.2) { [self] in
newImageView.center = CGPoint(x: UIScreen.main.bounds.center.x - 15, y: UIScreen.main.bounds.center.y - 200)
newImageView.backgroundColor = UIColor.clear
newImageView.contentMode = .scaleAspectFit
newImageView.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissFullscreenImage))
newImageView.addGestureRecognizer(tap)
self.view.addSubview(newImageView)
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
print("touch..outside")
if let sender = touch?.view?.gestureRecognizers?.first {
print(sender.view?.tag)
sender.view?.removeFromSuperview()
}
}
@objc func dismissFullscreenImage(sender: UITapGestureRecognizer) {
UIView.animate(withDuration: 0.2) { [self] in
sender.view?.removeFromSuperview()
}
}
如果我点击单元格图像,如何移除所有位于前景中的图像,请指导我。
英文:
I have added UITapGestureRecognizer for collectionview cell image like
code: with this code if i tap on two cell images then both are showing. Here if i tap on second cell image then how to remove first image from foreground
here touchesBegan
not calling when i tap on outside of the newImageView(but on collectionview) why? is there any solution for this
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FriendCollectionViewCell.cellId, for: indexPath) as! FriendCollectionViewCell
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(cellTappedMethod(_:)))
cell.profileImageView?.gestureRecognizers?.removeAll()
cell.profileImageView.isUserInteractionEnabled = true
cell.profileImageView.tag = indexPath.row
cell.profileImageView.addGestureRecognizer(tapGestureRecognizer)
return cell
}
@objc func cellTappedMethod(_ sender: UITapGestureRecognizer){
let imageView = sender.view as! UIImageView
let newImageView = UIImageView(image: imageView.image)
newImageView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width * 0.7, height: 300.0)//UIScreen.main.bounds
UIView.animate(withDuration: 0.2) { [self] in
newImageView.center = CGPoint(x: UIScreen.main.bounds.center.x - 15, y: UIScreen.main.bounds.center.y - 200)
newImageView.backgroundColor = UIColor.clear
newImageView.contentMode = .scaleAspectFit
newImageView.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissFullscreenImage))
newImageView.addGestureRecognizer(tap)
self.view.addSubview(newImageView)
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{
let touch = touches.first
print("touch..outside")
var sender = UITapGestureRecognizer()
print(sender.view?.tag)
if ((touch?.view) != nil){
print("touch..")
sender.view?.removeFromSuperview()
}
}
@objc func dismissFullscreenImage(sender: UITapGestureRecognizer) {
UIView.animate(withDuration: 0.2) { [self] in
sender.view?.removeFromSuperview()
}
}
if i tap on cell image then how to remove all image which are in foreground. please guide me
答案1
得分: 1
为了实现在点击新单元格图像时从前景中删除先前的图像的所需行为,您可以跟踪当前显示的图像视图,并在添加新图像之前将其删除。
var currentImageView: UIImageView?
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FriendCollectionViewCell.cellId, for: indexPath) as! FriendCollectionViewCell
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(cellTappedMethod(_:)))
cell.profileImageView?.gestureRecognizers?.removeAll()
cell.profileImageView.isUserInteractionEnabled = true
cell.profileImageView.tag = indexPath.row
cell.profileImageView.addGestureRecognizer(tapGestureRecognizer)
return cell
}
@objc func cellTappedMethod(_ sender: UITapGestureRecognizer) {
let imageView = sender.view as! UIImageView
currentImageView?.removeFromSuperview()
let newImageView = UIImageView(image: imageView.image)
newImageView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width * 0.7, height: 300.0)
newImageView.center = CGPoint(x: UIScreen.main.bounds.center.x - 15, y: UIScreen.main.bounds.center.y - 200)
newImageView.backgroundColor = UIColor.clear
newImageView.contentMode = .scaleAspectFit
newImageView.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissFullscreenImage))
newImageView.addGestureRecognizer(tap)
self.view.addSubview(newImageView)
currentImageView = newImageView
}
@objc func dismissFullscreenImage(sender: UITapGestureRecognizer) {
sender.view?.removeFromSuperview()
currentImageView = nil
}
在这段代码中,currentImageView
变量在类级别声明,以跟踪当前显示在屏幕上的图像视图。当单元格图像被点击时,先前的图像视图(如果有的话)会从父视图中删除,然后添加新的图像视图。currentImageView
变量会被更新为新的图像视图,当关闭全屏图像时,会清除引用以表示当前没有显示图像视图。
至于在点击 newImageView
外部时 touchesBegan
未被调用的问题,这是因为 newImageView
位于集合视图的上方并拦截了触摸事件。一种解决方法是子类化 UICollectionView
并在子类中覆盖 touchesBegan
方法。
class MyCollectionView: UICollectionView {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
}
}
以上是您要求的代码部分的翻译。
英文:
To achieve the desired behavior of removing the previous image from the foreground when tapping on a new cell image, you can keep track of the currently displayed image view and remove it before adding a new one.
var currentImageView: UIImageView?
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FriendCollectionViewCell.cellId, for: indexPath) as! FriendCollectionViewCell
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(cellTappedMethod(_:)))
cell.profileImageView?.gestureRecognizers?.removeAll()
cell.profileImageView.isUserInteractionEnabled = true
cell.profileImageView.tag = indexPath.row
cell.profileImageView.addGestureRecognizer(tapGestureRecognizer)
return cell
}
@objc func cellTappedMethod(_ sender: UITapGestureRecognizer) {
let imageView = sender.view as! UIImageView
currentImageView?.removeFromSuperview()
let newImageView = UIImageView(image: imageView.image)
newImageView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width * 0.7, height: 300.0)
newImageView.center = CGPoint(x: UIScreen.main.bounds.center.x - 15, y: UIScreen.main.bounds.center.y - 200)
newImageView.backgroundColor = UIColor.clear
newImageView.contentMode = .scaleAspectFit
newImageView.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissFullscreenImage))
newImageView.addGestureRecognizer(tap)
self.view.addSubview(newImageView)
currentImageView = newImageView
}
@objc func dismissFullscreenImage(sender: UITapGestureRecognizer) {
sender.view?.removeFromSuperview()
currentImageView = nil
}
In this code the currentImageView
variable is declared at the class level to keep track of the image view currently displayed on the screen. When a cell image is tapped, the previous image view (if any) is removed from the superview before adding a new one. The currentImageView
variable is updated with the new image view, and when dismissing the full-screen image, the reference is cleared to indicate that no image view is currently displayed.
As for the issue with touchesBegan
not being called when tapping outside the newImageView
, it's because the newImageView
is on top of the collection view and intercepts the touch events. One solution is to subclass UICollectionView
and override the touchesBegan
method in the subclass.
class MyCollectionView: UICollectionView {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论