Swift教程_零基础学习Swift完整实例(八)_swift完整实例(添加View的动画效果、添加View的阴影)


6.添加View的动画效果

本章节主要来做明细页面点击后翻转的动画效果,该效果可以进行多种改变,以达到想要的效果。

1.首先我们需要进行翻转的正反两个view,前面我们已经做好了,分别是PKOElementDetailImageViewPKOElementDetailImageFlippedView,具体翻转动画在明细页面的控制其中进行,触发当然是PKOElementDetailImageView中的点击事件,前文已经提到。
2.PKOElementDetailImageView中的点击事件调用PKOElementDetailViewController中的flipImageView()方法,该方法具体实现翻转功能,注释中写的很详细。
代码如下。

//翻转动画
    func flipImageView() {
        UIView.beginAnimations(nil, context:nil)
        //平滑动画效果
        UIView.setAnimationCurve(UIViewAnimationCurve.Linear)
        UIView.setAnimationDuration(1)
        
        var reflectionHeight: CGFloat
        var reflectedImage: UIImage?
        
        //点击正面
        if(self.frontViewIsVisible == true){
            UIView.setAnimationTransition(UIViewAnimationTransition.FlipFromLeft, forView: self.subView!, cache: true)
            self.detailImage.removeFromSuperview()
            self.subView?.addSubview(self.detailImageFlipped)
        }
        //点击反面
        else{
            UIView.setAnimationTransition(UIViewAnimationTransition.FlipFromRight, forView:self.subView!, cache:true)
            self.detailImageFlipped.removeFromSuperview()
            self.subView?.addSubview(self.detailImage)
        }
        //提交动画
        UIView.commitAnimations()
        //设置是否正面显示标识
        self.frontViewIsVisible = !self.frontViewIsVisible
    }

7.添加View的阴影

本章节主要来做明细页面图片的阴影效果,该效果可以进行高度设置,并且完全反射,包含所绘制的文字。

1.通过控制器PKOElementDetailViewController绘制明细图的同时,绘制图片的阴影,该阴影应该基于阴影的主图,所以放在PKOElementDetailImageView中处理。
reflectedImageWithHeight(height: UInt) ->UIImage该方法将返回对应阴影image。
具体做法请看注释,思路是:复制一个位图并裁剪成需要大小-翻转并绛色-填充渐变色
代码如下。

//通过指定高度生成倒影图,方法完全照搬官方sample,
    func reflectedImageWithHeight(height: UInt) ->UIImage{
        //这里注意,swift不能直接在CG方法中用nil,需要声明一个变量
        var nilUnsafeMutablePointer: UnsafeMutablePointer<Void> = nil
        //rgb颜色容器,RGBA和CMYK的区别我会另开博文去说这个
        var colorSpace  = CGColorSpaceCreateDeviceRGB()
        var int32CGImageAlphaInfo = CGImageAlphaInfo.PremultipliedLast.toRaw()
        var bitmapInfo = CGBitmapInfo.fromRaw(int32CGImageAlphaInfo)
        
        //使用CG绘制位图上下文,以下是方法的用法,网上抓的,大家可以试一下具体用法。
        //参数data指向绘图操作被渲染的内存区域,这个内存区域大小应该为(bytesPerRow*height)个字节。如果对绘制操作被渲染的内存区域并无特别的要求,那么可以传递NULL给参数date。
        //参数width代表被渲染内存区域的宽度。
        //参数height代表被渲染内存区域的高度。
        //参数bitsPerComponent被渲染内存区域中组件在屏幕每个像素点上需要使用的bits位,举例来说,如果使用32-bit像素和RGB颜色格式,那么RGBA颜色格式中每个组件在屏幕每个像素点上需要使用的bits位就为32/4=8。
        //参数bytesPerRow代表被渲染内存区域中每行所使用的bytes位数。
        //参数colorspace用于被渲染内存区域的“位图上下文”。
        //参数bitmapInfo指定被渲染内存区域的“视图”是否包含一个alpha(透视)通道以及每个像素相应的位置,除此之外还可以指定组件式是浮点值还是整数值。
        var mainViewContentContext = CGBitmapContextCreate(nilUnsafeMutablePointer, UInt(self.bounds.size.width), height, UInt(8), UInt(0), colorSpace, bitmapInfo!)
        
        //注意,swift操作CG是不需要释放的,CG内部的GC已经处理了
        
        //调整位图位置,CGContextTranslateCTM为位移方法
        var translateVertical = CGFloat(self.bounds.size.height) - CGFloat(height)
        //这里相当于翻转
        CGContextTranslateCTM(mainViewContentContext, 0, -translateVertical)
        
        //将该位图渲染到layer层,layer层是view的根层,这里相当与copy一个self
        self.layer.renderInContext(mainViewContentContext)
        
        //根据位图上下文生成位图
        var mainViewContentBitmapContext = CGBitmapContextCreateImage(mainViewContentContext)
        
        //创建一个mask,确认刚才生成的位图那些是需要显示的,这里主要用它的渐变功能,image mask就像是用于表征色彩放在页面的哪一部分
        var gradientMaskImage = PKOElementDetailImageView.AEViewCreateGradientImage(UInt(1), pixelsHigh: UInt(height))
        
        //将位图需要显示的部分显示出来
        var reflectionImage = CGImageCreateWithMask(mainViewContentBitmapContext, gradientMaskImage)
        
        //通过image生成UIImage,并返回
        var theImage = UIImage(CGImage: reflectionImage)
        return theImage
    }
    
    class func AEViewCreateGradientImage ( pixelsWide: UInt, pixelsHigh: UInt) ->CGImageRef {
        var nilUnsafeMutablePointer: UnsafeMutablePointer<Void> = nil
        var colorSpace = CGColorSpaceCreateDeviceGray()
        var int32CGImageAlphaInfo = CGImageAlphaInfo.None.toRaw()
        var bitmapInfo = CGBitmapInfo.fromRaw(int32CGImageAlphaInfo)
        //使用CG绘制位图上下文,渐变色位图
        var gradientBitmapContext = CGBitmapContextCreate(nilUnsafeMutablePointer, pixelsWide, pixelsHigh,
            UInt(8), UInt(0), colorSpace, bitmapInfo!)
        
        //创建渐变对象,对于CG渐变我会在开博文详细解释
        var colors: [CGFloat] = [0.0, 1.0,1.0, 1.0]
        var nilUnsafePointer: UnsafePointer<CGFloat> = nil
        var grayScaleGradient = CGGradientCreateWithColorComponents(colorSpace, colors, nilUnsafePointer, UInt(2))
        
        //渐变的开始点和结束点
        var gradientStartPoint = CGPointZero
        var gradientEndPoint = CGPointMake(0, CGFloat(pixelsHigh))
        
        //填充渐变色
        CGContextDrawLinearGradient(gradientBitmapContext, grayScaleGradient, gradientStartPoint, gradientEndPoint, CGGradientDrawingOptions())
        
        //通过image生成UIImage,并返回
        var theCGImage = CGBitmapContextCreateImage(gradientBitmapContext)
        return theCGImage
    }

2.在PKOElementDetailViewController中图像渲染时调用PKOElementDetailImageView中的reflectedImageWithHeight(height: UInt) ->UIImage返回image,将其添加在subview中。
代码如下。

//创建倒影图
        var reflectionRect = imageRect
        reflectionRect.size.height = CGFloat(CGRectGetHeight(reflectionRect)) * CGFloat(reflectionRadio)
        reflectionRect = CGRectOffset(reflectionRect, 0, CGRectGetHeight(imageRect))
        var reflectionView = UIImageView(frame: reflectionRect)
        self.reflectionImage = reflectionView
        var height = (self.detailImage?.bounds.height as CGFloat!) * CGFloat(reflectionRadio)
        self.reflectionImage.image = self.detailImage?.reflectedImageWithHeight(UInt(height))
        self.reflectionImage.alpha = 0.3
        //添加倒影
        self.subView?.addSubview(self.reflectionImage)

3.在翻转的同时需要更新倒影,使倒影应用于反面,再次翻转时需要再次更新,保证阴影跟随主图的变幻而变化,在控制器的翻转方法flipImageView()中进行处理即可 。
代码如下。

//翻转动画
    func flipImageView() {
        UIView.beginAnimations(nil, context:nil)
        //平滑动画效果
        UIView.setAnimationCurve(UIViewAnimationCurve.Linear)
        UIView.setAnimationDuration(1)
        
        var reflectionHeight: CGFloat
        var reflectedImage: UIImage?
        
        //点击正面
        if(self.frontViewIsVisible == true){
            UIView.setAnimationTransition(UIViewAnimationTransition.FlipFromLeft, forView: self.subView!, cache: true)
            self.detailImage?.removeFromSuperview()
            self.subView?.addSubview(self.detailImageFlipped)
            
            // 更新倒影
            reflectionHeight = (self.detailImageFlipped.bounds.height as CGFloat) * CGFloat(reflectionRadio)
            reflectedImage = self.detailImageFlipped.reflectedImageWithHeight(UInt(reflectionHeight))
            self.reflectionImage.image = reflectedImage
        }
        //点击反面
        else{
            UIView.setAnimationTransition(UIViewAnimationTransition.FlipFromRight, forView:self.subView!, cache:true)
            self.detailImageFlipped.removeFromSuperview()
            self.subView?.addSubview(self.detailImage!)
            
            // 更新倒影
            reflectionHeight = (self.detailImage!.bounds.height as CGFloat) * CGFloat(reflectionRadio)
            reflectedImage = self.detailImage?.reflectedImageWithHeight(UInt(reflectionHeight))
            self.reflectionImage.image = reflectedImage
        }
        //提交动画
        UIView.commitAnimations()
        //设置是否正面显示标识
        self.frontViewIsVisible = !self.frontViewIsVisible
    }

至此全部改造完成,完整源代码请去第一篇下载

点击进入ooppookid的博客

你可能感兴趣的:(ios,技术,xcode,swift,Object-C)