黑马程序员——UI基础纪要

——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

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培训、期待与您交流! ——

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值