誰かが私を助けてくれることを望んでいた。ユーザーが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
}
}
ImageScrollを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
}
UIScrollViewによるUIImageViewピンチズーム|| Swift 3およびXcode 8レターの画像ズームiOSYoutube video 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
}
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()
}
}
私の見解では、問題はcurrentScaleの決定です。 imageViewのスケールを変更するため、常に1になります。次のようにcurrentScaleを割り当てる必要があります。
let currentScale = self.imageView?.frame.size.width / self.imageView?.bounds.size.width
Swift 3ソリューション
デフォルトでは、UIImageView's
userInteration
は無効になっています。 UIImageView
にジェスチャーを追加する前に有効にします。
imgView.isUserInteractionEnabled = true
画面座標の2つのタッチのポイントに相対的なスケール係数
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
}
おそらく間違った方法で検索してしまいました。
ContentMode = .centreでimageViewを取得した後です。しかし、私はそれがズームインしすぎていると判断し、ズームアウトする方法を探していました。方法は次のとおりです。
self.imageView.contentScaleFactor = 3
1は、何かをしているようです。 1つ以上がズームアウトします... 3つは私には有効ですが、テストする必要があります。
Swift 3.のピンチとダブルタップの両方を使用したズーム機能について、回答を投稿しました こちら 。
最大の問題は、func
の最後にあると思います。sender.scale = 1
があります。そのコード行を削除すると、毎回画像が跳ね返るだけではなりません。
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: UIPinchMethodRecognizer) {
guard let sender.view != nil 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を使用して、スケール制限を設定できます。
これは古い質問ですが、元のコードの何が問題なのかを説明する答えは見当たりません。
この行:
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
自己を送信者に変更する(および強制的にビューをラップ解除する)ことにより、スケール計算は期待どおりに機能します。