在激活iOS 13上下文菜单时,如何防止UIScrollView放大一吨?

在激活iOS 13上下文菜单时,如何防止UIScrollView放大一吨?,ios,uiscrollview,ios13,uicontextmenuinteraction,uicontextmenuconfiguration,Ios,Uiscrollview,Ios13,Uicontextmenuinteraction,Uicontextmenuconfiguration,如果您有一个可以放大的UIScrollView,并且您在滚动视图内的视图中添加了一个iOS 13上下文菜单交互(例如:aUIImageView),当您执行交互时,它会奇怪地立即放大图像,然后将其缩小以显示上下文菜单,然后在退出此关联菜单时,它会将图像放大很远。它似乎超出了UIImageView的范围 StackOverflow似乎不支持嵌入视频/GIF,因此,下面是Imgur上的一段视频,展示了我的意思: 有没有办法防止这种行为?例如,在WKWebView(aUIScrollView子类)中,长

如果您有一个可以放大的
UIScrollView
,并且您在滚动视图内的视图中添加了一个iOS 13上下文菜单交互(例如:a
UIImageView
),当您执行交互时,它会奇怪地立即放大图像,然后将其缩小以显示上下文菜单,然后在退出此关联菜单时,它会将图像放大很远。它似乎超出了UIImageView的范围

StackOverflow似乎不支持嵌入视频/GIF,因此,下面是Imgur上的一段视频,展示了我的意思:

有没有办法防止这种行为?例如,在
WKWebView
(a
UIScrollView
子类)中,长时间按图像不会显示此行为

如果您想在一个简单的新Xcode项目中对其进行测试,下面是一段简单的代码来展示它的一个示例:

导入UIKit
类RootViewController:UIViewController、UIScrollViewDelegate、UIContextMenuInteractionDelegate{
让scrollView=UIScrollView()
让imageView=UIImageView(图像:UIImage(名为:“cat.jpg”)!)
重写func viewDidLoad(){
super.viewDidLoad()
[view,scrollView].forEach{$0.backgroundColor=.black}
scrollView.delegate=self
scrollView.frame=view.bounds
scrollView.addSubview(imageView)
scrollView.contentSize=imageView.frame.size
view.addSubview(滚动视图)
//设置缩放比例
让scaleToFit=min(scrollView.bounds.width/imageView.bounds.width,scrollView.bounds.height/imageView.bounds.height)
scrollView.maximumZoomScale=max(1.0,缩放比例)
scrollView.minimumZoomScale=scaleToFit<1.0?scaleToFit:1.0
scrollView.zoomScale=scaleToFit
//添加上下文菜单支持
imageView.isUserInteractionEnabled=true
imageView.addInteraction(UIContextMenuInteraction(委托:self))
}
重写func viewdilayoutsubviews(){
super.viewDidLayoutSubviews()
scrollView.frame=view.bounds
}
//MARK:-UIScrollView
func VIEWFOR缩放(在scrollView:UIScrollView中)->UIView{
返回图像视图
}
//标记:-上下文菜单
func contextMenuInteraction(u交互:UIContextMenuInteraction,configurationForMenuAtLocation位置:CGPoint)->UIContextMenuConfiguration{
在中返回UIContextMenuConfiguration(标识符:nil,预览提供程序:{()->UIViewController
归零
}){(建议元素)->UIMenu?在
变量子项:[UIAction]=[]
附加(UIAction(标题:“Upvote”,图像:UIImage(系统名:“arrow.up”){(操作)在
})
附加(UIAction(标题:“向下投票”,图像:UIImage(系统名称:“arrow.down”){(操作)在
})
返回UIMenu(标题:“”,图像:nil,标识符:nil,选项:[],子项:子项)
}
}
}

如果您也喜欢,这里有一个
cat.jpg

我想我解决了它。解决方案的要点是,不要像您直观地认为的那样将交互添加到图像视图本身,而是将其添加到外部视图,然后使用
UITargetPreview
API将上下文菜单预览集中到图像视图的矩形上。通过这种方式,所有人都可以避免接触出问题的图像视图,而只需转到其父视图,然后“裁剪”到子视图,这样子视图就可以保持愉快的状态。:)

以下是我最终得到的代码:

导入UIKit
类RootViewController:UIViewController、UIScrollViewDelegate、UIContextMenuInteractionDelegate{
让wrapperView=UIView()
让scrollView=UIScrollView()
让imageView=UIImageView(图像:UIImage(名为:“cat.jpg”)!)
重写func viewDidLoad(){
super.viewDidLoad()
wrapperView.frame=view.bounds
view.addSubview(包装视图)
[view,wrapperView,scrollView].forEach{$0.backgroundColor=.black}
scrollView.delegate=self
scrollView.frame=view.bounds
scrollView.addSubview(imageView)
scrollView.contentSize=imageView.frame.size
wrapperView.addSubview(scrollView)
//设置缩放比例
让scaleToFit=min(scrollView.bounds.width/imageView.bounds.width,scrollView.bounds.height/imageView.bounds.height)
scrollView.maximumZoomScale=max(1.0,缩放比例)
scrollView.minimumZoomScale=scaleToFit<1.0?scaleToFit:1.0
scrollView.zoomScale=scaleToFit
//添加上下文菜单支持
wrapperView.addInteraction(UIContextMenuInteraction(委托:self))
}
//MARK:-UIScrollView
func VIEWFOR缩放(在scrollView:UIScrollView中)->UIView{
返回图像视图
}
//标记:-上下文菜单
func contextMenuInteraction(u交互:UIContextMenuInteraction,configurationForMenuAtLocation位置:CGPoint)->UIContextMenuConfiguration{
scrollView.zoomScale=scrollView.minimumZoomScale
在中返回UIContextMenuConfiguration(标识符:nil,预览提供程序:{()->UIViewController
归零
}){(建议元素)->UIMenu?在
变量子项:[UIAction]=[]
附加(UIAction(标题:“Upvote”,图像:UIImage(系统名:“arrow.up”){(操作)在
})
附加(UIAction(标题:“向下投票”,图像:UIImage(系统名称:“arrow.down”){(操作)在
})
返回UIMenu(标题:“”,图像:nil,标识符:nil,选项:[],子项:子项)
}
}
func contextMenuInteraction(交互:UIContextMenuInteraction,预览带有配置:UIContextMenuConfiguration的高亮菜单)->UITargeted预览{
let parameters=UIPreviewParameters()
让rect=imageView.convert(imageView.bounds,to:wrapperView)
参数