整体开源源代码记录,Swift中的动画
分类:美高梅游戏官网网站

整体开源源代码记录(滚动图片、滚动固定及贝塞尔曲线画突效果),贝塞尔

1:左右滚动多张图片实现

#import <UIKit/UIKit.h>

@protocol JZAlbumDelegate <NSObject>

@optional
-(void)didSelectedAlbumAtIndex:(NSInteger)index;

@end

@interface JZAlbumCell : UITableViewCell

@property(nonatomic, strong) NSArray *imgurlArray;/**< 图片URL */

@property(nonatomic, assign) id<JZAlbumDelegate> delegate;

-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier frame:(CGRect)frame;

@end

#import "JZAlbumCell.h"
#import "UIImageView+WebCache.h"

@interface JZAlbumCell ()
{
    UIScrollView *_scrollView;
}

@end

@implementation JZAlbumCell

-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier frame:(CGRect)frame{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        //创建scrollview
        _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(5, 0, frame.size.width, frame.size.height)];
        _scrollView.showsHorizontalScrollIndicator = NO;
        [self addSubview:_scrollView];

        //添加图片
        for (int i = 0; i < 10; ++i) {
            UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake((screen_width*2/5+5)*i, 5, screen_width*2/5, frame.size.height-10)];
            imageView.layer.masksToBounds = YES;
            imageView.layer.cornerRadius = 5;
//            [imageView setImage:[UIImage imageNamed:@"lesson_default"]];
            imageView.tag = i+20;
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(OnTapImage:)];
            [imageView addGestureRecognizer:tap];
            imageView.userInteractionEnabled = YES;
            [_scrollView addSubview:imageView];
        }

    }
    return self;
}


- (void)awakeFromNib {
    // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

-(void)setImgurlArray:(NSArray *)imgurlArray{
    _scrollView.contentSize = CGSizeMake((screen_width*2/5+5)*imgurlArray.count+5, _scrollView.frame.size.height);
    for (int i = 0; i < imgurlArray.count; i++) {
        UIImageView *imageView = (UIImageView *)[_scrollView viewWithTag:20+i];
        [imageView sd_setImageWithURL:[NSURL URLWithString:imgurlArray[i]] placeholderImage:[UIImage imageNamed:@"lesson_default"]];
    }
}

-(void)OnTapImage:(UITapGestureRecognizer *)sender{
    UIImageView *imageView = (UIImageView *)sender.view;
    int tag = (int)imageView.tag-20;
    [self.delegate didSelectedAlbumAtIndex:tag];
}


@end

            static NSString *cellIndentifier = @"courseCell1";
            JZAlbumCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIndentifier];
            if (cell == nil) {
                cell = [[JZAlbumCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIndentifier frame:CGRectMake(0, 0, screen_width, 90)];
                //下划线
                UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 89.5, screen_width, 0.5)];
                lineView.backgroundColor = separaterColor;
                [cell addSubview:lineView];
            }

            cell.delegate = self;
            [cell setImgurlArray:_albumImgurlArray];

            return cell;

效果图:

图片 1

 

2:红色view和蓝色view是添加在scrollView上的,向上拖动,红色view停留在屏幕顶端不动,其它的继续滚动,向下拖动后,红色view跟着下来

@interface ViewController () <UIScrollViewDelegate>

@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;

@property (weak, nonatomic) IBOutlet UIView *blueView;

@property (weak, nonatomic) IBOutlet UIView *redView;

@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end

@implementation ViewController

- (void)viewDidLoad {

    [super viewDidLoad];

    self.scrollView.contentSize = CGSizeMake(0, CGRectGetMaxY(self.blueView.frame));

}



- (void)scrollViewDidScroll:(UIScrollView *)scrollView

{

    CGFloat imageH = self.imageView.frame.size.height;

    CGFloat offsetY = scrollView.contentOffset.y;

    if (offsetY >= imageH) {

        //将红色控件添加到控制器View中

        CGRect redFrame = self.redView.frame;

        redFrame.origin.y = 0;

        self.redView.frame = redFrame;

        [self.view addSubview:self.redView];

    }else {

        //将红色控件添加到控制器scrollView中

        CGRect redFrame = self.redView.frame;

        redFrame.origin.y = 140;

        self.redView.frame = redFrame;

        [self.scrollView addSubview:self.redView];

    }



    CGFloat scale = 1 - (offsetY / 20);

    scale = (scale >= 1) ? scale : 1;

    self.imageView.transform = CGAffineTransformMakeScale(scale, scale);

}

@end

3:通过贝塞尔曲线画突效果

#define SCREEN_WIDTH  ([UIScreen mainScreen].bounds.size.width)


@implementation CustomView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        UIView *myView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 100)];
        myView.backgroundColor=[UIColor redColor];
        [self addSubview:myView];
    }
    return self;
}


- (void)drawRect:(CGRect)rect
{
    UIColor *color = [UIColor redColor];
    [color set];  //设置线条颜色

    UIBezierPath* aPath = [UIBezierPath bezierPath];

    aPath.lineWidth = 5.0;
    aPath.lineCapStyle = kCGLineCapRound;  //线条拐角
    aPath.lineJoinStyle = kCGLineCapRound;  //终点处理

    [aPath moveToPoint:CGPointMake(SCREEN_WIDTH/2-50, 100)]; //左边点

    [aPath addQuadCurveToPoint:CGPointMake(SCREEN_WIDTH/2+50, 100) controlPoint:CGPointMake(SCREEN_WIDTH/2, 150)];  //右边点 中间点

    //[aPath stroke]; //只画线
    [aPath fill]; //填充
}

效果:

图片 2

1:左右滚动多张图片实现 #import UIKit/UIKit.h @protocol JZAlbumDelegat...

// each square will take between 4.0 and 8.0 seconds// to complete one animation loopanim.duration = Double(arc4random_uniform / 10// stagger each animation by a random value// `290` was chosen simply by experimentationanim.timeOffset = Double(arc4random_uniform

图片 3container-2.gif 从一个View转变到另一个View是常见的动画效果,苹果为我们提供了一种简洁直接的用法来自动实现removeSuperview()和addSubView()的效果:

// set up some values to use in the curvelet ovalStartAngle = CGFloat(90.01 * M_PI/180)let ovalEndAngle = CGFloat(90 * M_PI/180)let ovalRect = CGRectMake(97.5, 58.5, 125, 125)// create the bezier pathlet ovalPath = UIBezierPath()ovalPath.addArcWithCenter(CGPointMake(CGRectGetMidX, CGRectGetMidY), radius: CGRectGetWidth / 2, startAngle: ovalStartAngle, endAngle: ovalEndAngle, clockwise: true)// create an object that represents how the curve // should be presented on the screenlet progressLine = CAShapeLayer()progressLine.path = ovalPath.CGPathprogressLine.strokeColor = UIColor.blueColor().CGColorprogressLine.fillColor = UIColor.clearColor().CGColorprogressLine.lineWidth = 10.0progressLine.lineCap = kCALineCapRound// add the curve to the screenself.view.layer.addSublayer(progressLine)// create a basic animation that animates the value 'strokeEnd'// from 0.0 to 1.0 over 3.0 secondslet animateStrokeEnd = CABasicAnimation(keyPath: "strokeEnd")animateStrokeEnd.duration = 3.0animateStrokeEnd.fromValue = 0.0animateStrokeEnd.toValue = 1.0// add the animationprogressLine.addAnimation(animateStrokeEnd, forKey: "animate stroke end animation")
// create and add blue-fish.png image to screenlet fish = UIImageView()fish.image = UIImage(named: "blue-fish.png")fish.frame = CGRect(x: 50, y: 50, width: 50, height: 50)self.view.addSubview// create an array of views to animate (in this case just one)let viewsToAnimate = [fish]// perform the system animation// as of iOS 8 UISystemAnimation.Delete is the only valid optionUIView.performSystemAnimation(UISystemAnimation.Delete, onViews: viewsToAnimate, options: nil, animations: { // any changes defined here will occur // in parallel with the system animation }, completion: { finished in // any code entered here will be applied // once the animation has completed})
let transitionOptions = UIViewAnimationOptions.TransitionCurlDown

因为初始值和结束值相同,iOS不能在中间添加新值.如果要实现如此,我们可以利用animateKeyFramesWithDuration来将翻转分割成许多小组合,然后将他们组成一个完整的动画效果:我们将整个翻转分割成3部分,每一部分翻转1/3:

图片 4path-1.gif

let transitionOptions = UIViewAnimationOptions.TransitionFlipFromLeft

图片 5progress-1.gif

  • Keyframe block animations另一个iOS7新增加的特性,用于替代创建动画时插入开始和结束值,它是将一个整体分为你想要的多个部分.例如我们想要将一张图片旋转360度.用我们熟知的动画方法通过改变transform属性来实现:

图片 6path-2.gif

let duration = 2.0let delay = 0.0let options = UIViewKeyframeAnimationOptions.CalculationModeLinearUIView.animateKeyframesWithDuration(duration, delay: delay, options: options, animations: { // each keyframe needs to be added here // within each keyframe the relativeStartTime and relativeDuration need to be values between 0.0 and 1.0 UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 1/3, animations: { // start at 0.00s  // duration 1.67s  // end at 1.67s (0.00s + 1.67s) self.fish.transform = CGAffineTransformMakeRotation(1/3 * fullRotation) }) UIView.addKeyframeWithRelativeStartTime(1/3, relativeDuration: 1/3, animations: { self.fish.transform = CGAffineTransformMakeRotation(2/3 * fullRotation) }) UIView.addKeyframeWithRelativeStartTime(2/3, relativeDuration: 1/3, animations: { self.fish.transform = CGAffineTransformMakeRotation(3/3 * fullRotation) }) }, completion: {finished in // any code entered here will be applied // once the animation has completed })}
@IBAction func animateButtonTapped(sender: AnyObject) { // create a 'tuple' (a pair or more of objects assigned to a single variable) let views = (frontView: self.redSquare, backView: self.blueSquare) // set a transition style let transitionOptions = UIViewAnimationOptions.TransitionCurlUp UIView.transitionWithView(self.container, duration: 1.0, options: transitionOptions, animations: { // remove the front object... views.frontView.removeFromSuperview() // ... and add the other object self.container.addSubview(views.backView) }, completion: { finished in // any code entered here will be applied // .once the animation has completed })}

我们来尝试下其他的转换效果:

现在有了一个单一的动画,我们需要把它成倍增加来创建一个复杂的场景:

let container = UIView()let redSquare = UIView()let blueSquare = UIView()override func viewDidLoad() { super.viewDidLoad() // set container frame and add to the screen self.container.frame = CGRect(x: 60, y: 60, width: 200, height: 200) self.view.addSubview(container) // set red square frame up // we want the blue square to have the same position as redSquare // so lets just reuse blueSquare.frame self.redSquare.frame = CGRect(x: 0, y: 0, width: 200, height: 200) self.blueSquare.frame = redSquare.frame // set background colors self.redSquare.backgroundColor = UIColor.redColor() self.blueSquare.backgroundColor = UIColor.blueColor() // for now just add the redSquare // we'll add blueSquare as part of the transition animation self.container.addSubview(self.redSquare) }
  • 容器的页面转换苹果提供了许多默认的动画效果,使你能很轻松地完成页面之间的动画过渡.为了很好地利用这些方法,你需要一个父容器.这个父容器一般为一个不可见的大尺寸的UIView.做这些动画效果之前需要做一些准备工作.我们要创建两种不同颜色的UIView之间的转换动画需要另外创建一个UIView.首先,需要在viewDidLoad()方法中创建三个views...

如果你手动输入开始和持续时间很容易出错,但如果要实现keyframes动画之间的连贯顺滑,我们可以通过CalculationModePaced参数来忽略你输入的开始和持续时间,自动计算出动画相对应的时间:

  • view: 添加转场动画的页面
  • duration: 动画所持续的秒数
  • options: 可选参数
  • animations: 定义要变换部分的block
  • completion: 动画结束时的block动画block中要完成移走一个view的同时在容器中新增一个view.
let duration = 2.0let delay = 0.0let options = UIViewKeyframeAnimationOptions.CalculationModePacedUIView.animateKeyframesWithDuration(duration, delay: delay, options: options, animations: { // note that we've set relativeStartTime and relativeDuration to zero. // Because we're using `CalculationModePaced` these values are ignored // and iOS figures out values that are needed to create a smooth constant transition UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 0, animations: { self.fish.transform = CGAffineTransformMakeRotation(1/3 * fullRotation) }) UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 0, animations: { self.fish.transform = CGAffineTransformMakeRotation(2/3 * fullRotation) }) UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 0, animations: { self.fish.transform = CGAffineTransformMakeRotation(3/3 * fullRotation) }) }, completion: nil)

现在我们可以很轻松的实现翻转360的动画效果.

由于设置的动画不同的属性值,现在我们的方块随贝塞尔曲线移动看起来自然多了.

运行程序,你将看到一个红色色块:

图片 7fishes.gif

  • 系统默认动画iOS7另一个新特性是UIView.performSystemAnimation,但其中仅有UISystemAnimation.Delete的参数,希望苹果能不断丰富此功能以使之能够简单的调用.
// create a 'tuple' (a pair or more of objects assigned to a single variable)var views : (frontView: UIView, backView: UIView)// if redSquare has a superView (e.g it's in the container)// set redSquare as front, and blueSquare as back// otherwise flip the orderif(self.redSquare.superview){ views = (frontView: self.redSquare, backView: self.blueSquare)}else { views = (frontView: self.blueSquare, backView: self.redSquare)}

我们可以设定不同方块的动画时间为随机数(这样方块就有不同的移动速度),还有方块开始的位置.

现在我们很容易就能将红色色块换成图片并且增加页面的背景,从而创建出鱼儿自由游动的场景.

现在我们有多个方块,但他们开始时间相同,看起来不太自然:

现在我们能够在红蓝色块中自由转换了!

图片 8static-red-square.png现在我们在storyboard中添加一个按钮来控制动画方法.UIView.transitionWithView有许多参数:

图片 9rotate-1.gif

图片 10container-3.gif

图片 11container-4.gif

  • 贝塞尔曲线动画另一个有用的知识是画出曲线的动画.当我们创建一个曲线的动画时,贝塞尔曲线的路径并不能展示在屏幕上,但可以用keyframe动画替代.在本示例中我们要实现在屏幕中从0到100%画出曲线的动画.需要在点击方法@IBAction中增加一些代码.
  • 使一个物体按照贝塞尔曲线运动一个有意思的动画效果是物体按照曲线运动.我们很容易实现从A到B移动的效果,而实现多个坐标点ABCDE的移动我们需要再次利用keyframebased动画.我们可以利用keyframe block来实现移动效果,但如果想要顺滑我们必须定义多个keyframe,但却使代码变得复杂难懂.好消息是我们可以用贝塞尔曲线自动完成keyframe所做的工作.这需要我们使用更强大的iOS动画特性,了解它后并不会很难.
// create and add blue-fish.png image to screenlet fish = UIImageView()fish.image = UIImage(named: "blue-fish.png")fish.frame = CGRect(x: 50, y: 50, width: 50, height: 50)self.view.addSubview// angles in iOS are measured as radians PI is 180 degrees so PI × 2 is 360 degreeslet fullRotation = CGFloatUIView.animateWithDuration(1.0, animations: { // animating `transform` allows us to change 2D geometry of the object // like `scale`, `rotation` or `translate` self.fish.transform = CGAffineTransformMakeRotation(fullRotation)})

图片 12path-3.gif

@IBAction func animateButtonTapped(sender: AnyObject) { // create a 'tuple' (a pair or more of objects assigned to a single variable) var views : (frontView: UIView, backView: UIView) if(self.redSquare.superview){ views = (frontView: self.redSquare, backView: self.blueSquare) } else { views = (frontView: self.blueSquare, backView: self.redSquare) } // set a transition style let transitionOptions = UIViewAnimationOptions.TransitionCurlUp // with no animation block, and a completion block set to 'nil' this makes a single line of code UIView.transitionFromView(views.frontView, toView: views.backView, duration: 1.0, options: transitionOptions, completion: nil) }

本文翻译自OO 在Prototyping iOS Animations in Swift中介绍了UIKit中基于block方法的一些小的动画效果并且教你如何利用随机数的变化来创建一个复杂的场景.这些知识能够创建一些有意思的动画,但仅是苹果所提供创建动画效果工具中的冰山一角.这篇文章将教你一些进阶的动画制作,一旦你掌握这些知识,将会打开动画的潘多拉墨盒:)

// loop from 0 to 5for i in 0...5 { // create a square let square = UIView() square.frame = CGRect(x: 55, y: 300, width: 20, height: 20) square.backgroundColor = UIColor.redColor() self.view.addSubview // randomly create a value between 0.0 and 150.0 let randomYOffset = CGFloat( arc4random_uniform // for every y-value on the bezier curve // add our random y offset so that each individual animation // will appear at a different y-position let path = UIBezierPath() path.moveToPoint(CGPoint(x: 16,y: 239 + randomYOffset)) path.addCurveToPoint(CGPoint(x: 301, y: 239 + randomYOffset), controlPoint1: CGPoint(x: 136, y: 373 + randomYOffset), controlPoint2: CGPoint(x: 178, y: 110 + randomYOffset)) // create the animation let anim = CAKeyframeAnimation(keyPath: "position") anim.path = path.CGPath anim.rotationMode = kCAAnimationRotateAuto anim.repeatCount = Float.infinity anim.duration = 5.0 // add the animation square.layer.addAnimation(anim, forKey: "animate position along path")}

图片 13container-1.gif红色方块转换到蓝色方块时,一切正常,但之后就一直是蓝色方块.这是因为我们的@IBAction方法设置的是红色可见方块.而这只有在首次点击动画按钮时才为true.要解决这个问题需要判断出哪个色块是可见的,从而实现从从红色转变为蓝色,或者蓝色转变为红色.有许多方法可以做到,但我们现在使用Swift的一个特性'tuple'来实现.

这个动画简单地画出了一个圆形,但可以推广于各种图形.有人还将此用于画出文字的路径,或者你可以显示你画任意一条曲线时的路径.

图片 14delete.gif

Girl学iOS100天 第5天

// first set up an object to animate// we'll use a familiar red squarelet square = UIView()square.frame = CGRect(x: 55, y: 300, width: 20, height: 20)square.backgroundColor = UIColor.redColor()// add the square to the screenself.view.addSubview// now create a bezier path that defines our curve// the animation function needs the curve defined as a CGPath// but these are more difficult to work with, so instead// we'll create a UIBezierPath, and then create a // CGPath from the bezier when we need itlet path = UIBezierPath()path.moveToPoint(CGPoint(x: 16,y: 239))path.addCurveToPoint(CGPoint(x: 301, y: 239), controlPoint1: CGPoint(x: 136, y: 373), controlPoint2: CGPoint(x: 178, y: 110))// create a new CAKeyframeAnimation that animates the objects position let anim = CAKeyframeAnimation(keyPath: "position")// set the animations path to our bezier curveanim.path = path.CGPath// set some more parameters for the animation// this rotation mode means that our object will rotate so that it's parallel to whatever point it is currently on the curve anim.rotationMode = kCAAnimationRotateAutoanim.repeatCount = Float.infinityanim.duration = 5.0// we add the animation to the squares 'layer' propertysquare.layer.addAnimation(anim, forKey: "animate position along path")

本文由美高梅网址发布于美高梅游戏官网网站,转载请注明出处:整体开源源代码记录,Swift中的动画

上一篇:浏览器内核简介,十天精通CSS3 下一篇:没有了
猜你喜欢
热门排行
精彩图文