ios开发系列应注意点
本人作为一名ios开发者,将自己的ios开发过程中遇到的重点难点和易犯错点记录下来,希望可以帮助到大家
1.UI基础的一些知识点
1.如何连线
连线的方式:
1)可以先在控制器中手写一个方法,返回值为IBAction,然后点击空心圆圈,拖线连到要监听的按钮上
2)也可以按住control键,从控件直接拖线到控制器的 @implementation代码块里面,通过窗体配置事件的监听方法,点connect,完成连线
2.NSInteger对应的占位符%zd
%zd 的含义:
* 从头文件可以看到:NSInteger在64为系统是 long类型的;在32为系统为int类型的;
* 所以加入这里写 %ld或 %d,都不能满足两种CPU运行环境
* %zd 会根据CPU不同,判断数据的长度
在32位系统中:%zd == %d
在64为系统中:%zd == %ld
3.如何对数字进行自动装箱(包装成对象)
@(result).description 先‘装箱’,把数字装箱成对象,然后调用对象的description方法,就会把数字对象打印成字符串
4.结构体赋值方法
要修改一个对象的结构体属性里面的一个变量时,不能直接修改,而要先取出整个结构体,然后修改,然后在把修改后的结构体赋值回对象
5.关于按钮控件
按钮控件是一个 ‘复合’控件:按钮里面内置了一个 UIImageView、一个 UILabel
6.可以下载源码的网站
www.code4app.com
2.三个案例
1.纯代码编写的小飞机案例
#import "ViewController.h"
/**
* 飞机按钮移动方向枚举
*/
typedef NS_ENUM(NSInteger, HMPlaneFlyDirection) {
HMPlaneFlyDirectionTop = 100,// 页面设置的Tag值
HMPlaneFlyDirectionBottom = 101,
HMPlaneFlyDirectionLeft = 102,
HMPlaneFlyDirectionRight = 103
};
@interface ViewController ()
@property (nonatomic, weak) UIButton *btnPlane;
@end
@implementation ViewController
/*
* 控制器有创建视图的责任,在创建并且显示视图的过程中,有很多个阶段,每个阶段都会有一个方法被调用
* 例如:
* - (void)viewWillAppear:(BOOL)animated; // 视图将要显示的时候
* - (void)viewDidAppear:(BOOL)animated; // 视图已经显示的时候
* - (void)viewWillDisappear:(BOOL)animated; // 视图将要消失的时候
* - (void)viewDidDisappear:(BOOL)animated; // 视图已经消失的时候
*/
// 视图已经加载,但是还没有显示的时候
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. 翻译:在视图加载之后,可以在这里做一些附加的初始化。自己的语言理解:根视图view加载之后,想要在跟视图里面添加一些子视图,在这里做!
// 搭建界面:放一个背景图片框,一个飞机按钮,四个方向按钮。想象一下:代码太少不了,我们把这些代码封装到一个方法里面
[self setupUI];
}
- (void)setupUI{
// 创建一个背景图片框,放图片
/**
* 在屏幕上显示一个控件的过程
* 1. 创建一个控件对象
* 2. 设置控件要显示的位置和大小(frame)
* 3. 添加到一个视图里面(父试图)
*/
// 1. 创建一个控件对象
UIImageView *imgVBackGround = [[UIImageView alloc] init];
// 2. 设置控件要显示的位置和大小(frame)
imgVBackGround.frame = self.view.frame;
// 2.1 设置控件的属性:图片
imgVBackGround.image = [UIImage imageNamed:@"background"];
// 3. 添加到一个视图里面(父试图):通过addSubView方法将视图添加到父试图中
[self.view addSubview:imgVBackGround];
// 添加飞机按钮
// 1. 创建一个控件对象
UIButton *btnPlane = [UIButton buttonWithType:UIButtonTypeCustom];
// 2. 设置控件要显示的位置和大小(frame)
// 2.1 设置控件的属性
UIImage *imgNormal = [UIImage imageNamed:@"hero1"];
UIImage *imgHighlighted = [UIImage imageNamed:@"hero2"];
// 为button设置图片的方法 , 其中forState就是之前学的按钮的状态,Default(Normal) 和 Hightlighted
[btnPlane setImage:imgNormal forState:UIControlStateNormal];
[btnPlane setImage:imgHighlighted forState:UIControlStateHighlighted];
// 可以通过 CGRectMake 方法设置 frame 的值
// btnPlane.frame = CGRectMake(0, 0, 100, 100);
// 也可以通过确定控件的大小和位置的方式,让控件自己去计算frame
[btnPlane sizeToFit];// 确定了 控件的大小
btnPlane.center = self.view.center;// 确定了 控件的位置
// 3. 添加到一个视图里面(父试图):通过addSubView方法将视图添加到父试图中
[self.view addSubview:btnPlane];
self.btnPlane = btnPlane;
// 添加四个方向按钮:一个按钮上面就那么多代码,何况四个呢。。。封装
UIButton *topButton = [self setupDirectionButton:@"top"];
UIButton *bottomButton = [self setupDirectionButton:@"bottom"];
UIButton *leftButton = [self setupDirectionButton:@"left"];
UIButton *rightButton = [self setupDirectionButton:@"right"];
// 把四个按钮添加到屏幕上
[self.view addSubview:topButton];
[self.view addSubview:bottomButton];
[self.view addSubview:leftButton];
[self.view addSubview:rightButton];
// 下面为四个按钮设置frame
// 首先定义一个浮点数:保存按钮的宽和高
CGFloat buttonWH = 40;
// 然后一个等宽等高的矩形,作为四个按钮的中间矩形(屏幕中点向下200的地方)
CGRect centerRect = CGRectMake(self.view.center.x - buttonWH * 0.5, self.view.center.y + 200, 40, 40);
// 设定一个偏移量
CGFloat offset = 50;
// CGRectOffset 根据某一个确定的rect,在x、y轴上进行一定的偏移后得到的rect
topButton.frame = CGRectOffset(centerRect, 0, -offset);
bottomButton.frame = CGRectOffset(centerRect, 0, offset);
leftButton.frame = CGRectOffset(centerRect, -offset, 0);
rightButton.frame = CGRectOffset(centerRect, offset, 0);
// 设置tag
topButton.tag = HMPlaneFlyDirectionTop;
bottomButton.tag = HMPlaneFlyDirectionBottom;
leftButton.tag = HMPlaneFlyDirectionLeft;
rightButton.tag = HMPlaneFlyDirectionRight;
}
/**
* 这个方法只负责创建按钮并设置图片,不负责设置frame和添加到视图中
*
* @param strDirection 方向字符串:top | bottom | left | right
*
* @return 创建的按钮
*/
- (UIButton *)setupDirectionButton:(NSString *)strDirection{
UIButton *btnDirect = [UIButton buttonWithType:0];
UIImage *imgNormal = [UIImage imageNamed:[NSString stringWithFormat:@"%@_normal",strDirection]];
UIImage *imgHighlighted = [UIImage imageNamed:[NSString stringWithFormat:@"%@_highlighted",strDirection]];
[btnDirect setImage:imgNormal forState:UIControlStateNormal];
[btnDirect setImage:imgHighlighted forState:UIControlStateHighlighted];
/**
* 使用代码的方式添加按钮点击事件的监听(发生关系)
* 参数1:按钮的点击事件由谁来监听?self:代表当前对象方法的对象--控制器对象
* 参数2:按钮的点击事件由当前控制器对象的哪个方法来监听?这里需要定义一个方法,@selector(clickDirectionButton:)中的 ":" 代表的是后面有一个参数。按钮点击事件的监听方法后面的参数默认是触发事件的控件
*
*
*/
[btnDirect addTarget:self action:@selector(clickDirectionButton:) forControlEvents:UIControlEventTouchUpInside];
return btnDirect;
}
- (void)clickDirectionButton:(UIButton *)button{
// 拿出控件的tag属性值
NSInteger tag = button.tag;
// 拿出飞机按钮的frame属性,准备修改
// center:控件的中心点在父试图中的坐标;通过修改控件的中心点在父试图中的位置的坐标,也可以实现控件位置的修改
// CGRect frm = self.btnPlane.frame;
CGPoint center = self.btnPlane.center;
// 给Magic Number 以一定的意义:偏移量
CGFloat offset = 10;
// 通过tag。分别按钮的不同方向,修改不同的变量
switch (tag) {
// 在实际开发中,像下面这种‘100’,‘101’,‘10’……等数字我们称为‘硬编码’或‘Magic Number’(魔法数字),这种代码最好不要出现在编码中,因为我们写代码不是给机器看的,而是给人看的,是为了让别人能够看明白你的代码,能够维护你的代码,所以我们一定要给这种编码以一定的意义
case HMPlaneFlyDirectionTop:// 向上
center.y -= offset;
break;
case HMPlaneFlyDirectionBottom:// 向下
center.y += offset;
break;
case HMPlaneFlyDirectionLeft:// 向左
center.x -= offset;
break;
case HMPlaneFlyDirectionRight:// 向右
center.x += offset;
break;
default:
break;
}
// 把结构体赋值回对象
self.btnPlane.center = center;
}
@end
2.纯代码编写的汇率计算器
#import "ViewController.h"
#define HUILV 6.1314
@interface ViewController ()
@property (nonatomic,weak) UITextField *textNum;
@property (nonatomic,weak) UILabel *labRes;
@property (nonatomic,weak) UILabel *labHuiLv;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setCountryImgView];
[self setTextView];
[self setLableView];
[self setSubView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/**
* 设置国家图片
*
* @param countryName 国家名称
* @param imgRect 图片大小
*/
- (void)setCountryImgWith:(NSString*)countryName andwith:(CGRect)imgRect{
UIImageView *countryImgView = [UIImageView new];
UIImage *countryImg = [UIImage imageNamed:countryName];
[countryImgView setImage:countryImg];
countryImgView.frame = imgRect;
[self.view addSubview:countryImgView];
}
/**
* 创建图片视图
*/
-(void)setCountryImgView{
CGRect usaRect = CGRectMake(10, 30, 150, 110);
[self setCountryImgWith:@"USA" andwith:usaRect];
CGRect chinaRect = CGRectMake(10, 150, 150, 110);
[self setCountryImgWith:@"China" andwith:chinaRect];
}
/**
* 创建文字域视图
*/
- (void)setTextView{
UITextField *textNum = [UITextField new];
//设置无边框
[textNum setBorderStyle:UITextBorderStyleNone];
//设置无输入时文字
[textNum setPlaceholder:@"请在此输入金额"];
//设置字体大小
UIFont *textFont = [UIFont systemFontOfSize:14];
[textNum setFont:textFont];
//设置右对齐
[textNum setTextAlignment:NSTextAlignmentRight];
//设置数字键盘
[textNum setKeyboardType:UIKeyboardTypeNumberPad];
//设置清空按钮
[textNum setClearButtonMode:UITextFieldViewModeWhileEditing];
//设置位置
CGRect textRect = CGRectMake(200, 100, 150, 30);
textNum.frame = textRect;
[self.view addSubview:textNum];
_textNum = textNum;
}
/**
* 设置结果Lable
*/
- (void)setLableView{
UILabel *labResultView = [UILabel new];
labResultView.text = @"此处显示结果";
UIFont *resFont = [UIFont systemFontOfSize:14];
[labResultView setFont:resFont];
[labResultView setTextAlignment:NSTextAlignmentRight];
CGRect resLabRect = CGRectMake(200, 220, 150, 30);
labResultView.frame = resLabRect;
[self.view addSubview:labResultView];
_labRes = labResultView;
}
//创建子视图
- (void)setSubView{
UIView *subView = [UIView new];
CGRect subViewRect = CGRectMake(0, 280, self.view.frame.size.width, self.view.frame.size.height-150);
subView.frame = subViewRect;
UIColor *subViewColor = [UIColor lightGrayColor];
[subView setBackgroundColor:subViewColor];
[self.view addSubview:subView];
//添加按钮
[self setButton];
//添加汇率描述
[self setHuiLvLab];
}
//创建按钮
- (void)setButton{
UIButton *butRes = [UIButton buttonWithType:UIButtonTypeCustom];
UIColor *nomColor = [UIColor greenColor];
[butRes setTitle:@"计算" forState:UIControlStateNormal];
[butRes setTitle:@"计算中" forState:UIControlStateHighlighted];
[butRes setBackgroundColor:nomColor];
CGRect butRect = butRes.frame;
CGSize butSize = CGSizeMake(100, 30);
butRect.size = butSize;
butRes.frame = butRect;
CGPoint butCenter = CGPointMake(self.view.center.x, 450);
butRes.center = butCenter;
[self.view addSubview:butRes];
[butRes addTarget:self action:@selector(clickResButton) forControlEvents:UIControlEventTouchUpInside];
}
//设置汇率lab
- (void)setHuiLvLab{
UILabel *labHuiLv = [UILabel new];
float huilv = HUILV;
NSString *dateStr = [self getNowTime];
UIFont *huilvFont = [UIFont systemFontOfSize:13];
[labHuiLv setFont:huilvFont];
labHuiLv.text = [NSString stringWithFormat:@"当前汇率为%.4f,更新于%@",huilv,dateStr];
CGRect huiLvRect = CGRectMake(20, 380, self.view.frame.size.width-40, 30);
labHuiLv.frame = huiLvRect;
[self.view addSubview:labHuiLv];
_labHuiLv = labHuiLv;
}
//创建按钮监听
-(IBAction)clickResButton{
NSInteger inputNum = self.textNum.text.integerValue;
NSString *resStr = @(inputNum * HUILV).description;
self.labRes.text = resStr;
float huilv = HUILV;
NSString *dateStr = [self getNowTime];
self.labHuiLv.text = [NSString stringWithFormat:@"当前汇率为%.4f,更新于%@",huilv,dateStr];
[self.view endEditing:YES];
}
//得到当前时间
- (NSString*)getNowTime{
NSDate *nowDate = [NSDate new];
NSDateFormatter *fom = [NSDateFormatter new];
fom.dateFormat = @"yyyy年MM月dd日HH时mm分ss秒";
NSString *dateStr = [fom stringFromDate:nowDate];
return dateStr;
}
@end
3.关于格式化时间输出的方法
//得到当前时间
- (NSString*)getNowTime{
NSDate *nowDate = [NSDate new];
NSDateFormatter *fom = [NSDateFormatter new];
fom.dateFormat = @"yyyy年MM月dd日HH时mm分ss秒";
NSString *dateStr = [fom stringFromDate:nowDate];
return dateStr;
}
3.快捷键
1.一些好用的快捷键
Control + A:移动光标到行首
Control + E:移动光标到行末
Control + D:删除光标右边的字符
Control + K:删除本行
Command + ->:移动到行尾
创建新工程:command + shift + n
快速看头文件:command + shift + o
模拟器home键:command + shift + h
模拟器键盘: command + h
4.UI基础控件的使用
1.UIView有关
// frame设置需要有中间值
CGRect frame = bigView.frame;
frame.size.width *= 2;
frame.size.height *= 2;
bigView.frame = frame;
// 圆角
bigView.layer.cornerRadius = 150;//角度设为frame.width/height则是个圆
bigView.clipsToBounds = YES;
// 边框
bigView.layer.borderWidth = 2;
bigView.layer.borderColor = [[UIColor blackColor] CGColor];
// 设置背景图片
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Default"]];
/*
//相对父视图的坐标
@property(nonatomic) CGRect frame;
//相对于自己内容的坐标
@property(nonatomic) CGRect bounds;
//父视图
@property(nonatomic,readonly) UIView *superview;
//所有的子视图
@property(nonatomic,readonly,copy) NSArray *subviews;
//内容模式(填充一边位等比例模式)
@property(nonatomic) UIViewContentMode contentMode; // default UIViewContentModeScaleToFill
//在最上层添加一个视图
- (void)addSubview:(UIView *)view;
//在指定层面插入一个视图(如果层级越界,就相当于add)
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;
//在某个视图是下级插入一个新视图
- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;
//在某个视图的上级插入一个新视图
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;
//从父视图中移除(自杀)
- (void)removeFromSuperview;
//修改2个视图的层级
- (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2;
//将某个视图移到最上层
- (void)bringSubviewToFront:(UIView *)view;
//将某个视力移到最底层
- (void)sendSubviewToBack:(UIView *)view;
//判断一个视图是否是别外一个视图的子视图(如果是同一个视图也会返回yes)
- (BOOL)isDescendantOfView:(UIView *)view;
//通过tag找view
- (UIView *)viewWithTag:(NSInteger)tag;
*/
2.UILable有关
/*
//设置文字
@property(nonatomic,copy) NSString *text;
//文字颜色
@property(nonatomic,retain) UIColor *textColor;
//阴影颜色
@property(nonatomic,retain) UIColor *shadowColor;
//阴影坐标
@property(nonatomic) CGSize shadowOffset;
//将label大小调整为单行展示文字所需要的大小
- (void)sizeToFit;
//对齐方式
@property(nonatomic) NSTextAlignment textAlignment;
//换行方式省略号位置
@property(nonatomic) NSLineBreakMode lineBreakMode;
//行数,默认是1,设为0后自动换行
@property(nonatomic) NSInteger numberOfLines;
//字体
@property(nonatomic,retain) UIFont *font;
*/
// 不能自动换行,但能增加长度
[self.label sizeToFit];
//使用固定字体
label.font = [UIFont fontWithName:@"Zapfino" size:20];
//系统默认字体
label.font = [UIFont systemFontOfSize:20];
//系统默认字体加黑
label.font = [UIFont boldSystemFontOfSize:20];
//系统默认字体斜体
label.font = [UIFont italicSystemFontOfSize:20];
3.UIButton有关
// btn的类型,除了custom和system,另外4个都自带大小和外观
UIButton *btn = [UIButtonbuttonWithType:UIButtonTypeInfoDark];
// 设置文字垂直和水平的对齐方式
btn.titleLabel.font = [UIFont systemFontOfSize:15];
btn.contentVerticalAlignment = UIControlContentVerticalAlignmentBottom;
btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
// 当btn接收到TouchUpInside这个事件时,会给self发送btnClick这个消息
// 事件-消息机制
[btn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
4.UIImageView有关
// 图片转为NSData
UIImagePNGRepresentation(_ivView.image)
// 图片转为点阵图(防止渲染)
[_ivView.image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
// 显示图片大小为imageView大小
_starsView.contentMode = UIViewContentModeLeft;
_starsView.clipsToBounds = YES;
// 设置图像填充模式,等比例显示(CTRL+6)
iv.contentMode = UIViewContentModeScaleAspectFit;
// 从iPhone4开始,设备的屏幕都是retina屏(2倍,一个坐标位横向纵向显示2个像素点,高清屏,视网膜屏),(6p是3倍的)
// retina屏幕会优先找a@2x.png,找不到就找a.png
iv.image = [UIImage imageNamed:@"a"];
// 图片对象(自带的大小是坐标体系的大小,如果用的是@2x图片,像素大小的宽高除以2就是坐标体系的大小
UIImage *image = [UIImageimageNamed:@"c"];
// 用图片直接创建图片视图,x,y默认是0,宽高默认是图片的大小
UIImageView *secondIv = [[UIImageViewalloc]initWithImage:image];
/** 图片轮播 **/
// 设置图片视图轮播图片的数组,单次动画时间,循环次数(默认无线循环,0次也是无线循环),开始动画
iv.animationImages = tempArr;
iv.animationDuration = tempArr.count/10.0f;
iv.animationRepeatCount = 0;
[iv startAnimating];
/*
//开始动画
- (void)startAnimating;
//手动结束动画
- (void)stopAnimating;
//判断动画状态
- (BOOL)isAnimating;
//图片
@property(nonatomic,retain) UIImage *image;
//动画的图片数组
@property(nonatomic,copy) NSArray *animationImages;
//动画时间(也就是一次完整的动画需要的时间)
@property(nonatomic) NSTimeInterval animationDuration;
//动画循环次数,循环完以后会自动停止
@property(nonatomic) NSInteger animationRepeatCount;
*/
5.UITextFiled有关
// 占位提示符
tf.placeholder = @"请输入QQ号";
// 边框风格
tf.borderStyle = UITextBorderStyleLine;
// 背景图片(和边框风格冲突)
// 如果风格是圆角,那么背景图片失效
// 如果边框风格不是圆角,那么边框风格失效
tf.background = [UIImage imageNamed:@"tf_bg"];
// 当字符串的长度超过tf的长度,可以自动缩小字体
tf.adjustsFontSizeToFitWidth = YES;
// 自动缩小的最小值
tf.minimumFontSize = 30;
// 水平方向的对齐方式(同label)
tf.textAlignment = NSTextAlignmentRight;
// 垂直方向对齐方式(同button)
tf.contentVerticalAlignment = UIControlContentVerticalAlignmentBottom;
// 当字符串的长度超过tf的长度,可以自动缩小字体
tf.adjustsFontSizeToFitWidth = YES;
// 自动缩小的最小值
tf.minimumFontSize = 30;
// 水平方向的对齐方式(同label)
tf.textAlignment = NSTextAlignmentRight;
// 垂直方向对齐方式(同button)
tf.contentVerticalAlignment = UIControlContentVerticalAlignmentBottom;
// 当弹出键盘的时候,清空tf的文字
tf.clearsOnBeginEditing = YES;
// 设置清空按钮出现的方式
tf.clearButtonMode = UITextFieldViewModeWhileEditing;
// 安全输入(暗文输入,专门输入密码使用)
tf.secureTextEntry = YES;
// 键盘类型
tf.keyboardType = UIKeyboardTypeDefault;
// 回车键的外观(和功能没有任何关系)
tf.returnKeyType = UIReturnKeyNext;
// 设置tf的左边的附属view的出现模式(实际工作中一般都是图片imageview)
// 一个view只能成为一个地方的附属view
tf.leftView = view;
tf.leftViewMode = UITextFieldViewModeAlways;
// 键盘view和附属view
tf.inputView = view;
tf.inputAccessoryView = view;
// 收起这个页面的键盘
[self.view endEditing:YES];
// 放弃第一响应
[self.view resignFirstResponder]