美文网首页
iOS Swift 仿微信朋友圈实现图片点击放大查看

iOS Swift 仿微信朋友圈实现图片点击放大查看

作者: 艾欧尼亚 | 来源:发表于2019-12-07 18:56 被阅读0次

    效果图:


    RPReplay.gif

    实现思路

    scrollView 具有放大缩小的功能,实现图片的放大与缩小的思路就是将imageView放在scrollView上,双击时调用scrollView的

    @available(iOS 3.0, *)
        open func zoom(to rect: CGRect, animated: Bool)
    

    来实现imageView的放大与缩小
    Demo地址

    实现步骤

    1.两个初始化方法

    // 通过图片url数组初始化
    init(urlArr: [String],number: Int)
    
    // 通过图片数组初始化
    init(_ Images: [UIImage],number: Int)
    

    在初始化方法中初始化backScrollView 和承载imageView的scrollView,并给imageView和scrollView添加点击手势
    2.承载imageView的scrollView设置代理方法

    extension ShowBigImgView : UIScrollViewDelegate {
        // 当scrollview 尝试进行缩放的时候
        func viewForZooming(in scrollView: UIScrollView) -> UIView? {
            let offsetX = self.backScroll.contentOffset.x
            let tagValue = offsetX / ScreenW
            return self.backScroll.viewWithTag(Int(tagValue))?.viewWithTag(100 + Int(tagValue))
        }
        
        // 当缩放完毕的时候调用
        func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
            printLog(message: "缩放结束-\(scale)")
        }
        
        // 当正在缩放的时候
        func scrollViewDidZoom(_ scrollView: UIScrollView) {
            printLog(message: "正在缩放")
            
            let offsetX = self.backScroll.contentOffset.x
            let tagValue = offsetX / ScreenW
            
            //获取到这个scrollview
            var centerX = self.backScroll.center.x
            var centerY = self.backScroll.center.y
            
            centerX = scrollView.contentSize.width > scrollView.frame.size.width ?
                scrollView.contentSize.width/2:centerX
            centerY = scrollView.contentSize.height > scrollView.frame.size.height ?
                scrollView.contentSize.height/2:centerY
            scrollView.viewWithTag(100 + Int(tagValue))?.center = CGPoint(x: centerX, y: centerY)
        }
    }
    

    3.图片的点击放大手势

        @objc func imageClick(tap:UITapGestureRecognizer) {
            
            var newscale : CGFloat = 0
            
            guard let scroll = tap.view?.superview as? UIScrollView else {
                return
            }
            
            if scroll.zoomScale == 1.0 {
                newscale = 3
            }else {
                newscale = 1.0
            }
            
            let zoomRect = self.zoomRectForScale(scrollview: scroll,scale: newscale, center: tap.location(in: tap.view))
            
            scroll.zoom(to: zoomRect, animated: true)
        }
    // 计算放大或缩小的frame
        func zoomRectForScale(scrollview: UIScrollView, scale: CGFloat,center: CGPoint) -> CGRect {
            var zoomRect: CGRect = CGRect()
            zoomRect.size.height = scrollview.frame.size.height / scale
            zoomRect.size.width = scrollview.frame.size.width / scale
            zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0)
            zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0)
            return zoomRect
        }
    

    4.出现时的动画

        func pushAnimation(num: Int) {
            // 获取UIImageView()
            guard let imageView = self.backScroll.viewWithTag(100 + num) as?  UIImageView else {
                return
            }
            transformAnimation(animationView: imageView)
        }
    // 缩放动画
        func transformAnimation(animationView: UIImageView) {
            let animation: CABasicAnimation = CABasicAnimation()
            animation.keyPath = "transform.scale"
            animation.fromValue = 0.2 // 原始系数
            animation.toValue = 1 // 缩放系数
            animation.duration = 0.3
            animation.isRemovedOnCompletion = true
            animation.fillMode = kCAFillModeRemoved
            animationView.layer.add(animation, forKey: nil)
        }
    

    5.消失时的动画

        @objc func backBtnClick() {
            self.removeAnimation()
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                self.removeFromSuperview()
            }
        }
    
    // 缩放 + 淡入淡出
        func removeAnimation() {
            
            let x = Int(self.backScroll.contentOffset.x)
            let y = Int(ScreenW)
            guard (x % y) == 0 else{
                return
            }
            // 获取
            let tag = x / y + 100
            guard let imageView = self.backScroll.viewWithTag(tag) else {
                return
            }        
            let scale = CABasicAnimation()
            scale.keyPath = "transform.scale"
            scale.fromValue = 1.0
            scale.toValue = 0.2
            scale.duration = 0.3
            scale.fillMode = kCAFillModeForwards
            scale.isRemovedOnCompletion = false
            imageView.layer.add(scale, forKey: nil)
    
            let backAnimation = CAKeyframeAnimation()
            backAnimation.keyPath = "opacity"
            backAnimation.duration = 0.4
            backAnimation.values = [
                NSNumber(value: 0.90 as Float),
                NSNumber(value: 0.60 as Float),
                NSNumber(value: 0.30 as Float),
                NSNumber(value: 0.0 as Float),
            ]
            backAnimation.keyTimes = [
                NSNumber(value: 0.1),
                NSNumber(value: 0.2),
                NSNumber(value: 0.3),
                NSNumber(value: 0.4)
            ]
            backAnimation.fillMode = kCAFillModeForwards
            backAnimation.isRemovedOnCompletion = false
            self.layer.add(backAnimation, forKey: nil)
        }
    

    6.调用

        let showController = ShowBigImgController(imgs: imgs, img: url)
        showController.modalPresentationStyle = .overFullScreen
        self.present(showController, animated: false, completion: nil)
    

    Demo地址

    相关文章

      网友评论

          本文标题:iOS Swift 仿微信朋友圈实现图片点击放大查看

          本文链接:https://www.haomeiwen.com/subject/omvdgctx.html