我希望有人能帮助我。我试图允许用户在 UIImageView 上捏缩放(允许最大和最小级别)。但由于某种原因,它不能正常工作。图像放大一点然后又弹回来。谢谢你。
这是缩放功能
func zoom(sender:UIPinchGestureRecognizer) {
if sender.state == .Ended || sender.state == .Changed {
let currentScale = self.view.frame.size.width / self.view.bounds.size.width
var newScale = currentScale*sender.scale
if newScale < 1 {
newScale = 1
}
if newScale > 9 {
newScale = 9
}
let transform = CGAffineTransformMakeScale(newScale, newScale)
self.imageView?.transform = transform
sender.scale = 1
}
}
UIImageView 与 UIScrollView 捏合缩放 || swift 3 和 Xcode 8 中的图像缩放 ios letter Youtube 视频 URL
class PhotoDetailViewController: UIViewController, UIScrollViewDelegate {
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var imgPhoto: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 6.0
// scrollView.delegate = self - it is set on the storyboard.
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imgPhoto
}
我决定将 imageView 添加到 UIScrollView 中。它允许用户缩放和平移。这是我使用的代码。
为了设置最大/最小缩放,我使用了:
scrollImg.minimumZoomScale = 1.0
scrollImg.maximumZoomScale = 10.0
这是其余的代码。
var vWidth = self.view.frame.width
var vHeight = self.view.frame.height
var scrollImg: UIScrollView = UIScrollView()
scrollImg.delegate = self
scrollImg.frame = CGRectMake(0, 0, vWidth!, vHeight!)
scrollImg.backgroundColor = UIColor(red: 90, green: 90, blue: 90, alpha: 0.90)
scrollImg.alwaysBounceVertical = false
scrollImg.alwaysBounceHorizontal = false
scrollImg.showsVerticalScrollIndicator = true
scrollImg.flashScrollIndicators()
scrollImg.minimumZoomScale = 1.0
scrollImg.maximumZoomScale = 10.0
defaultView!.addSubview(scrollImg)
imageView!.layer.cornerRadius = 11.0
imageView!.clipsToBounds = false
scrollImg.addSubview(imageView!)
我也必须添加这个
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return self.imageView
}
Swift 3 及以上函数原型
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return self.mainImage
}
支持 Swift 5.1,您可以创建
UIImageView
的扩展,如下所示:
extension UIImageView {
func enableZoom() {
let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(startZooming(_:)))
isUserInteractionEnabled = true
addGestureRecognizer(pinchGesture)
}
@objc
private func startZooming(_ sender: UIPinchGestureRecognizer) {
let scaleResult = sender.view?.transform.scaledBy(x: sender.scale, y: sender.scale)
guard let scale = scaleResult, scale.a > 1, scale.d > 1 else { return }
sender.view?.transform = scale
sender.scale = 1
}
}
swift 4 的选项
class ViewController: UIViewController, UIScrollViewDelegate {
@IBOutlet weak var scrolView: UIScrollView!
@IBOutlet weak var imgPhoto: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
scrolView.delegate = self
scrolView.minimumZoomScale = 1.0
scrolView.maximumZoomScale = 10.0
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imgPhoto
}
}
您可以使用开源的ImageScrollView,一个可缩放和可滚动的图像视图。 http://github.com/huynguyencong/ImageScrollView
像这个开源的,将ImageView添加到ScrollView
open class ImageScrollView: UIScrollView {
var zoomView: UIImageView? = nil
}
extension ImageScrollView: UIScrollViewDelegate{
public func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return zoomView
}
public func scrollViewDidZoom(_ scrollView: UIScrollView) {
adjustFrameToCenter()
}
}
使用 Swift 5.0,它对我来说是这样的:
let myImageView = UIImageView(image: myImage)
myImageView.isUserInteractionEnabled = true
let pinchMethod = UIPinchGestureRecognizer(target: self, action: #selector(pinchImage(sender:)))
myImageView.addGestureRecognizer(pinchMethod)
@objc func pinchImage(sender: UIPinchGestureRecognizer) {
guard let sender = sender.view else { return }
if let scale = (sender.view?.transform.scaledBy(x: sender.scale, y: sender.scale)) {
guard scale.a > 1.0 else { return }
guard scale.d > 1.0 else { return }
sender.view?.transform = scale
sender.scale = 1.0
}
}
您可以使用scale.a、scale.b、scale.c、scale.d、scale.tx和scale.ty来设置规模限制。
在我看来,问题在于你对 currentScale 的确定。它始终等于 1,因为您更改了 imageView 的比例。您应该按如下方式指定 currentScale:
let currentScale = self.imageView?.frame.size.width / self.imageView?.bounds.size.width
Swift 3 解决方案
默认情况下,
UIImageView's
userInteration
已禁用。在 UIImageView
中添加任何手势之前启用它。
imgView.isUserInteractionEnabled = true
相对于屏幕中两次触摸点的比例因子 坐标
var lastScale:CGFloat!
func zoom(gesture:UIPinchGestureRecognizer) {
if(gesture.state == .began) {
// Reset the last scale, necessary if there are multiple objects with different scales
lastScale = gesture.scale
}
if (gesture.state == .began || gesture.state == .changed) {
let currentScale = gesture.view!.layer.value(forKeyPath:"transform.scale")! as! CGFloat
// Constants to adjust the max/min values of zoom
let kMaxScale:CGFloat = 2.0
let kMinScale:CGFloat = 1.0
var newScale = 1 - (lastScale - gesture.scale)
newScale = min(newScale, kMaxScale / currentScale)
newScale = max(newScale, kMinScale / currentScale)
let transform = (gesture.view?.transform)!.scaledBy(x: newScale, y: newScale);
gesture.view?.transform = transform
lastScale = gesture.scale // Store the previous scale factor for the next pinch gesture call
}
}
Swift 3 解决方案
这是我使用的代码。我将imageView添加到scrollView作为子视图。
class ZoomViewController: UIViewController,UIScrollViewDelegate {
@IBOutlet weak var scrollView:UIScrollView!
@IBOutlet weak var imageView:UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 10.0//maximum zoom scale you want
scrollView.zoomScale = 1.0
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imageView
}
[2022 年 9 月,Swift 5]
对我来说似乎效果很好的方法之一是将图像视图嵌入到滚动视图中,您可以快速查看我正在共享的库,以便更好地理解,以保持这个答案简短。我已经建立了这个小型库并将其用于生产应用程序。您可以安装或将文件复制粘贴到您的项目中。作为 UIView 来使用是非常容易的,如果需要的话,可以听听它的委托以获取更多选项。
该库名为InteractiveImageView,它支持iOS 11.0及以上版本,链接到GitHub: https://github.com/egzonpllana/InteractiveImageView
我认为最大的问题是在你的
func
的末尾,你有sender.scale = 1
。如果删除该行代码,您的图像不应每次都反弹回来。
这是一个老问题,但我没有看到任何答案来解释原始代码的问题。
这一行:
let currentScale = self.view.frame.size.width / self.view.bounds.size.width
正在主视图而不是 imageView 上工作,因此比例计算始终为 ~1
这个简单的改变使它的行为符合预期
let currentScale = sender.view!.frame.size.width / sender.view!.bounds.size.width
通过将 self 更改为发送者(并强制视图展开),比例计算将按预期进行。
我最终来到这里,可能是寻找错误的方式。
我在将 imageView 设置为 contentMode = .centre 后。 但我认为它放大得太大了,我正在寻找一种方法来缩小它。 方法如下:
self.imageView.contentScaleFactor = 3
1 就好像你在做任何事情。超过 1 会缩小... 3 对我有用,但你需要测试一下。
确认使用 Xcode 15 | iOS 17 | iOS 17斯威夫特 5 |故事板
我发现这个 YouTube 视频 (https://www.youtube.com/watch?v=0Tz0vI721c8) 是一个更好的示例。它特别有助于设置正确的约束。