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]