IOS 开发笔记-基础 UI(7)汤姆猫(UIImageView 的序列帧动画、图片加载,方法重构、Bundle 图片素材)

使用UIImageView、UIButton实现一个综合小案例---汤姆猫

回忆:UIImageView 来自UIView,UIView 来自UIResponder,UIButton 来自UIControl,UIControl 来自UIView

单独看实现,代码实现其实比较简单,但是创意很难得,美工要求很高! 是一个了不起的游戏!

功能分析

(1)点击对应的按钮后,让汤姆猫展现对应的动画

步骤分析

(1)搭建UI界面,同时也是准备素材

(2)监听按钮点击

(3)根据点击的按钮执行对应的动画

说明:只适配了3.5寸屏幕

Images.xcassets中的素材

1>  苹果极力推荐(images。xcassets 只支持 png 格式)png格式的图片,因为 png 格式图片保真,不要用 jpg 图片,jpg不保真,压缩比太高,有噪点。

2>  图片只支持[UIImage imageNamed]的方式实例化,但是不能从Bundle中加载

3>  在编译时,Images.xcassets中的所有文件会被打包为Assets.car的文件

如果一定要使用 jpg 格式图片,那么要放到 supporting files 文件夹内

UIImageView的序列帧动画

类关系

NS_CLASS_AVAILABLE_IOS(2_0) @interface UIImageView : UIView

找到一个属性;动画图像(复数,数组)

@property(nonatomic,copy) NSArray *animationImages;            // The array must contain UIImages. Setting hides the single image. default is nil

还有一个时间间隔

@property(nonatomic) NSTimeInterval animationDuration;         // for one cycle of images. default is number of images * 1/30th of a second (i.e. 30 fps)

double类型,是一组图片,播放一个周期的时间,默认是每秒30个图

typedef double NSTimeInterval;

还有一个重复属性,0代表无线重复,默认是0

@property(nonatomic) NSInteger      animationRepeatCount;      // 0 means infinite (default is 0)

还有三个对象方法

- (void)startAnimating;
- (void)stopAnimating;
- (BOOL)isAnimating;

注意:不可以并行的进行动画,比如和水的时候,不能同时被打头!需要判断方法,上面提到了isAnimating 方法

代码如下:

#import "ViewController.h"

@interface ViewController ()

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

@end

@implementation ViewController

- (void)tomAnimationOfName:(NSString *) img andCount:(int)count
{
    //序列帧动画:让一组图片,和放电影一样,一张张的播放,动起来的效果

    //判断是否动画中,不可以同步
    if ([self.tom isAnimating]) {
        //直接结束动画操作方法,这里就是没有返回值,nil 不行
        return;
    }

    //开始肯定是存储图片,81个,用可变数组
    NSMutableArray *arrayImage = [NSMutableArray array];
    //遍历图片
    for (int i = 0; i < count; i++) {
        //类似 c,格式控制,不足两位0补齐
        NSString *name = [NSString stringWithFormat:@"%@_%02d.jpg", img, i];
        UIImage *image = [UIImage imageNamed:name];
        //添加到数组里
        [arrayImage addObject:image];
    }
    //然后开始动画
    //把图片放到animationImages,接受数组参数
    self.tom.animationImages = arrayImage;
    //设置时间间隔,81张图,图多就播的时间稍微长,否则短
    self.tom.animationDuration = arrayImage.count * 0.074;
    //设置重复次数
    self.tom.animationRepeatCount = 1;
    //开始动画
    [self.tom startAnimating];
    //结束动画
}

- (IBAction)head
{
    [self tomAnimationOfName:@"knockout" andCount:81];
}

- (IBAction)drink
{
    [self tomAnimationOfName:@"drink" andCount:81];
}

不过,发现程序运行的时候非洲消耗内存!

考虑UIImage imageNamed问题(详解:UIImage 的imageWithContentsOfFile:path和imageNamed的区别

在图片使用完成后,不会直接被释放掉,具体释放时间由系统决定,这是不好的,不合理的。需要我们手动改变。比如如果同一图片,一个程序里总是反复使用每次都要重新从磁盘加载,会降低性能。(程序员追求的是平衡,相对性能好,执行时间好。不能搞极端。)这些是模拟器测不出来的,因为使用的是电脑的内存,不会轻易用完。一般来说:imageNmaed  适用于图片小的,常用的图像处理。来进行加载。还可以使用[UIImage imageWithContentsOfFile:path]实例化图像(全路径)。

因为前者有缓存(图片所占用的内存会一直停留在程序中)

+ (UIImage *)imageNamed:(NSString *)name;

后者,无缓存(图片所占用的内存会在一些特定操作后被清除)

+ (UIImage *)imageWithContentsOfFile:(NSString *)path

- (id)initWithContentsOfFile:(NSString *)path;

path是图片的全路径

        NSString *name = [NSString stringWithFormat:@"%@_%02d.jpg", img, i];
        // UIImage *image = [UIImage imageNamed:name];
        //添加到数组里
        NSString *file = [[NSBundle mainBundle] pathForResource:name ofType:nil];
        UIImage *image = [UIImage imageWithContentsOfFile:file];
        [arrayImage addObject:image];

这样发现,还是没什么大的改变,那么应该在动画调用的时候,做手动的把动画数组的内容清空!这里还要注意,要节哀延迟,否则动画刚开始,就清空了!注意!

    //结束动画,应该等等再清空
    [self.tom performSelector:@selector(setAnimationImages:) withObject:nil afterDelay:self.tom.animationDuration];

代码中的方法重构的策略

1> 将具有共性的代码复制到一个新的方法

2> 根据不同的调用情况,增加方法的参数

提示:在写程序时不要着急重构,有时候把代码先写出来,更容易看清楚如何重构才会更好!当一份代码重复出现在程序的多处地方,就会造成程序又臭又长,当这份代码的结构要修改时,每一处出现这份代码的地方都得修改,导致程序的扩展性很差,因此,要将重复出现的代码抽取到某个方法中,在需要这份代码的地方调用方法即可

抽取代码的思路:将相同的代码放到一个方法中,将不同的值当做方法参数传进来

Bundle中的图片素材

往项目中拖拽素材时,通常选择

1> Destination: 勾选

2> Folders:

选择第一项:黄色文件夹

Xcode中分文件夹,Bundle中所有素材所在,都在同一个文件夹下,开发效率很高,因此,不能出现文件重名的情况,但是美工不舒服。

特点:

可以直接使用[NSBundle mainBundle]作为资源路径,效率高!

可以使用[UIImage imageNamed:]加载图像

选择第二项:蓝色文件夹

Xcode中分文件夹,Bundle中同样分文件夹,因此,可以出现文件重名的情况

特点:

需要在[NSBundle mainBundle]的基础上拼接实际的路径,效率较差!

不能使用[UIImage imageNamed:]加载图像

文件管理

[NSFileManager defaultManager]

常用方法

1> 判断文件是否存在

- (BOOL)fileExistsAtPath:(NSString *)path;

2> 将文件从源路径复制到目标路径

- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error;

3> 删除文件

- (BOOL)removeItemAtPath:(N

序列帧动画开发大概步骤:

// 1. 设置图片的数组

[self.tom setAnimationImages:xxx];

// 2. 设置动画时长,默认每秒播放30张图片

[self.tom setAnimationDuration:xxx];

// 3. 设置动画重复次数,默认为0,无限循环

[self.tom setAnimationRepeatCount:xxx];

// 4. 开始动画

[self.tom startAnimating];

// 5. 动画播放完成后,清空动画数组

[self.tom performSelector:@selector(setAnimationImages:) withObject:nil afterDelay:self.tom.animationDuration];
时间: 2024-08-02 02:45:17

IOS 开发笔记-基础 UI(7)汤姆猫(UIImageView 的序列帧动画、图片加载,方法重构、Bundle 图片素材)的相关文章

IOS 开发笔记-基础 UI(1)-简单的计算器

(1)UI是App的根基:一个App应该是先有UI界面,然后在UI的基础上增加实用功能 (2)UI相对简单易学:UI普遍是学习过程中最简单的一块,能快速拥有成就感和学习兴趣 (3)UI至关重要:开发中的绝大部分时间都在处理UI 谨记一条IOS软件开发定律:万物皆对象,UI界面上的每一个元素都是一个对象 IOS,android 软件开发过程 UIKit框架是跟UI有关系的,标签,文本,按钮,进度条,开关等控件,都是封装在UIKit框架内部的,UIKit框架中提供了丰富多彩的可视化组件元素,利用UI

IOS 开发笔记-基础 UI(5)使用代码创建按钮

在实际开发中,很多的时候是需要手动写代码来创建按钮的. 在开发过程中,并不是每次都通过storyboard拖控件完成UI界面,因为storyboard上面的界面是“固定死”的,有时候可能会在程序运行过程中动态地添加一些新的控件到界面上,比如QQ,微信的聊天信息,是有人发出一条信息后才动态显示出来的.因此,需要掌握如何用代码动态地添加控件.实际上,storyboard的本质就是根据图形界面描述转成相应的代码(xml 文件).还有一个原因,就是有的国内的公司,或者一些 IOS 开发的团队,并不使用故

iOS开发:纯代码实现汤姆猫小游戏

演示效果如下: 代码如下: 1 // 2 // CKViewController.m 3 // 纯代码实现汤姆猫 4 // 5 // Created by FrankChen on 14-12-10. 6 // Copyright (c) 2014年 diaozhatian. All rights reserved. 7 // 8 9 #import "CKViewController.h" 10 11 @interface CKViewController () 12 { 13 //

IOS 开发笔记-基础 UI(6)照片浏览器(控件的懒加载)

使用UIImageView.UILabel.UIButton实现一个综合小案例 功能分析 (1)点击箭头切换序号.图片.描述 (2)如果是首张图片,左边箭头不能点击 (3)如果是尾张图片,右边箭头不能点击 步骤分析 (1)搭建UI界面 (2)监听按钮点击 切换序号.图片.描述 1. 界面分析 1> 需要读取或修改的属性的控件 // 序号标签 // 图片 // 图片描述 // 左边按钮 // 右边按钮 2> 需要监听响应事件的对象,需要添加监听方法 // 左边按钮 // 右边按钮 uiimage

IOS 开发笔记-基础 UI(3)按钮的使用(放大缩小、改变位置,首位式动画)和学习案例

UIKit框架提供了非常多的UI控件,但并不是每一个都很常用,有些控件可能1年内都用不上,有些控件天天用,比如UIButton.UILabel.UIImageView.UITableView等等,按钮控件是非常重要且比较基础的一个UI控件---UIButton,一般情况下,点击某个控件后,会做出相应反应的都是按钮,按钮的功能比较多,既能显示文字,又能显示图片,还能随时调整内部图片和文字的位置. 案例: 功能分析 (1)左下角4个方向按钮,控制头像按钮的位置 (2)右下角分别是放大.缩小按钮,控制

IOS 开发笔记-基础 UI(4)按钮的使用(transform属性)和学习案例

利用transform属性可以修改控件的位移(位置).缩放.旋转.经常用在动画里,比如旋转角度,动画缩放,平移等 先学几个 xcode 开发的小技巧: 故事板的viewcontroll,可以直接拖拽复制,且不同项目里的图片素材也可以相互拖拽复制使用,但是图片的拖拽复制要按option 健进行,否则就是剪切了.那么我们在开发到类似的一些项目的时候,不用每次都重写弄界面,那么可以直接拖拽拷贝故事板,图片拖拽要按住 option 键同时拽到 images.xcassets 目录下即可正常显式,且拖拽到

IOS 开发笔记-基础 UI(2)

1.公司标示一般使用反向域名 正向域名 www.xxx.com 用来标示一台网络主机,只要公司内部不重复就可以.反向域名 com.xxx.demo 用来标示产品,应该唯一标识. cn.com.abc.product,最后面是自己公司的产品名字 2..Bundle Identifier: 产品唯一标示符 Bundle ID = 公司的反向域名 + 产品名 1> 在模拟器上面,只能有一个唯一的标示符的应用程序2> 在AppStore上,所有的应用程序的Bundler ID都是唯一的 Bundle

IOS 开发笔记-基础 UI(9)运行循环的概念

运行循环 int i = 0; // 死循环 while (YES) { printf("请输入一个整数,0表示退出:"); scanf("%d", &i); NSLog(@"%d", i); if (i == 0) { break; } } 以上程序,会不停的循环运行,但是,会在输入的时候中断,等待,有了输入之后,再继续循环运行,且一旦输入了复合条件的值,那么通过 if 判断,break退出循环体. 这就是简单的 runloop 模型.

IOS 开发笔记-基础 UI(8)控件连线的 strong 和 weak 设定

回忆 oc 的内存管理: objective-c 语法快速过(6)内存管理原理,objective-c 语法快速过(7)编译器特性ARC ARC是苹果为了简化程序员对内存的管理,推出的一套内存管理机制,使用ARC机制,对象的申请和释放工作会在运行时,由编译器自动在代码中添加retain和release 1> strong:强指针引用的对象,在生命周期内不会被系统释放,在OC中,对象默认都是强指针 2> weak:弱指针引用的对象,系统会立即释放,弱指针可以指向其他已经被强指针引用的对象 他们都