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.可以下載源碼的網站
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屏幕會優先找[email protected],找不到就找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]