• 问题总会出现,不过解决问题的方法也会出现!!!

UI控件02-基础控件02

UI控件 小雨 518次浏览 已收录 0个评论

NSArray和NSDictionary的简单使用

读写plist文件
Plist文件的创建和读取
属性的懒加载
重写属性的get方法

viewDidLoad方法的使用

凡是要在当控制器的View加载完毕以后执行的代码, 都可以写在这个方法中

UILabel自动换行

要想让UILabel自动换行,设置Lines为0即可

UI控件02-基础控件02

UILabel的文字居中显示

UI控件02-基础控件02

UIButton和UIImageView

相同点

都能显示图片

不同点

UIButton默认情况就能监听点击事件,而UIImageView默认情况下不能
UIButton可以在不同状态下显示不同的图片
UIButton既能显示文字,又能显示图片

如何选择

UIButton:需要显示图片,点击图片后需要做一些特定的操作
UIImageView:仅仅需要显示图片,点击图片后不需要做任何事情

NSArray和NSDictionary的使用

当图片内容非常多时,“根据index来设置内容”的代码就不具备扩展性,要经常改动
为了改变现状,可以考虑将图片数据线保存到一个数组中,数组中有序地放着很多字典,一个字典代表一张图片数据,包含了图片名、图片描述
@property (strong, nonatomic) NSArray *images;
由于只需要初始化一次图片数据,因此放在get方法中初始化
将属性放在get方法中初始化的方式,称为“懒加载””延迟加载”

什么是Plist文件

直接将数据直接写在代码里面,不是一种合理的做法。如果数据经常改,就要经常翻开对应的代码进行修改,造成代码扩展性低
因此,可以考虑将经常变的数据放在文件中进行存储,程序启动后从文件中读取最新的数据。如果要变动数据,直接修改数据文件即可,不用修改代码
一般可以使用属性列表文件存储NSArray或者NSDictionary之类的数据,这种属性列表文件的扩展名是plist,因此也成为“Plist文件”

创建Plist文件

UI控件02-基础控件02

解析Plist文件

接下来通过代码来解析Plist文件中的数据
获得Plist文件的全路径

NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:@"imageData" ofType:@"plist"];

加载plist文件

_images = [NSArray arrayWithContentsOfFile:path];
- (NSArray *)images
{
if (_images == nil) {
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:@"imageData" ofType:@"plist"];
_images = [NSArray arrayWithContentsOfFile:path];
}
return _images;
}

Plist文件的解析过程

UI控件02-基础控件02

UIImageView帧动画相关属性和方法

@property(nonatomic,copy) NSArray *animationImages;
需要播放的序列帧图片数组(里面都是UIImage对象,会按顺序显示里面的图片)
@property(nonatomic) NSTimeInterval animationDuration;
帧动画的持续时间
@property(nonatomic) NSInteger animationRepeatCount;
帧动画的执行次数(默认是无限循环)
- (void)startAnimating;
开始执行帧动画
- (void)stopAnimating;
停止执行帧动画
- (BOOL)isAnimating;
是否正在执行帧动画

UIImage的2种加载方式

方式一:有缓存(图片所占用的内存会一直停留在程序中)

+ (UIImage *)imageNamed:(NSString *)name;//name是图片的文件名

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

+ (UIImage *)imageWithContentsOfFile:(NSString *)path
- (id)initWithContentsOfFile:(NSString *)path;//path是图片的全路径

重复代码的封装抽取

当一份代码重复出现在程序的多处地方,就会造成程序又臭又长,当这份代码的结构要修改时,每一处出现这份代码的地方都得修改,导致程序的扩展性很差
因此,要将重复出现的代码抽取到某个方法中,在需要这份代码的地方调用方法即可
抽取代码的思路
将相同的代码放到一个方法中
将不同的值当做方法参数传进来

继承关系

UIButton -> UIControl -> UIView
UIImageView -> UIView

一, transform 属性: 平移/旋转/缩放

平移:

只会生效一次, 是以初始位置为参照点

self.redView.transform = CGAffineTransformMakeTranslation(-10, 0);

每次都会生效
是以当前的位置为参照点

self.redView.transform = CGAffineTransformTranslate( self.redView.transform, 10, 0);

旋转:

传递的参数是弧度
(圆的周长)c = 2πr
弧度: l = 2πr / r
2π = 360°
π = 180°
π/2 = 90°

缩放:

想要放大: 传递的参数必须大于1
想要缩小: 大于0 小于 1

弧度计算

UI控件02-基础控件02

二, 图片浏览器

1. 加载数据

外侧: 使用数组装载数据, 方便数据切换 , 定义了索引 index = 1
内侧: 使用字典, 可以存储多个 key: value 值

UI控件02-基础控件02

2. 初始化界面

取出在数组中对应的 (index – 1) 字典
更新 UI 界面

3. 实现 rightButton 的点击逻辑

让索引_index++

更新 UI 界面

4. 实现 leftButton 的点击逻辑

让索引 _index—
更新 UI 界面

自定义了一个 updateUI 这个方法

leftButton 什么时候不可被点击

当 index = 1 的时候, 不可以被点击, 其他情况都可以
_index = 1 (第一次调用) 1 != 1 –> NO
_leftButton.enabled = NO; 初始化界面的时候 左侧按钮时不可以被点击的

_leftButton.enabled = (_index != 1);

rightButton 当最后一张图片的时候, 不可以被点击
/**
(_index != _dataArray.count)

当 _index = 1 (第一次调用) 1 != 5 –> YES
_rightButton.enabled = YES ; 表示按钮可以被点击
.
.
当_ index = 5 (最后一张图片) 5 != 5 –> NO
_rightButton.enabled = NO ; 表示按钮可以被点击
*/

使用数组装载数据: 为什么不使用这种方式?

当数据过多的时候, 就导致代码比较臃肿
解决这个问题使用了 plist 文件

_dataArray = @[
@{@"icon":@"btn_01",@"title":@"以后别想再这间网吧玩 LOL, 小学生"},
@{@"icon":@"btn_02",@"title":@"闭嘴, 小学生"},
@{@"icon":@"btn_03",@"title":@"装逼一直是你的强项"},
@{@"icon":@"btn_04",@"title":@"我让你买表"},
@{@"icon":@"btn_05",@"title":@"我这个傻吊怎么得罪你了"}];

plist与数组对比

UI控件02-基础控件02

plist 文件是 XML 描述的文件
root 根部的数据类型, 要跟 实际数据结构的外侧类型保持一致
内部要跟, 数据中 每一个元素的类型保持一致 (字典)

读取 plist 文件

安装目录: [NSBundle mainBundle]

文件路径: 如果找到文件, 会返回一个路径
如果找不到, 就返回 nil

查看安装目录
[NSBundle mainBundle].bundlePath

NSString *path = [[NSBundle mainBundle] pathForResource:@"Image.plist" ofType:nil];

读取数据的方式: 懒加载

// 重写数组的 get 方法
- (NSArray *)dataArray {
// 如果数组为 空, 就从文件中读取数据,(大括号中的代码只会执行一次)
if (nil == _dataArray) {
// 读取 plist 文件中的内容
// 1. 获取文件的路径
// pathForResource: ofType: 根据传入的文件名, 到安装目录中查找对应的文件, 如果找到 返回这个文件的路径, 如果找不到 返回为 nil
NSString *path = [[NSBundle mainBundle] pathForResource:@"Image.plist" ofType:nil];
// 2. 读取文件中的内容
// plist 文件中 root 是什么类型的, 就用什么类型的数据去接收
_dataArray = [NSArray arrayWithContentsOfFile:path];
}

return _dataArray;
}

字典转模型:

字典里的 key 值容易输入错误, 编译器没有任何提醒
不专业, 费事

字典转模型的方式:

字典里的 key 值 对应 模型中的 属性
字典里 value 的类型 对应 模型中 属性的类型

对外提供一个 对象方法 和 一个类方法

//对象方法
- (instancetype)initWithDict:(NSDictionary *)dict;

// 类方法
+ (instancetype)imageModelWithDict:(NSDictionary *)dict;

UI控件02-基础控件02

三, 汤姆猫

UIImageView 的序列帧动画

动画是靠图片的不断切换完成的, 那么存放图片要使用 数组 (有序的)

帧动画的步骤:

1. 把跟动画相关的图片, 存放到数组里 imageArray

2. 把 imageArray 这个数组赋值给 imageView.animationImages 这个属性
animationImages 这个数组中, 每一个元素都必须是 UIImage 对象

3. 设置动画的属性
动画执行的时间 animationDurations
动画执行的次数 animationRepeatCount
重复次数如果不设置,默认为0 , 但是回无限循环下去

4. 开始动画
[imageView startAnimating];

Assets.xcassets : 存放的是素材图片 –> 图标, 背景图片

UI控件02-基础控件02

内存管理:

图片加载的两种方式:

1. [UIImage imageNamed:imageName];
会自动的做缓存
优点:
再次加载的时候直接读取缓存, 所有速度快, 避免重复加载
缺点:
程序不死, 内存不释放, 导致内存飙升, 很有可能被系统杀掉

2. [UIImage imageWithContentOfFiel:path]
图片资源不能放到 Assets.xcassets 这个文件夹中

UI控件02-基础控件02

png 和 jpg 的区别

iOS对 png 支持比较好, 不管图片放到哪里, 都可以直接使用图片名称进行访问
Assets.xcassets

如果是 jpg 格式呢?
放到 Assets.xcassets 文件中, 使用的时候, 可以不用加后缀名
如果在 Assets.xcassets 文件夹以外 , 使用图片的时候, 就要添加后缀名 jpg

UI控件02-基础控件02

延迟执行:

延迟 duration 时间后调用 self 的 resetPoint 这个方法, 传递参数为 nil ,

[self performSelector:@selector(resetPoint) withObject:nil afterDelay:duration];

UI控件02-基础控件02

弹框:

UIAlertView : iOS 8

UIAlertController : iOS 9

通过联线和storyboard 上的控件进行关联

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

通过手动拖放到 storyboard 上的时候, 控制器的 view 已经对 orangeView 有了一个强应用

如果 在控制器中 property 的 属性 修饰符 使用 strong 的话
就会导致 控制器也对 orangeVIew 有一个强应用

添加 UI 控件注意事项:

已有在使用 UI 控件的时候, 声明属性用 weak

@property (nonatomic, weak) UIButton *button;

UIButton *button = [[UIButton alloc] initWithFrame:];

self.button = button;

[self.view addSubview:button];

Xcode模拟器常用快捷键:

command + 1, 2, 3, 4

shift + command + h : home 键效果

UIViewContentMode详解

UIImageView的contentMode继承自UIView
UIView有个UIViewContentMode类型的属性contentMode,可以通过它来修改视图的内容显示模式。

typedef NS_ENUM(NSInteger, UIViewContentMode) {
UIViewContentModeScaleToFill,
UIViewContentModeScaleAspectFit, // contents scaled to fit with fixed aspect. remainder is transparent
UIViewContentModeScaleAspectFill, // contents scaled to fill with fixed aspect. some portion of content may be clipped. UIViewContentModeRedraw, // redraw on bounds change (calls -setNeedsDisplay)
UIViewContentModeCenter, // contents remain same size. positioned adjusted.
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight, };
CGRect rect = self.view.frame; UIImageView *imageView = [[UIImageView alloc] initWithFrame:rect];
imageView.contentMode = UIViewContentModeTop;
imageView.image = [UIImage imageNamed:@"demoImage"];
[self.view addSubview:imageView];

UIViewContentModeScaleToFill
根据视图的比例去拉伸图片内容。UI控件02-基础控件02

UIViewContentModeScaleAspectFit
保持图片内容的纵横比例,来适应视图的大小。UI控件02-基础控件02

UIViewContentModeScaleAspectFill
用图片内容来填充视图的大小,多余得部分可以被修剪掉来填充整个视图边界。UI控件02-基础控件02

UIViewContentModeRedraw
这个选项是单视图的尺寸位置发生变化的时候通过调用setNeedsDisplay方法来重新显示。
UIViewContentModeCenter
保持图片原比例在视图中间显示图片内容
如果视图大小小于图片的尺寸,则图片会超出视图边界,下面类同UI控件02-基础控件02

UIViewContentModeTop
保持图片原比例在视图中间顶部显示图片内容UI控件02-基础控件02

UIViewContentModeBottom
保持图片原比例在视图中间底部显示图片内容UI控件02-基础控件02

UIViewContentModeLeft
保持图片原比例在视图中间左边显示图片内容UI控件02-基础控件02

UIViewContentModeRight
保持图片原比例在视图中间右边显示图片内容UI控件02-基础控件02

UIViewContentModeTopLeft
保持图片原比例在视图左上角显示图片内容UI控件02-基础控件02

UIViewContentModeTopRight
保持图片原比例在视图右上角显示图片内容UI控件02-基础控件02

UIViewContentModeBottomLeft
保持图片原比例在视图左下角显示图片内容UI控件02-基础控件02

UIViewContentModeBottomRight
保持图片原比例在视图右下角显示图片内容UI控件02-基础控件02


本博客内容既有转载自网络的内容,也有本作者原创内容,仅供学习与交流之用
如有侵权或者错误之处,请及时在下方留言!
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址