1. 熟悉Git的基本流程
- git clone
- git add -A
- git commit -m " "
- git push
- git pull
2. OC(Objective - C)中的类和对象
- 熟悉使用编程过程中常用的快捷键 并熟练使用 提高代码速度.
- 类和对象
- 类: 一个具有相同特征和行为的事物的抽象集合.
- 对象: 类的实例也成为类的实现.
- OOP(面向对象编程) OOD(面向对象设计)
- 面向对象的三大特性: 封装 继承 多态 (都是为了提高代码的复用)
- 创建一个Person类 包含name,age和sex三个实例变量
{
@public
NSString *_name;
@private
NSInteger _age;
@protected
NSString *_sex;
}
@public (公有的, 本类,子类和其他类都可以使用)
@protected (受保护的,本类和子类可以使用)
@private (私有的, 只有本类才可以使用)
- (void)setName:(NSString *)name; // setter方法(赋值方法) - (NSString *)name; // getter方法(取值方法) - (void)sleep:(NSInteger)time; // 实例方法的声明: 返回值类型 + 方法名 + 参数列表
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age; // 初始化方法
+ (instancetype)personWithName:(NSString *)name age:(NSInteger)age; // 遍历构造器
3.字符串和数值
-
NSString 的方法
/** 初始化(init) /
NSString str = [[NSString alloc] init];
/ 便利构造器(string) /
NSString str1 = [NSString string];
/ 获取字符串长度(length) /
NSUInteger length = str.length;
/* 获取字符串中字符(character) /
/* 字符串是否相等(equal) /
[str isEqualToString:str1];
/* 获取子串(sub) /
/* 拼接字符串(append) */
[str stringByAppendingString:@"dsdsddf"];
[str stringByAppendingFormat:@"kfkdjf%@", str];NSString *pathStr = @"/users/local/bin"; // 有返回值的需要接收一下 pathStr = [pathStr stringByAppendingPathComponent:@"name.plist"]; NSLog(@"%@", pathStr); /** 替换字符串(replace) */ // str stringByReplacingCharactersInRange:<#(NSRange)#> withString:<#(nonnull NSString *)#> /** 字符串对象转化为int类型(int) */ [str intValue]; /** 字符串对象转化为其他数据类型, 例如double, float, BOOL等. */ [str doubleValue]; [str floatValue]; [str boolValue]; /** 字符串全部大写(uppercase) */ [str uppercaseString]; /** 字符串全部小写(lowercase) */ [str lowercaseString]; /** 字符串首字母大写(capitalized) */ [str capitalizedString]; /** 是否以指定字符串为前缀(prefix) */ BOOL a = [str hasPrefix:@"sd"]; /** 是否以指定字符串为后缀(suffix) */ BOOL b = [str hasSuffix:@"dsd"];
-
数组
数组: 分为可变数组 NSMutableArray 与 不可变数组 NSArray
数组中只能存放对象类型元素
数组主要是有序存放元素的集合类型 并且可以通过下标取值
不可变数组只能取值 可变数组可以増 删 改
2.1 初始化一个不可变数组
1> initWithObjects + 任意对象类型
有序填入每个元素 初始化结束以nil为判别标准 遇到nil 就表示数组结束
当数组里存在空元素时 如果用初始化 或者 构造器的话 程序运行不会报错 我们可能会不在意 可是此时数组中元素已经丢失 而字面量方式写的 数组可以使程序crash 能很直接的告诉我们 数组中存在空值 所以一般在创建数组时用字面量方法 我们也能知道 在数组中元素不能有空值
NSArray *array = [[NSArray alloc] initWithObjects: @"123", @"234", @"345", @"456", nil];
2> 构造器方法
NSArray *arr = [NSArray arrayWithObjects:@"123", @"234", @"345", @"456", nil];
3> 字面量 同 NSString @"" NSNumber @()
NSArray *myArray = @[@"123", @"234", @"345", @"456"];
2.2 数组的取值
1> count 取数组元素的个数
NSLog(@"%ld", array.count);
2> 通过下标取出数组元素
NSString *numStr = [array objectAtIndex:2];
3> array[0] 语法糖 取值
NSString *numStr1 = array[0];
4> 根据值取下标
NSUInteger indexObject = [array indexOfObject:@"234"];
NSLog(@"%ld", indexObject);
5> 用下面的方式来取数组中的元素 可以避免数组为空时 不必要的crash
[array lastObject];
[array firstObject];
2.3 初始化可变数组(不推荐使用字面量)
NSMutableArray *array = [NSMutableArray array];
1> 数组中添加元素
[array addObject:@"777"];
2> 插入
[array insertObject:@"hahah" atIndex:1];
3> 移除
[array removeObject:@"777"];
[array removeAllObjects];
4> 替换
[array replaceObjectAtIndex:0 withObject:@"zhaohao"];可变数组和不可变数组的区别
- 可变指的是本身可变 不可变要是想改变的话 就要用一个数组来接收
- 可变 继承于不可变 也就是说可变的数组是不可变的子类
字典
存储键值对(key - value)的集合类型
字典存储数据是无序的
通过key值存储 查找value
1> 初始化
先value 后key
字典中只能存放对象类型
如果有数字 将数字转化为NSNumber类型
3.1 不可变字典
1> 不可变字典初始化
NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:@"tantan", @"name", [NSNumber numberWithInt:18], @"age", @"tantan", @"firstName", nil];
2> 不可变字典遍历构造器
NSDictionary *dic1 = [NSDictionary dictionaryWithObjectsAndKeys:@"jiajia", @"name", [NSNumber numberWithInt:20], @"age", nil];
3> 字面量 先 key 后value (数字为NSNumber类型)
NSDictionary *dic2 = @{@"name": @"zhengyu", @"age": @(20), @"sex": @"man"};
4> 取值 通过key值取对应的value
NSString *str = [dic2 objectForKey:@"name"];
NSLog(@"%@", str);
5> 获取所有key值
NSArray *keyArr = [dic2 allKeys];
NSLog(@"%@", keyArr);
6> 获取所有value
NSArray *valueArr = [dic2 allValues];
NSLog(@"%@", valueArr);
7> count 与key 或 value的个数相同
NSUInteger count = [dic2 count];
NSLog(@"%ld", count);
8> 通过一个字典的key 取另一个字典中对应value数组
NSArray *allValueArr = [dic objectsForKeys:dic2.allKeys notFoundMarker:[NSNumber class]];
NSLog(@"%@", allValueArr);
9> 有可能两个相同的value 对应的key不同 用下面的方法就可以查找出所有不同的key 将这些key 放到一个数组里
NSArray *keyArray = [dic allKeysForObject:@"tantan"];
NSLog(@"%@", keyArray);
10> dic[@"name"]; (语法糖) dic[key]
NSLog(@"%@", dic1[@"name"]);
3.2 可变字典
1> 可变字典初始化方式 (不推荐使用字面量)
NSMutableDictionary *mutDic = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"yuhan", @"name", @"man", @"sex", @"18", @"age", nil];
NSMutableDictionary *mutDic1 = [[NSMutableDictionary alloc] init];
NSMutableDictionary *mutDic = [@{} mutableCopy]; (不推荐)
2> 取值与不可变 相同
3> 可变字典可以进行増 删 改 操作
4>. 给字典添加键值对 用setObject: forKey: 如果新增加的key存在 会将之前的value覆盖 如果key不存在 会使字典增加一个键值对1
[mutDic setObject:@"yuhan" forKey:@"name"];
[mutDic1 setObject:@"man" forKey:@"sex"];
NSLog(@"%@, %@", mutDic, mutDic1);
5>. 删除字典中的键值对
[mutDic removeObjectForKey:@"name"];
NSLog(@"%@", mutDic);
[mutDic removeAllObjects];
NSLog(@"%@", mutDic);
6>. 语法糖 赋值 与 字典添加键值对作用一样 可以向字典里添加键值对 也可以从字典里取 值
mutDic[@"where"] = @"huludao";
mutDic[@"birth"] = @"1993";
mutDic[@"study"] = @"college";
NSLog(@"%@", mutDic);
NSLog(@"%@", mutDic[@"where"]);遍历和排序
4.1 遍历
4.1.1 for循环遍历数组
将数组倒序输出 存放在一个可变数组中
首先创建一个不可变数组 让后用可变数组接收
NSArray *arr = @[@"伟仔", @"阿美", @"飞哥", @"糖糖", @"瑞瑞"];
NSMutableArray *mutArr = [NSMutableArray array];
for (NSInteger i = arr.count - 1; i >= 0; i--) {
[mutArr addObject:arr[i]];
}
NSLog(@"%@", mutArr);
4.1.2 for循环遍历字典
定义一个字典 遍历输出 name sex age
NSDictionary *dic = @{@"name": @"陈冠希", @"sex": @"man", @"age": @"35"};
NSArray *keyArr = dic.allKeys;
for (NSInteger i = 0; i < keyArr.count; i++) {
NSString *key = keyArr[i];
NSString *value = [dic objectForKey:key];
NSLog(@"%@ = %@", key, value);
4.1.3 枚举器遍历数组
NSEnumerator *stringArrayEnumerator = [arr objectEnumerator];
id value = nil;
while ((value = [stringArrayEnumerator nextObject])) {
NSLog(@"%@", value);
}
// 倒序输出
NSEnumerator *rever = [arr reverseObjectEnumerator];
id value1 = nil;
while ((value1 = [rever nextObject])) {
NSLog(@"%@", value1);
}
4.1.4 枚举器遍历字典
字典 枚举器 默认打印字典的value 也可以打印所有的key值 无序的
NSEnumerator *dicEnumerator = [dic.allKeys objectEnumerator];
id value2 = nil;
while (value2 = [dicEnumerator nextObject]) {
// NSArray *allKey = [dic allKeysForObject:value2]; 取key
NSLog(@"%@", value2);
}
4.1.5 枚举器遍历集合
NSSet *set = [NSSet setWithObjects:@"q", @"w", @"e", @"r", nil];
NSEnumerator *setEnu = [set objectEnumerator];
id setValue = nil;
while (setValue = [setEnu nextObject]) {
NSLog(@"%@", setValue);
}
4.1.6 快速枚举(for...in...) 遍历数组
NSString *newStr = [NSString string];
for (NSString *string in arr) {
NSLog(@"%@", string);
newStr = [newStr stringByAppendingString:string];
}
NSLog(@"%@", newStr);
4.1.7 快速枚举遍历字典
for (NSString *dicStr in dic) {
NSLog(@"%@", dicStr);
NSLog(@"%@", [dic objectForKey:dicStr]);
}
4.1.8 集合 快速遍历
for (NSString *setStr in set) {
NSLog(@"%@", setStr);
}
4.2 排序
参数1 key: 排序条件 参数2 acending YES(升序) / NO(降序)
数组有排序的方法
NSArray *numArr = @[@1, @7, @5, @4];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"self" ascending:YES];
numArr = [numArr sortedArrayUsingDescriptors:@[sort]];
NSLog(@"num: %@", numArr);
可变数组与不可变数组 排序使用的方法不同
NSMutableArray *numMutArr = [NSMutableArray arrayWithObjects:@"1", @"5", @"6", @"2", nil];
NSSortDescriptor *mutSort = [[NSSortDescriptor alloc] initWithKey:@"self" ascending:YES];
[numMutArr sortUsingDescriptors:@[mutSort]];
NSLog(@"%@", numMutArr);
4. 内存管理
- 内存溢出 没存用尽 导致crash
- 野指针 指针指向被释放的地方 过度释放
内存方式
垃圾回收机制 只有mac有
MRC 手动管理引用计数
ARC 自动管理引用计数 ARC基于MRC
看到 retain alloc copy 引用计数加1 需要进行内存管理
NSObject *objc = [[NSObject alloc] init];
[objc retain];
// 需要两次释放
[objc release];
[objc release];
release autorelease 会对引用计数减1
当对象的引用计数为0时 系统会调用相应的dealloc方法
ARC
语义特性: strong(强引用 引用计数加1) weak(应用于简单对象类型 弱引用 对象被释放时 对象会自动置空) retain(强引用 引用计数加1) copy(吧对象拷贝一份 原来的引用计数不变 新对象的引用计数加1) assign(应用于简单数据类型 不会产生引用计数)
协议 - 声明协议
- 签订协议
- 实现协议方法
注意事项:
在ARC工程下使用MRC的文件(三方) -fno-objc-arc
在MRC工程下使用ARC的文件 -fobjc-arc
需要加在 build phases下的编译source下
5. 类的扩展
- 类目
category(类别 类目 分类)
创建category (通过Object - C创建会产生两个文件 文件名: 类 + category名 .h / .m)
例: 创建一个类目, 给NSString添加方法 获取字符串首字母并将其大写
.h文件
#import <Foundation/Foundation.h>
@interface NSString (Uper)
- (void)getStr:(NSString *)str;
- (NSString *)getFirstChar;
@end
.m文件
#import "NSString+Uper.h"
@implementation NSString (Uper)
- (void)getStr:(NSString *)str {
NSString *str1 = [str uppercaseString];
NSLog(@"%@", [str1 substringToIndex:1]);
}
- (NSString *)getFirstChar {
NSString *first = [self substringWithRange:NSMakeRange(0, 1)];
return first.uppercaseString;
}
@end
main.m
#import <Foundation/Foundation.h>
#import "NSString+Uper.h"
int main(int argc, const char * argv[]) {
// 获取字符串首字母 并将其大写
NSString *str = @"zhaohao";
[str getStr:str];
NSString *first = [str getFirstChar];
NSLog(@"%@", first);
return 0;
}
-
延展(Extension) 一般定义在.m文件里
例:
.h文件中声明
#import <Foundation/Foundation.h>@interface Lovers : NSObject - (void)getLoverLife; @end
.m文件
#import "Lovers.h"
// 延展的声明
@interface Lovers ()
// 使用延展 可以保证.h的简洁 外界要用到的属性 / 方法才在.h中声明
// 延展中 主要实现属性 / 方法
@property (nonatomic, copy) NSString *cloth;
// 声明方法
- (void)shopping;
@end
@implementation Lovers
- (void)shopping {
NSLog(@"lalala");
}
- (void)whatchTV {
NSLog(@"HAHAH");
}
- (void)doSport {
NSLog(@"HEIHEIHEI");
}
- (void)getLoverLife {
[self shopping];
[self doSport];
[self doSport];
}
@end
-
代理delegate模式
Student.h
#import <Foundation/Foundation.h>
// 第一步 规定了协议内容
@protocol GetMacBook <NSObject>
- (NSString *)buyMacBook:(NSString *)money; // 默认必须实 现
@optional // 可选的实现方法
- (void)drawBill;
@end@interface Student : NSObject // 第二步 设定委托方 // 委托方的写法 @property (nonatomic, weak) id <GetMacBook> delegate; // 什么时候触发代理 - (void)seeWeChat; @end
Student.m
#import "Student.h"
@implementation Student
// 第三步 让代理人执行方法
- (void)seeWeChat {
// 代理人可能没有实现协议方法
// 判断代理人是否存在 判断代理人能否响应 对应的协议方法 当两者同时满足 执行
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(buyMacBook:)]) {
NSString *mac = [self.delegate buyMacBook:@"14000"];
NSLog(@"%@", mac);
}
}
@end
BuyPerson.h
#import <Foundation/Foundation.h>
#import "Student.h"
// 第四步 签订协议
@interface BuyPerson : NSObject <GetMacBook> // 签协议
@end
BuyPerson.m
#import "BuyPerson.h"
@implementation BuyPerson
// 实现协议方法
- (NSString *)buyMacBook:(NSString *)money {
NSLog(@"%@", money);
return @"mac";
}
@end
main.m
Student *stu = [[Student alloc] init];
BuyPerson *per = [[BuyPerson alloc] init];
// 设定代理人
stu.delegate = per;
[stu seeWeChat]
6. iOS新特性
-
nonnull nullable null_resettable修饰属性
Person.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN@interface Persson : NSObject // Nullability(判断为不为空的能力) 是在编译层次上加了一些改 动 (只能作用于对象类型) // nonnull声明的属性不能为空 (setter和getter方法) // @property (nonatomic, nonnull, assign) NSInteger age; (错的) @property (nonatomic, nonnull, copy) NSString *name; @property (nonatomic, copy) NSString * __nonnull size; // nullable声明属性可以为空 (setter和getter方法) @property (nonatomic, nullable, copy) NSString *sex; @property (nonatomic, copy) NSString * __nullable study; // UIViewController中的view属性 @property (null_resettable, nonatomic, strong) NSArray *friends; @property (nonatomic, strong) NSDictionary *dic; // NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END // 一般应用于不头文件.h 一般将属性包含起来 默认 nonnull 如 果是其他修饰要加 例如 nullable null_resettable 要写 NS_ASSUME_NONNULL_END @end
Person.m
#import "Persson.h"
@implementation Persson
// null_resettable 声明属性时会阿生冲突 需要重写setter方法处理掉为空的情况
- (void)setFriends:(NSArray *)friends {
if (friends == nil) {
friends = [NSArray array];
return;
}
_friends = friends;
}
@end
main.m
Persson *per1 = [[Persson alloc] init];
// nonnull 修饰属性 对应的getter和setter方法
per1.name = nil; // 不能为空
per1.name = @"zhoahao";
per1.size = nil; // 不能为空
// nullable 修饰属性 对应的getter和setter方法
// [per1 setSex:<#(NSString * _Nullable)#>];
per1.study = nil;
// null_resettable
// [per1 setFriends:<#(NSArray * _Nullable)#>] set 方法可以为空值
// [per1 friends]; getter 方法是nonnull
per1.friends = nil;
-
泛型
带泛型的容器 (规定了容器中所存储的类型 数组中添加其他类型会有警告 数组中取出的类型不再是id类型 泛型会改变类的一些方法 与之声明的方法相同) (例如: 声明一个可变数组内部存放的都是字符串 不能放其他类型)
NSMutableArray *array1 = [NSMutableArray arrayWithObjects:@"zhaohao", nil];
NSMutableArray<NSString *> *array = [NSMutableArray arrayWithObjects:@"123", nil];
// array1.lastObject. id 类型 没有length属性
// array.lastObject.length NSString类型 有length
[array addObject:@" "];
// [array addObject:@20];
// [array addObject:per1];
协变性 与 逆变性
#import <Foundation/Foundation.h>
// 自定义泛型声明方式
// @interface 类名<泛型名> : 父类
// 自定义泛型 声明后 泛型名 可以应用在属性 方法中
// 泛型名等效于 类型修饰 (例: NSString *)
@interface Truck<__contravariant ObjectType> : NSObject
@property (nonatomic, strong) ObjectType firstObject;
- (void)addObject:(ObjectType)object;- (id)anyObject; @end #import "Truck.h" @implementation Truck - (void)addObject:(id)object { } - (id)anyObject { return nil; } // 方法的返回值 是一个数组 / 可变数组 - (__kindof NSArray *)returnArray { // 加上kindof 返回的是这 个类及这个类的子类 // return @[]; return [NSMutableArray array]; } @end main.m Truck *oneTruck = nil; Truck<NSArray *> *truck1 = nil; Truck<NSMutableArray *> *truck2 = nil; // 大类型(任意类型) 可赋值给任意类型 任意类型也可赋值给大类型 oneTruck = truck1; oneTruck = truck2; truck1 = oneTruck; truck2 = oneTruck; // __covariant 协变性 子类在给父类赋值时 自动强转 truck1 = truck2; // __contravariant 逆变性 父类给子类赋值 自动强转 truck2 = truck1;
-
__kindOf
#import <Foundation/Foundation.h>
@interface Truck<__contravariant ObjectType> : NSObject
@property (nonatomic, strong) ObjectType firstObject;
- (void)addObject:(ObjectType)object;- (id)anyObject; - (__kindof NSArray *)returnArray; @end #import "Truck.h" @implementation Truck - (void)addObject:(id)object { } - (id)anyObject { return nil; } // 方法的返回值 是一个数组 / 可变数组 - (__kindof NSArray *)returnArray { // 加上kindof 返回的是这 个类及这个类的子类 // return @[]; return [NSMutableArray array]; } @end main.m Truck *truckKindOf = [[Truck alloc] init]; // NSMutableArray *arr = (NSMutableArray *)[truckKindOf returnArray]; // 强转 NSArray *arr1 = [truckKindOf returnArray];
7. UIView UIWindow
7.1 程序的组成结构
main.m (没有他, 程序不能正常运行)
AppDelegate (程序的执行者 签订了UIApplicationDelegate协议 其中的所有协议方法都是可选的) AppDelegate就和一个普通的类 因为签订了协议 所以得到很多方法
ViewController(主要负责视图管理)
Main.storyboard (主要负责视图管理) LaunchScreen.storyboard (可视化管理 主要负责启动页)
Assets.xcassets (主要用来管理图片素材) 原来叫 image.xcassets(x-code 7 之前)
LaunchScreen.storyboard
-
info.plist (工程配置文件)
模拟器 command + 1 ~ 5 (改变模拟器大小)
command + ← / → 横屏 / 竖屏
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
// 给Window 添加颜色
self.window.backgroundColor = [UIColor whiteColor];
// 让Window 显示并成为主窗口
[_window makeKeyAndVisible];
// 从x-code7以后 必须设置 rootViewController
// 设置Windows主窗口
_window.rootViewController = [[ViewController alloc] init];// 设置坐标 UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 270, 270)]; view.backgroundColor = [UIColor cyanColor]; // 将view添加到window [self.window addSubview:view];
iOS坐标系 与 数学上的坐标系不同 y轴正方向是想下的 原点是屏幕的左上角
frame bounds center 都是UIView的属性
frame (x, y, width, height) 指的是在他父视图上的位置
bounds (x, y, width, height) 指的是视图本身的坐标系 bounds x y 修改了本身的坐标 影响他的子视图 bounds (x, y) 修改的是本身的大小 根据其中心点进行收缩或扩张 bounds的改变 不会影响其中心点
- 使用父类初始化方法(用来显示文本)
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, 200, 270, 120)];
label.backgroundColor = [UIColor blackColor];
[_window addSubview:label]; - UILabel
text
label.text = @"美梦是个气球 牵在手上 向往蓝天 不管高低 不曾远离 我视线 梦想是个诺言 写在心上 明天你是否会想起 昨天你写的日记 明天你是否还惦记曾经最爱哭的你 老师们都已想不起";
// textColor
label.textColor = [UIColor whiteColor];
// font
label.font = [UIFont systemFontOfSize:17]; // 默认17
// label.font = [UIFont boldSystemFontOfSize:10]; 加粗
// textAlignment 对齐方式 0 1 2 枚举
label.textAlignment = 0;
// numberOfLines 不确定行数时 赋值 0
label.numberOfLines = 0; - UIButton
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(100, 100, 60, 30);
button.backgroundColor = [UIColor redColor];
[_window addSubview:button];
// 给button添加事件
[button addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
// 添加文字
[button setTitle:@"确认" forState:UIControlStateNormal];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - UITextField
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(50, 370, 270, 30)];
textField.backgroundColor = [UIColor redColor];
[_window addSubview:textField];
// 给输入框赋初值
// textField.text = @"文字";
// 文字颜色
textField.textColor = [UIColor blackColor];
// borderStyle 边缘
textField.placeholder = @"请输入密码";
textField.clearsOnBeginEditing = YES; // command + k
7.2 使用button 设计一个播放和暂停的功能
#import "AppDelegate.h"
#import "ViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
[self.window makeKeyAndVisible];
self.window.rootViewController = [[ViewController alloc] init];
UIButton *playButton = [UIButton buttonWithType:UIButtonTypeSystem];
playButton.frame = CGRectMake(50, 100, 150, 30);
playButton.backgroundColor = [UIColor redColor];
[playButton setTitle:@"播放" forState:UIControlStateNormal];
[playButton addTarget:self action:@selector(playSong:) forControlEvents:UIControlEventTouchUpInside];
[self.window addSubview:playButton];
// 暂停
- (void)pasueSong:(UIButton *)pasueSong {
NSLog(@"暂停");
[pasueSong removeTarget:self action:@selector(pasueSong:) forControlEvents:UIControlEventTouchUpInside];
[pasueSong addTarget:self action:@selector(playSong:) forControlEvents:UIControlEventTouchUpInside];
[pasueSong setTitle:@"播放" forState:UIControlStateNormal];
}
- (void)playSong:(UIButton *)playButton {
NSLog(@"播放");
// 移除点击事件
[playButton removeTarget:self action:@selector(playSong:) forControlEvents:UIControlEventTouchUpInside];
[playButton addTarget:self action:@selector(pasueSong:) forControlEvents:UIControlEventTouchUpInside];
[playButton setTitle:@"暂停" forState:UIControlStateNormal];
}
7.3 利用imageView设计简单动画
#import "AppDelegate.h"
#import "ViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
// 已经完成加载时 会走这个方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
[self.window makeKeyAndVisible];
self.window.backgroundColor = [UIColor whiteColor];
self.window.rootViewController = [[ViewController alloc] init];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIImage *image = [UIImage imageNamed:@"BackGround.png"];
[imageView setImage:image];
[self.window addSubview:imageView];
UIImageView *flowerImageView = [[UIImageView alloc] initWithFrame:CGRectMake(55, 100, 100, 100)];
NSMutableArray *flowerArray = [NSMutableArray array];
for (int i = 1; i < 19; i++) {
NSString *flowerName = [NSString stringWithFormat:@"flower%d.tiff", i];
UIImage *flowerImage = [UIImage imageNamed:flowerName];
[flowerArray addObject:flowerImage];
}
flowerImageView.animationImages = flowerArray;
flowerImageView.animationDuration = 2;
flowerImageView.animationRepeatCount = 0;
[flowerImageView startAnimating];
[self.window addSubview:flowerImageView];
UIImageView *guaImageView = [[UIImageView alloc] initWithFrame:CGRectMake(55, 200, 100, 100)];
NSMutableArray *guaArray = [NSMutableArray array];
for (int i = 1; i < 17; i++) {
NSString *guaName = [NSString stringWithFormat:@"gua%d.tiff", i];
UIImage *guaImage = [UIImage imageNamed:guaName];
[guaArray addObject:guaImage];
}
guaImageView.animationImages = guaArray;
guaImageView.animationDuration = 2;
guaImageView.animationRepeatCount = 0;
[guaImageView startAnimating];
[self.window addSubview:guaImageView];
UIImageView *plantsImageView = [[UIImageView alloc] initWithFrame:CGRectMake(55, 300, 100, 100)];
NSMutableArray *plantsArray = [NSMutableArray array];
for (int i = 1; i < 10; i++) {
NSString *plantsName = [NSString stringWithFormat:@"plants%d.tiff", i];
UIImage *plantsImage = [UIImage imageNamed:plantsName];
[plantsArray addObject:plantsImage];
}
plantsImageView.animationImages = plantsArray;
plantsImageView.animationDuration = 2;
plantsImageView.animationRepeatCount = 0;
[plantsImageView startAnimating];
[self.window addSubview:plantsImageView];
return YES;
}
7.4 UIViewController
-
在UIViewController中程序执行的顺序
// 初始化方法
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// 不要再这个方法中加载视图
// 在这个方法中去初始化一些数据相关的内容
}
return self;
}// 加载ViewController中的view // UINavagationController UITableViewController在 loadView中给赋值的 - (void)loadView { [super loadView]; NSLog(@"loadView"); } // view已经加载 // 自定义视图创建 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } // 下列方法 会执行多次+ - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; }
7.5 模态跳转页面
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
PresentViewController *present = [[PresentViewController alloc] init];
// 模态出一个视图控制器
present.modalTransitionStyle = 1; // 翻页的效果
[self presentViewController:present animated:YES completion:nil];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 返回上一页 (让模态出来的页面消失)
[self dismissViewControllerAnimated:YES completion:nil];
}