J'ai un problème avec le pincement zoomant un UIImageView
qui est situé dans un UIScrollView
. L'image effectue un zoom en réponse aux entrées de pincement de l'utilisateur, mais l'image effectue un zoom et devient plus grande jusqu'à ce qu'elle occupe tout l'écran plutôt que de rester dans les limites de mon UIScrollView
. J'ai regardé un tas de questions, d'articles et de vidéos sur YouTube pour essayer de trouver la source du problème mais je n'ai rien trouvé.Swift - UIImageAfficher les zooms plus grands que UIScrollView
Les questions suivantes semblent SO être vaguement liées, mais je ne pouvais pas encore résoudre mon problème après avoir regardé les:
- content size of UIScrollView
- UIScrollView with scaled UIImageView using autolayout
- UIScrollView squashes UIImageView image
- Swift UIImageView Stretched Aspect
- UIImageView pinch zoom swift
Mon UIScrollView
est créé dans mon storyboard et j'ai utilisé les contraintes de disposition créées dans le constructeur de l'interface pour l'ancrer en place. J'ai défini le délégué de la vue de défilement à viewDidLoad()
(et j'ai ajouté UIScrollViewDelegate
au début de ma classe). Le UIImageView
est créé par programme. Je déclare la vue de l'image en haut de la classe comme ci-dessous:
class VCImageViewer: UIViewController, UIScrollViewDelegate {
@IBOutlet weak var lblImageTitle: UILabel!
@IBOutlet weak var btnBack: UIButton!
@IBOutlet weak var scrollView: UIScrollView!
var imageView:UIImageView = UIImageView() // <-- Image view
-je ajouter alors la vue de l'image en tant que vue sous ma UIScrollView
avec la ligne de suivi du code, appelé au cours viewDidLoad()
:
self.scrollView.addSubview(self.imageView)
Après avoir ajouté la vue de l'image à la vue déroulante, je charge une image dans la vue de l'image. Je récupère l'image d'une URL et la charge en utilisant le code suivant. Encore une fois, cela s'appelle viewDidLoad()
.
self.imageView.image = UIImage(data: data)
self.imageView.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: (self.imageView.image?.size)!)
if self.imageView.image != nil {
self.lblError.isHidden = true
self.FormatImageViewerWithImage()
}
Cela confirme que l'image a correctement chargé, cache une étiquette d'avertissement, j'afficheraient si elle avait pas, et demande self.FormatImageViewerWithImage()
, ce qui est ci-dessous:
func FormatImageViewerWithImage() {
// Constraints
let constraintImageViewTop:NSLayoutConstraint = NSLayoutConstraint(item: self.imageView, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: self.scrollView, attribute: NSLayoutAttribute.top, multiplier: 1, constant: 0)
let constraintImageViewBottom:NSLayoutConstraint = NSLayoutConstraint(item: self.imageView, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutRelation.equal, toItem: self.scrollView, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 0)
let constraintImageViewLeft:NSLayoutConstraint = NSLayoutConstraint(item: self.imageView, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: self.scrollView, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 0)
let constraintImageViewRight:NSLayoutConstraint = NSLayoutConstraint(item: self.imageView, attribute: NSLayoutAttribute.right, relatedBy: NSLayoutRelation.equal, toItem: self.scrollView, attribute: NSLayoutAttribute.right, multiplier: 1, constant: 0)
self.view.addConstraints([constraintImageViewTop, constraintImageViewBottom, constraintImageViewLeft, constraintImageViewRight])
self.scrollView.contentSize = self.imageView.image!.size
self.scrollView.clipsToBounds = false
let scrollViewFrame = scrollView.frame
let scaleWidth = scrollViewFrame.size.width/self.scrollView.contentSize.width
let scaleHeight = scrollViewFrame.size.height/self.scrollView.contentSize.height
let minScale = min(scaleWidth, scaleHeight)
self.scrollView.minimumZoomScale = minScale
self.scrollView.maximumZoomScale = 1.0
self.scrollView.zoomScale = minScale
}
J'ai aussi mis en œuvre scrollViewDidZoom
avec :
func scrollViewDidZoom(_ scrollView: UIScrollView) {
self.CentreScrollViewContents()
}
func CentreScrollViewContents() {
let boundsSize = self.scrollView.bounds.size
var contentsFrame = self.imageView.frame
if contentsFrame.size.width < boundsSize.width {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width)/2
} else {
contentsFrame.origin.x = 0
}
if contentsFrame.size.height < boundsSize.height {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height)/2
} else {
contentsFrame.origin.y = 0
}
self.imageView.frame = contentsFrame
}
et viewForZooming
avec:
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return self.imageView
}
J'ai vu des questions précédentes (y compris certaines énumérées ci-dessus) qui suggéraient d'ajouter du code à viewWillLayoutSubviews()
, mais je n'ai eu aucun succès avec cela, donc mon viewWillLayoutSubviews()
est vide.
Quelqu'un peut-il voir quelque chose que je fais mal?
modifiez ceci: self.scrollView.clipsToBounds = faux à ce self.scrollView.clipsToBounds = true –
@MohammadBashirSidani Légende! Merci beaucoup, j'étais en train de m'arracher les cheveux. Si vous voulez l'ajouter comme réponse, je l'accepterai pour vous. –
très heureux que cela a fonctionné! Je vais l'ajouter comme réponse, merci! –