一开始的时候是UIScrollView直接嵌套UIImageView,滑动浏览都是正常的,但是不能伸缩,试了UIScrollVIew自身的zoom方法,也试用了pinch gesture的方法都无果,后来想到了用UIScrollView嵌套UIScrollVIew再嵌套UIImageView的方法实现,然后缩放用的是UIScrollView自身的缩放方法,成功,很棒。
载入图片是用的SDWebImage,提示框用的是MBProgressHUD
实现了在当前图片放大情况下,滑动到相邻的图片时对当前图片恢复到原始比例。以及缩小时保证图片在正中间。解决了滑动时显示多个“载入中”的BUG
以下是源码:(直接复制不能运行)
func showImages(theView:UIView,imageNamesTMP:[String])
{
println("showImages")
imageNames = imageNamesTMP
var numberOfImages:CGFloat = (CGFloat)(imageNames.count)
imageBigScrollView.contentSize = CGSizeMake(SCREENWIDTH * numberOfImages, SCREENHEIGHT)
imageSmallScrollViews = NSMutableArray()
for(var i = 0; i < (Int)(numberOfImages);i++)
{
var smallScrollView = UIScrollView(frame: CGRectMake(SCREENWIDTH * (CGFloat)(i), 0, SCREENWIDTH, SCREENHEIGHT))
smallScrollView.pagingEnabled = false
smallScrollView.contentSize = CGSizeMake(SCREENWIDTH, SCREENHEIGHT)
smallScrollView.delegate = self
smallScrollView.showsHorizontalScrollIndicator = false
smallScrollView.showsVerticalScrollIndicator = false
smallScrollView.minimumZoomScale = 0.2
smallScrollView.maximumZoomScale = 8
imageBigScrollView.addSubview(smallScrollView)
imageSmallScrollViews.addObject(smallScrollView)
}
var pageControlHeight:CGFloat = 20
imagePageControl = UIPageControl(frame: CGRectMake(0, SCREENHEIGHT - pageControlHeight, SCREENWIDTH, pageControlHeight))
theView.addSubview(imagePageControl)
var longGesture = UILongPressGestureRecognizer(target: self, action: "longPressed:")
imageBigScrollView.addGestureRecognizer(longGesture)
imagePageControl.numberOfPages = (Int)(numberOfImages)
imagePageControl.currentPage = 0
imagePageControl.backgroundColor = UIColor.clearColor()
imagePageControl.hidesForSinglePage = true
imagePageControl.defersCurrentPageDisplay = true
needToZoomIndex = imagePageControl.currentPage
imageViews = NSMutableArray()
imageFlag = NSMutableArray()
for(var i = 0; i < imageNames.count; i++)
{
imageViews.addObject(UIImageView())
imageFlag.addObject(0)
}
loadImageWithPage(0)
loadImageWithPage(1)
}
func loadImageWithPage(page:Int)
{
if(page < 0 || page >= imageNames.count)
{
return
}
var flag = imageFlag.objectAtIndex(page) as Int
var iView:UIImageView = imageViews.objectAtIndex(page) as UIImageView
if(flag == 0)
{
var frame = self.imageBigScrollView.frame
frame.origin.x = 0
frame.origin.y = 0
iView.userInteractionEnabled = true
iView.frame = frame
iView.contentMode = UIViewContentMode.ScaleAspectFit
(self.imageSmallScrollViews.objectAtIndex(page) as UIScrollView).addSubview(iView)
println("add one image:\(page)")
var hud:SMS_MBProgressHUD = SMS_MBProgressHUD.showMessagManually("载入中", toView: iView)
self.imageFlag.replaceObjectAtIndex(page, withObject: 1)
iView.sd_setImageWithPreviousCachedImageWithURL(NSURL(string: imageNames[page]), andPlaceholderImage: nil, options: SDWebImageOptions.ProgressiveDownload, progress: { (a, b) -> Void in
// println("\(page): \(b)")
// hud.progress = (Float)(a)/(Float)(b)
}, completed: { (tmpImage, err, cachType, url) -> Void in
hud.hide(true)
println("pic \(page) load complete")
if let error = err
{
}
else
{
self.imageFlag.replaceObjectAtIndex(page, withObject: 1)
self.imageViews.replaceObjectAtIndex(page, withObject: iView)
// iView.image.set
// CGRectMake(frame.size.width * (CGFloat)(page), (SCREENHEIGHT - image.size.height * SCREENWIDTH / image.size.width)/2, SCREENWIDTH, image.size.height * SCREENWIDTH / image.size.width)
// println(frame.width)
}
})
}
}
func scrollViewDidScroll(scrollView: UIScrollView) {
if(pageControlUsed == true)
{
return
}
var pageWidth = imageBigScrollView.frame.size.width
var page:Int = (Int)(floor((imageBigScrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1)
imagePageControl.currentPage = page
self.loadImageWithPage(page - 1)
self.loadImageWithPage(page)
self.loadImageWithPage(page + 1)
if(page != lastPageIndex)
{
setZoomToOne(lastPageIndex)
lastPageIndex = page
}
}
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
pageControlUsed = false
}
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
pageControlUsed = false
}
func setZoomToOne(page:Int)
{
if(page < 0 || page >= imageNames.count || lastSetIndex == page)
{
return
}
println("set:\(page) \(lastPageIndex)")
lastSetIndex = page
needToZoomIndex = page
(imageSmallScrollViews.objectAtIndex(page) as UIScrollView).setZoomScale(1, animated: true)
needToZoomIndex = imagePageControl.currentPage
}
func tapPressed(sender:UITapGestureRecognizer)
{
self.dismissViewControllerAnimated(true, completion: nil)
}
func longPressed(sender:UILongPressGestureRecognizer)
{
println("\(imagePageControl.currentPage)")
if(imagePageControl.currentPage != lastLongPressIndex)
{
lastLongPressIndex = imagePageControl.currentPage
UIActionSheet(title: "选择" , delegate: self, cancelButtonTitle: nil, destructiveButtonTitle: nil, otherButtonTitles: "保存图片","取消").showInView(self.view)
}
else
{
lastLongPressIndex = -1
}
}
func pinchPressed(sender:UIPinchGestureRecognizer)
{
println("pinch")
var iView:UIImageView = imageViews.objectAtIndex(imagePageControl.currentPage) as UIImageView
if(sender.state == UIGestureRecognizerState.Began)
{
beganScale = (imageSmallScrollViews.objectAtIndex(imagePageControl.currentPage) as UIScrollView).zoomScale
}
(imageSmallScrollViews.objectAtIndex(imagePageControl.currentPage) as UIScrollView).setZoomScale(beganScale * sender.scale, animated: true)
if(sender.state == UIGestureRecognizerState.Ended)
{
scrollViewEnd()
}
}
func scrollViewEnd()
{
// println("end")
var isv = imageSmallScrollViews.objectAtIndex(imagePageControl.currentPage) as UIScrollView
if(isv.zoomScale < 1.0)
{
println("set back 1")
isv.setZoomScale(1, animated: true)
}
else if(isv.zoomScale > 2.0)
{
isv.setZoomScale(2.0, animated: true)
}
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
// println("view for zoom")
return imageViews.objectAtIndex(needToZoomIndex) as UIImageView
}
func scrollViewDidZoom(scrollView: UIScrollView) {
var iView:UIImageView = imageViews.objectAtIndex(imagePageControl.currentPage) as UIImageView
var isv = imageSmallScrollViews.objectAtIndex(imagePageControl.currentPage) as UIScrollView
if(isv.zoomScale < 1.0)
{
isv.contentOffset = CGPointMake(-(isv.frame.width - iView.frame.size.width) / 2, -(isv.frame.height - iView.frame.size.height) / 2)
}
}
func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView!, atScale scale: CGFloat) {
scrollViewEnd()
}
func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
println("actionsheet:\(buttonIndex)")
if(buttonIndex == 0)
{
UIImageWriteToSavedPhotosAlbum((imageViews.objectAtIndex(imagePageControl.currentPage) as UIImageView).image, self, "imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:", nil)
}
}
func imageSavedToPhotosAlbum(image:UIImage, didFinishSavingWithError error:NSError?, contextInfo:AnyObject)
{
if let err = error
{
SMS_MBProgressHUD.showError("保存失败", toView: self.view)
}
else
{
SMS_MBProgressHUD.showCompleteMessage("保存成功", toView: self.view)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}