——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——
UI概览
程序运行的过程:当程序运行起来的时候,程序加载storyboard文件中箭头所指的控制器,由控制器负责创建里面的视图,视图负责创建里面的小的控件,然后显示出界面。
storyboard文件:storyboard是用来描述界面的,其中的剪头表示程序入口,指的是一个UI控制器 (ViewControler)。
view:表示控件(视图),父空间、子空间。
viewControler:视图控制器,用来管理视图,包括管理视图的创建和销毁、监听其中的子控件和用户的交互。
延展类(扩展类):
一般用来存放只是在内部使用的方法或者属性。
好处:安全
@interface ViewController()
@end
监听按钮点击
用视图控制器来监听按钮的点击
通过创建一个方法来监听按钮的点击,监听到按钮点击后做一些事情。为了让按钮和方法之间建立联系,我们需要连线,为了保证方法可以和监听的按钮进行连线,方法用IBAction修饰。
用属性来描述控件,UI控件必须用weak修饰,为了保证属性连线,属性用IBOutlet修饰。
创建弹窗
ios7的弹窗实现:
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"登录提示" message:@"登录成功" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
[alert show];
ios8的弹窗实现:
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"登录提示" message:@"登录失败" preferredStyle:UIAlertControllerStyleActionSheet];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alert animated:NO completion:nil];
点击按钮退出键盘
1>. 释放第一响应者(叫出键盘的控件就叫第一响应者):使用resignFirstResponder 方法来释放第一响应者。
2>. 第一响应者的父控件退出编辑状态:[self.view endEditing:YES];
UIButton按钮
按钮能同时显示图片和文字
按钮是分状态的(nomal(普通)、highlighted(高亮))
按钮能够显示不同状态下的文字和颜色
注意:
不能直接访问对象的 结构体属性的 成员变量
能够访问对象的结构体属性
赋值对象结构体成员属性三部曲:
1>. 取出对象的结构体属性struct,然后赋值给临时变量
2>. 修改临时变量的值
3>. 用临时变量覆盖原来的struct
添加动画
头尾式:
在要执行动画的头部开启动画 [UIView beginAnimations:nil context:nil];
在要执行动画的尾部提交动画 [UIView commitAnimations];
Transform形变属性
transform 是一种状态,并且只有一种状态
1. CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty):始终是以最原始的状态值进行变化的,所以只能变化一次。
2. CGAffineTransformMakeTranslation(CGAffineTransform t, CGFloat tx, CGFloat ty):能够变化多次,每次变化都是以上一次的状态t进行的变化。
3. CGAffineTransformIdentity:清空所有的设置的transform
懒加载:重写get方法
核心思想:当数据不存在的时候加载
好处:懒加载也叫延迟加载,在使用到数据的时候才加载数据,加载之前节省下的内存可以去做别的事,提高性能。
获取plist文件的路径
NSBundle是一个资源文件夹
mainBundle获取一个主要资源文件夹
NSString* path = [[NSBundle mainBundle] pathForResource:@”images” ofType:@”plist”];
有file必需传入全路径
[NSArray arrayWithContentsOfFile:path];
数据模型
字典:字典是NSDictionary类型,用键值对来存储数据,不好处(key值容易写错)
模型:是一个纯洁的Object类型,用属性来存储数据的,一个字典对应一个模型
字典转化模型:把字典中键值对转换成模型中的属性,把字典中的value值赋值给模型的属性
属性的确定
类型:取决于键值对中value值的类型
名称:取决于键值对中key值的名称
模型建立时:string类型一般用copy
ImageView播放动画的内存优化
序列帧动画:把有序的图片一张一张播放出来就叫序列帧动画
imageNamed:加载完图片后图片不会释放,图片会驻留内存
imageWithContentsOfFile:图片不会驻留内存
当动画执行完毕以后,将ImageView的animationImages设置为nil
xib
xib:用来描述界面,用来描述局部固定的界面
storyBoard:用来描述界面,是用来描述整体界面的
KVC (key - value - coding) 键值编码
一种可以直接通过字符串的名字(key)来访问类属性的机制。而不是通过调用Setter、Getter方法访问。当使用KVO、Core Data、CocoaBindings、AppleScript(Mac支持)时,KVC是关键技术。
获取值
valueForKey:,传入NSString属性的名字。
valueForKeyPath:,传入NSString属性的路径,xx.xx形式。
valueForUndefinedKey:它的默认实现是抛出异常,可以重写这个函数做错误处理。
修改值
setValue:forKey:
setValue:forKeyPath:
setValue:forUndefinedKey:
setNilValueForKey: 当对非类对象属性设置nil时,调用,默认抛出异常。
UIScrollView
NSTimer
当使用NSTimer的scheduledTimerWithTimeInterval方法时。事实上此时Timer会被加入到当前线程的Run Loop中,且模式是默认的NSDefaultRunLoopMode。而如果当前线程就是主线程,也就是UI线程时,某些UI事件,比如UIScrollView的拖动操作,会将Run Loop切换成NSEventTrackingRunLoopMode模式,在这个过程中,默认的NSDefaultRunLoopMode模式中注册的事件是不会被执行的。也就是说,此时使用scheduledTimerWithTimeInterval添加到Run Loop中的Timer就不会执行。
为了设置一个不被UI干扰的Timer,我们需要手动创建一个Timer,然后使用NSRunLoop的addTimer:forMode:方法来把Timer按照指定模式加入到Run Loop中。这里使用的模式是:NSRunLoopCommonModes,这个模式等效于NSDefaultRunLoopMode和NSEventTrackingRunLoopMode的结合。
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"主线程 %@", [NSThread currentThread]);
//创建Timer
NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(timer_callback) userInfo:nil repeats:YES];
//使用NSRunLoopCommonModes模式,把timer加入到当前Run Loop中。
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
//timer的回调方法
- (void)timer_callback
{
NSLog(@"Timer %@", [NSThread currentThread]);
}
// 模拟器的位置:
/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs
// 文档安装位置:
/Xcode.app/Contents/Developer/Documentation/DocSets
// 插件保存路径:
/Users/yesway/Library/ApplicationSupport/Developer/Shared/Xcode/Plug-ins yesway表示:个人。
// 自定义代码段的保存路径:
/Users/yesway/Library/Developer/Xcode/UserData/CodeSnippets
NSNotificationCenter(消息通信机制)
作用:NSNotificationCenter是专门供程序中不同类间的消息通信而设置的.
注册通知:即要在什么地方接受消息
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mytest:) name:@” mytest” object:nil];
参数介绍:
addObserver:观察者,即在什么地方接收通知;
selector: 收到通知后调用何种方法;
name: 通知的名字,也是通知的唯一标示,编译器就通过这个找到通知的。
发送通知:调用观察者处的方法。
[[NSNotificationCenter defaultCenter] postNotificationName:@”mytest”object:searchFriendArray];
参数:
postNotificationName:通知的名字,也是通知的唯一标示,编译器就通过这个找到通知的。
object:传递的参数
UIKeyboardAnimationCurveUserInfoKey = 7; //动画执行的节奏
UIKeyboardAnimationDurationUserInfoKey = "0.25"; //动画执行时间间隔
UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {375, 258}}"; //键盘bounds
//动画执行前的键盘中心的开始位置
UIKeyboardCenterBeginUserInfoKey = "NSPoint: {187.5, 796}";
//动画执行完毕后的键盘中心的开始位置
UIKeyboardCenterEndUserInfoKey = "NSPoint: {187.5, 538}";
//动画执行前键盘的frame
UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 667}, {375, 258}}";
//动画执行后键盘的frame
UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 409}, {375, 258}}";
// 注册监听
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrameNotification:) name:UIKeyboardWillChangeFrameNotification object:nil];
- (void) keyboardWillChangeFrameNotification:(NSNotification *) notifcation
{
// iOS8 只要在通知方法中只需要调整位置就会按照键盘的节奏执行动画
// NSLog(@"%@",notifcation.userInfo);
// 取出键盘结束的时候的frame
CGRect endFrame = [notifcation.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
// view的Y坐标
CGFloat viewY = endFrame.origin.y - self.view.frame.size.height;
// 设置控制器view的Y坐标
CGRect viewFrame = self.view.frame;
viewFrame.origin.y = viewY;
// 动画执行时间
CGFloat duration = [notifcation.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
// 当适配iOS7时候这个动画节奏写死 7 << 16
[UIView animateWithDuration:duration delay:0 options: 7 << 16 animations:^{
self.view.frame = viewFrame;
} completion:nil];
}
// 退出键盘
// resign 辞职
// [self.textField resignFirstResponder];
// YES 表示强制退出
[self.view endEditing:YES];
#import <Foundation/Foundation.h>
#import "HMPerson.h"
int main(int argc, const char * argv[]) {
// 1.通知的发布者 腾讯 新浪
// 获取通知中心的单例
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
// 3.通知的接受者 人
HMPerson *zhanSan = [[HMPerson alloc] init];
zhanSan.name = @"张三";
HMPerson *xiaoMing = [[HMPerson alloc] init];
xiaoMing.name = @"小明";
[center addObserver:zhanSan selector:@selector(receiveNotification:) name:@"娱乐" object:@"腾讯"];
// [center addObserver:xiaoMing selector:@selector(receiveNotification:) name:@"娱乐" object:@"腾讯"];
[center addObserver:xiaoMing selector:@selector(receiveNotification:) name:nil object:nil];
// 发布从通知
[center postNotificationName:@"娱乐" object:@"腾讯" userInfo:@{@"娱乐":@"张李范"}];
[center postNotificationName:@"财经" object:@"新浪" userInfo:@{@"股市":@"过山车"}];
[center postNotificationName:@"财经" object:@"腾讯" userInfo:@{@"股票":@"乐视总裁套现27亿"}];
return 0;
}
杂项
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
code需要延迟执行的代码
}
/**
* 返回可拉伸图片
*/
+ (instancetype)resizableImageNamed:(NSString *)imageName
{
// 获取图片
UIImage *image = [UIImage imageNamed:imageName];
CGFloat left = image.size.width * 0.5;
CGFloat right = left;
CGFloat top = image.size.height * 0.5;
CGFloat bottom = top;
return [image resizableImageWithCapInsets:UIEdgeInsetsMake(top, left, bottom, right)];
}
/**
* 根据最大宽度和字体返回字符串的大小[尺寸]
*/
- (CGSize)sizewithMaxWidth:(CGFloat)maxWidth andFont:(UIFont *)font
{
// 2.计算文本的最大区域
CGSize maxSize = CGSizeMake(maxWidth, CGFLOAT_MAX);
// 3.计算文本使用字体
NSDictionary *attr = @{NSFontAttributeName:font};
// 4.文本实际大小
CGSize textSize = [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attr context:nil].size;
return textSize;
}
/*
一个控件不显示的原因:
1.没有frame
2.没有添加到view的层次结构中
3.控件的颜色与父控件的颜色一样
4.透明
5.hidden = YES
6.被其他控件挡住了
7.frame在屏幕的外部
8.父控件出现上述情况
*/
// 如果缓冲池中有重用的Cell,那么使用缓冲池中的,如果没有,就去storyboard中查找有没有这个标识的cell,如果有就使用这个Cell做为模板创建cell
HMAppCell *cell = [tableView dequeueReusableCellWithIdentifier:@"app"];
// 2.9圆角
// 2.9.1设置半径
msgLabel.layer.cornerRadius = 8;
// 2.9.2切掉多余部分
msgLabel.layer.masksToBounds = YES;
//使用自动布局时UITableView行高设置
self.tableView.rowHeight = UITableViewAutomaticDimension; //让系统自动计算行高
self.tableView.estimatedRowHeight = 20; //xcode6.3还需要设置估算的行高
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——