UIWindow
初始化:
self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
self.window.backgroundColor = [UIColor whiteColor];
MyViewController *vc = [[MyViewController alloc]init];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
UIViewController
- (void)viewDidLoad;創(chuàng)建界面時自動執(zhí)行,將構(gòu)建界面的代碼放在這個方法中即可
- (void)viewWillAppear:(BOOL)animated;界面即將顯示前乱灵,方法自動執(zhí)行
- (void)viewDidAppear:(BOOL)animated;界面顯示完畢塑崖,方法自動執(zhí)行
- (void)viewWillDisappear:(BOOL)animated;界面即將消失前,方法自動執(zhí)行
- (void)viewDidDisappear:(BOOL)animated;界面已經(jīng)消失痛倚,方法自動執(zhí)行
- (void)removeFromSuperview;將某個控件移除
- (void)setNeedsLayout;界面信息發(fā)生改變后重新載入
UILabel標(biāo)簽
屬性:
frame
—>坐標(biāo)大小
text
—>文本內(nèi)容
textAlignment
—>字體對齊方式
textColor
—>字體顏色
font [UIFont systemFontOfSize:40]
—>字體大小
numberOfLines
—>文本的行數(shù)规婆,默認(rèn)為1,設(shè)置為0時蝉稳,行數(shù)可以任意
backgroundColor
—>背景色
font
—>字體
lineBreakMode
—>省略內(nèi)容的方式
//1創(chuàng)建標(biāo)簽的實(shí)例
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(50, 50, 100, 100)];
//2設(shè)置標(biāo)簽的屬性
label.text = @"This is a looooooooooooooooooog word";
label.backgroundColor = [UIColor lightGrayColor];
label.numberOfLines = 0;
label.font = [UIFont systemFontOfSize:22];
//設(shè)置換行后切斷的字符...的位置
label.lineBreakMode = NSLineBreakByTruncatingHead;
//修改文字的顏色
label.textColor = [UIColor redColor];
//3將標(biāo)簽添加到視圖中
[self.view addSubview:label];
UIButton按鈕
selected
—>是否被選中
//1 創(chuàng)建Button
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
//2 設(shè)置按鈕的屬性
button.frame = CGRectMake(50, 50, 200, 100);
button.backgroundColor = [UIColor lightGrayColor];
//設(shè)置按鈕在正常情況下的顯示標(biāo)題
[button setTitle:@"OK" forState:UIControlStateNormal];
//設(shè)置按鈕在高亮狀態(tài)下顯示的標(biāo)題
[button setTitle:@"KO" forState:UIControlStateHighlighted];
//設(shè)置按鈕在正常狀態(tài)下的背景圖
//[button setBackgroundImage:[UIImage imageNamed:@"playing_btn_pause_h@2x.png"] forState:UIControlStateNormal];
//設(shè)置按鈕在正常狀態(tài)下的圖片
[button setImage:[UIImage imageNamed:@"playing_btn_play_h@2x.png"] forState:UIControlStateNormal];
//設(shè)置按鈕文字的對齊
[button setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
//為按鈕添加事件的響應(yīng)
//參數(shù)1 點(diǎn)擊按鈕后觸發(fā)的對象 參數(shù)2 觸發(fā)的對象使用的方法 參數(shù)3 什么事件發(fā)生
[button addTarget:self action:@selector(aaa:) forControlEvents:UIControlEventTouchUpInside];
//3 將按鈕添加到視圖中
[self.view addSubview:button];
UIStepper步進(jìn)控件
核心屬性
value(為Double型抒蚜,與label聯(lián)用時需要用[NSString stringWithFormat:@"%.0f",self.stepper.value];進(jìn)行轉(zhuǎn)換)
重要事件:
valueChanged
第四檢查器中 behavior中autorepeat勾上可以按住按鈕持續(xù)增減
第四檢查器中 behavior中continuous取消勾上,數(shù)值持續(xù)增減過程不顯示
第四檢查器中 behavior中wrap勾上耘戚,到邊界數(shù)值之后會切換到另一個邊界數(shù)值
//當(dāng)stepper的數(shù)值被改變時將新的值顯示到標(biāo)簽上
- (IBAction)stepper:(id)sender {
self.label.text = [NSString stringWithFormat:@"%.0f",self.stepper.value];
}
- (void)viewDidLoad {
[super viewDidLoad];
//設(shè)置初始化設(shè)置
self.stepper.maximumValue = 50;
self.stepper.minimumValue = -50;
self.stepper.value = 10;
self.stepper.stepValue = 5;
//顯示
self.label.text = [NSString stringWithFormat:@"%.0f",self.stepper.value];
}
UISlider滑塊控件
核心屬性:
value(為Double型嗡髓,與label聯(lián)用時需要用[NSString stringWithFormat:@"%.0f",self.stepper.value];進(jìn)行轉(zhuǎn)換)
重要事件:
valueChanged
- (void)setThumbImage:(nullable UIImage *)image forState:(UIControlState)state; 修改按鈕顏色
UISwitch開關(guān)控件
核心屬性:
on(BOOL)
重要事件:
valueChanged
設(shè)置通過帶動畫效果控制switch:[self.switchs setOn:!self.switchs.on animated:YES];
UITextField文本框控件
borderstyle
—>外邊框類型
leftview
—>文本框內(nèi)部左側(cè)視圖
leftViewMode
—>左視圖默認(rèn)不顯示,需要修改
background
—>設(shè)置背景圖片還需要配合BorderStyle無邊框使用
clearbutton
—>清空文本框按鈕
capitalization
—>Words首字母大寫—>Senternces句子首字母大寫—>All Characters所有字母大寫
correction/autocorrectionType
—>自動糾錯
spell checking
—>拼寫檢測
keyboard type
—>鍵盤類型—>phone pad 阿拉伯?dāng)?shù)字
appearance
—>鍵盤顏色
return key
—>設(shè)置return鍵顯示的內(nèi)容
auto-enable return key
—>防止未輸入內(nèi)容就按return鍵
secure text entry
—>設(shè)置密碼模式
如何關(guān)閉鍵盤
關(guān)閉的方法之一:讓文本框放棄第一響應(yīng)者身份即可
成為第一響應(yīng)者:becomeFirstResponder
放棄第一響應(yīng)者:resignFirstResponder
遵守UITextViewDelegate
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString*)text {
if ([text isEqualToString:@"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}
遵守UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
關(guān)閉的方法之二:文本框所在的父視圖結(jié)束編輯狀態(tài)即可(結(jié)束編輯狀態(tài):系統(tǒng)會自動遍歷父視圖下的所有文本框并且將所有文本框都設(shè)置為放棄第一響應(yīng)者身份)
結(jié)束父視圖的編輯狀態(tài):[view endEditing:YES];// 用于-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event方法中
關(guān)閉鍵盤時機(jī):
時機(jī)1:點(diǎn)擊鍵盤右下角按鈕——為文本框連線一個事件收津,且事件種類為Did End On Exit事件
時機(jī)2:點(diǎn)擊界面的空白處——實(shí)現(xiàn)控制器的touchesBegan:withEvent方法饿这,配合[view endEditing:YES];方法
[self.view endEditing:YES];
兩個文本框設(shè)置點(diǎn)擊鍵盤右下角切換:
第一個文本框連線Did End Exit事件,在里面將第二個文本框設(shè)置為第一響應(yīng)者
UIAlertController 警告框及操作表
創(chuàng)建新的警告界面
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"登錄" message:@"輸入用戶名和密碼" preferredStyle:UIAlertControllerStyleAlert];
UIAlertControllerStyleAlert
—>參數(shù)生成一個中間框
UIAlertControllerStyleActionSheet
—>參數(shù)生成一個底部框
底部框不允許生成text輸入框撞秋,只能使用按鈕
創(chuàng)建文本框
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField){
textField.placeholder = @"name";
textField.textColor = [UIColor blueColor];
textField.clearButtonMode = UITextFieldViewModeUnlessEditing ;
textField.borderStyle = UITextBorderStyleRoundedRect;
}];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField){
textField.placeholder = @"password";
textField.textColor = [UIColor blueColor];
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
textField.borderStyle = UITextBorderStyleRoundedRect;
//設(shè)置不可見模式
textField.secureTextEntry = YES;
}];
placeholder
—>是提示輸入
textColor
—>文字顏色
clearButtonMode
—>清除按鈕出現(xiàn)方式:
UITextFieldViewModeNever
—>從不出現(xiàn)
UITextFieldViewModeWhileEditing
—>輸入過程中出現(xiàn)
UITextFieldViewModeUnlessEditing
—>輸入完畢后出現(xiàn)
UITextFieldViewModeAlways
—>總是出現(xiàn)
borderStyle文本框內(nèi)框架格式:
UITextBorderStyleNone
—>無任何格式
UITextBorderStyleLine
—>加邊框底部粗
UITextBorderStyleBezel
—>四周加細(xì)邊框
UITextBorderStyleRoundedRect
—>淺淡邊框
創(chuàng)建新的按鈕
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
NSArray *textfields = alert.textFields;
UITextField *namefield = textfields[0];
UITextField *passwordfield = textfields[1];
NSLog(@"%@:%@",namefield.text, passwordfield.text);
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Calcel" style:UIAlertActionStyleCancel handler:nil]];
//推出顯示 參數(shù)1:要顯示的控制器 參數(shù)2:是否使用動畫 參數(shù)3:推出結(jié)束后執(zhí)行的行動
[self presentViewController:alert animated:YES completion:nil];
UIAlertActionStyleDefault
—>參數(shù)生成一個默認(rèn)的按鈕格式长捧,設(shè)置為此模式時在底部框模式中會自動合并附近按鈕
UIAlertActionStyleCancel
—>參數(shù)生成一個退出按鈕,在中間框模式中默認(rèn)會在最左邊生成吻贿,設(shè)置為此模式時會在底部框模式中獨(dú)立分開
UIAlertActionStyleDestructive
—>參數(shù)生成一個有可能改變或數(shù)據(jù)串结,設(shè)置為此模式時在底部框模式中會自動合并附近按鈕
通過block方式獲得文本框中輸入的內(nèi)容,輸入的內(nèi)容會被放在系統(tǒng)生成的textFields數(shù)組中舅列,使用一個數(shù)組來接收其數(shù)據(jù)奉芦,第一個文本框中的內(nèi)容會放在數(shù)組[0]中,使用UITextField類型接收剧蹂,以此類推声功,使用時通過接收名.text調(diào)用其內(nèi)容
lazy loading懶加載(重寫getter方法實(shí)現(xiàn)晚加載)
-(NSArray *)allStudent{
if (!_allStudent) {
_allStudent = [NSArray alloc];
}
return _allStudent;
}
多界面切換
方式一 present-dismiss方式推出返回
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^ __nullable)(void))completion NS_AVAILABLE_IOS(5_0);
- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^ __nullable)(void))completion NS_AVAILABLE_IOS(5_0);
方式二 使用UINavigationController
//1 創(chuàng)建bvc的實(shí)例
BViewController * bvc = [[BViewController alloc]initWithNibName:@"BViewController" bundle:nil];
//2 由正在管理著avc的那個導(dǎo)航來負(fù)責(zé)推出bvc
[self.navigationController pushViewController:bvc animated:YES];
//返回
[self.navigationController popViewControllerAnimated:YES];
多VC之間的傳值
正向傳值
step1:為B公開一個屬性,用于接收要傳入的數(shù)值
//通過bvc這個引用宠叼,給要推出的控制器公開的那個屬性賦值
bvc.msg = self.textField.text ;
step2:A創(chuàng)建完B的實(shí)例之后先巴,在推出B之前,為B公開這個屬性賦值
step3:在B中冒冬,選擇合適的時機(jī)伸蚯,顯示傳入的數(shù)據(jù)
//顯示接收的信息
self.label.text = self.msg;
反向傳值(回調(diào)、回傳)
方法一:
直接在B中添加了AViewController類型的屬性简烤,然后B在dismiss之前給AViewController發(fā)消息
準(zhǔn)備:
1 AViewController為了接收回傳的值剂邮,公開一個屬性
2 BViewController為了存儲推出它的那個avc,公開一個屬性横侦,類型為AviewController挥萌。
步驟:
step1:avc在推出B之前绰姻,將自己的引用賦給B公開的backReference屬性。
step2:B在dismiss之前引瀑,通過存儲的backReference引用A狂芋,返回的控制器空開的backString的賦值。
step3:在avc中憨栽,在viewWillAppear中完成返回的文本顯示帜矾。
方法二:
直接在B中添加了id<xxxDelegate>類型的屬性昼接,然后B在dismiss之前給delegate發(fā)消息送火,方法名就是在協(xié)議中定義的指定的方法。
此種通過定義協(xié)議贫堰,規(guī)范另一個對象中的方法掸宛,并且給這個對象發(fā)消息的這種模式叫做代理模式灭衷,作用就是完成兩個對象,一個給另一個主動發(fā)消息的過程旁涤。
主動方(委托方翔曲,發(fā)送消息者)
1> 定義協(xié)議
2> 增加delegate屬性
3> 合適的時機(jī)給代理方發(fā)消息
//定義一個登陸的協(xié)議
@protocol UMLoginProtocol <NSObject>
- (void)loginSuccess;
- (void)loginFaild;
- (void)loginNetError;
@end
//代理屬性***注意weak,防止循環(huán)引用***
@property (nonatomic, weak) id<UMLoginProtocol>delegate;
合適的時候使用 [self loginSuccess];等方法
被動方(代理方劈愚,接收消息者)
1> 遵守協(xié)議
2> 實(shí)現(xiàn)方法
3> 將自己設(shè)置為代理方
@interface UMLoginViewController ()<UMLoginProtocol>
實(shí)現(xiàn)loginSuccess等方法
//設(shè)置自己為代理
[UMXmppTool sharedUMXmppTool].delegate = self;
UINavigationController導(dǎo)航控制器
配置導(dǎo)航欄(NavigationBar)
高度:
—>算上狀態(tài)欄(StatusBar 本來20個點(diǎn))一共64個點(diǎn)
設(shè)置StatusBar顏色
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}
內(nèi)容:
—>通過navigationItem屬性完成配置
左
—>leftBarButtonItem/s
中
—>title/titleView
右
—>rightBarButtonItem/s
topViewController
->附帶的view
左和右都是類似于可點(diǎn)擊的按鈕瞳遍,是UIBarButtonItem類型
取消系統(tǒng)默認(rèn)的藍(lán)色渲染
UIImage * leftImage = [[UIImage imageNamed:@"icon29.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
導(dǎo)航欄背景色
self.navigationController.navigationBar.barTintColor = [UIColor blackColor];
導(dǎo)航欄風(fēng)格改為深色系
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
左右按鈕的渲染色
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
配置工具欄(ToolBar)
位于導(dǎo)航控制器的底部
默認(rèn)隱藏,通過設(shè)置 self.navigationController.toolbarHidden = NO;即可顯示
toolBar中可包含的就是UIBarButtonItem類型的可點(diǎn)擊的按鈕菌羽,通過控制器的toolBarItems屬性設(shè)置工具條中包含的按鈕
高度:44個點(diǎn)
創(chuàng)建固定的填充按鈕
UIBarButtonItem * fixItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
修改固定按鈕長度
fixItem.width = 30;
創(chuàng)建可變的填充按鈕
UIBarButtonItem * flexibleItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
使用可填充按鈕
self.toolbarItems = @[fixItem,rewindItem,flexibleItem,playItem,flexibleItem,fastItem,fixItem];
設(shè)置在推出界面時隱藏底部各種
Bar vc.hidesBottomBarWhenPushed = YES;
常用設(shè)置的作用于范圍
與內(nèi)容有關(guān)的:只在當(dāng)前vc中生效
navigationItem的左中右
toolbarItems
與控制器bar的顯示隱藏有關(guān)的:在多個vc中都有效
navigationController.navigationBarHidden
navigationController.toolbarHidden
多導(dǎo)航控制器之間的切換
在A中推出B的時候掠械,B創(chuàng)建導(dǎo)航控制器,然后A推出B的導(dǎo)航控制器
BViewController * bvc = [[BViewController alloc]init];
//推出BViewController注祖,但BViewController也得有它的導(dǎo)航
UINavigationController * navi = [[UINavigationController alloc]initWithRootViewController:bvc];
//推出navi
[self.navigationController presentViewController:navi animated:YES completion:nil]
UIImageView圖片視圖
image
—>(類型UIImage)圖片
contentMode
—>顯示模式/居中/左/右
userInteractionEnabled
—>用戶交互屬性
NSData * __nullable UIImagePNGRepresentation(UIImage * __nonnull image);
—>將UIImage轉(zhuǎn)換成NSData用于上傳等
UIScrollView 滾動視圖
核心屬性:
frame:
—>視圖的可見區(qū)間的大小
contentSize:
—>設(shè)置內(nèi)容的大小
contentOffset:
—>記錄可見區(qū)域的左頂點(diǎn)在全部內(nèi)容區(qū)域中離內(nèi)容左頂點(diǎn)的偏移量
contentInset:
—>設(shè)置內(nèi)邊距
bounces:
—>到達(dá)邊界是否回彈
pagingEnabled:
—>一次滾動一個屏幕
automaticallyAdjustsScrollViewInsets:
—>關(guān)閉因?yàn)閷?dǎo)航欄下移的64個點(diǎn)
//創(chuàng)建一張尺寸較大的圖片視圖
//使用initWithImage方法在創(chuàng)建iv的同時就指定圖片的話猾蒂,則不設(shè)置frame,那么圖片有多大iv就有多大
UIImageView * iv = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"32.jpg"]];
//創(chuàng)建滾動視圖
UIScrollView * sv = [[UIScrollView alloc]init];
//sv.frame = CGRectMake(50, 100, 250, 400);
//設(shè)置等屏幕大小
sv.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
//設(shè)置邊的內(nèi)邊距(可以用于鍵盤彈出的時候用于縮起內(nèi)容)
//sv.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0);
//當(dāng)使用滾動視圖并搭配導(dǎo)航控制器時是晨,系統(tǒng)為了防止延伸到導(dǎo)航欄下方的滾動視圖在開始時肚菠,被遮蓋上,所以系統(tǒng)檢測到有導(dǎo)航時罩缴,就會把滾動視圖的內(nèi)容向下錯64個點(diǎn)蚊逢,有時不想使用該功能的話,則有兩種方法取消掉該效果
//方法一:關(guān)閉控制器的該功能箫章,不讓控制器自動調(diào)整滾動視圖的內(nèi)邊距
self.automaticallyAdjustsScrollViewInsets = NO;
//方法二:我們自己修改滾動視圖的內(nèi)邊距烙荷,向上把那64個點(diǎn)移回去
//設(shè)置滾動邊界
sv.contentSize = iv.frame.size;
[sv addSubview:iv];
//添加滾動視圖到控制器上
[self.view addSubview:sv];
控制器響應(yīng)滾動視圖與用戶的交互
step1:設(shè)置滾動視圖的代理為當(dāng)前控制器
step2:讓控制器遵守UIScrollViewDelegate協(xié)議
step3:根據(jù)需求實(shí)現(xiàn)協(xié)議中的方法,用于響應(yīng)滾動視圖與用戶的交互
UIPageControl頁數(shù)的提醒(小圓點(diǎn))
核心屬性:
frame:
—>坐標(biāo)大小
numberOfPages:
—>圓點(diǎn)的個數(shù)
currentPage:
—>當(dāng)前被選中的是第幾個圓點(diǎn)(下表從0開始算起)
pageIndicatorTintColor:
—>圓點(diǎn)的顏色
currentPageIndicatorTintColor:
—>被選中的圓點(diǎn)的顏色
userInterAction:
—>是否與用戶交互
UIPageControl * pc = [[UIPageControl alloc]init];
self.pc = pc;
pc.frame = CGRectMake(0, self.view.bounds.size.height -60, self.view.bounds.size.width, 40);
pc.numberOfPages = self.welcomeName.count;
pc.pageIndicatorTintColor = [UIColor whiteColor];
pc.currentPageIndicatorTintColor = [UIColor blueColor];
pc.userInteractionEnabled = NO;
[self.view addSubview:pc];
#pragma mark - UIScrollViewDelegate協(xié)議
-(void) scrollViewDidScroll:(UIScrollView *)scrollView{
CGPoint offset = scrollView.contentOffset;
self.pc.currentPage = round(offset.x/scrollView.bounds.size.width);
}
UITableView表視圖
表格的樣式
行之間沒有間距檬寂,普通樣式Plain樣式
可以將行分組(區(qū))终抽,分組樣式Group樣式
heightForRowAtIndexPath
—>設(shè)置行高
separator
—>下劃線
selection
—>選中陰影
表格的組成
tableView
+tableHeaderView
+section分區(qū)
+sectionHeader分區(qū)頭
+UITableViewCell(單元格/行)
+sectionFooter分區(qū)尾
+tableFooterView
如何使用UITableView
創(chuàng)建實(shí)例
-
設(shè)置frame
UITableView * tableView = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
添加到控制器的view中
[self.view addSubview:tableView];
- 設(shè)置表視圖的數(shù)據(jù)源代理(dataSource)
tableView.dataSource = self;tc
- 設(shè)置表視圖的delegate代理
tableView.delegate = self;
- 當(dāng)前控制器遵守UITableViewDataSource和UITableViewDelegate協(xié)議
- 三問一答
//1 有幾個分區(qū)
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
//2 每個分區(qū)有幾行(必答)
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 100;
}
//3 每行什么樣(必答)
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell * cell = [[UITableViewCell alloc]init];
cell.textLabel.text = @"HelloWorld";
return cell;
}
//一答:點(diǎn)擊某行后如何響應(yīng)
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
通過Cell內(nèi)的按鈕點(diǎn)擊等獲得Cell的indexPath
- (IBAction)cellHeadImageButtonClick:(UIButton *)sender {
UIResponder *responder = sender;
long indexPath = 0;
while ((responder = [responder nextResponder])){
if ([responder isKindOfClass: [UITableViewCell class]]) {
indexPath = [self.tableView indexPathForCell:(UITableViewCell *)responder].row;
}
}
}
通過Cell內(nèi)手勢獲得對應(yīng)的Cell的indexPath
- (void)imLongPress:(NSNotification *)noti {
[self.msgTextField resignFirstResponder];
UIGestureRecognizer * gr = noti.userInfo[@"gr"];
CGPoint tmpPointTouch = [gr locationInView:self.tableView];
if (gr.state == UIGestureRecognizerStateBegan) {
//獲取行數(shù)
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:tmpPointTouch];
if (indexPath == nil) {
NSLog(@"not tableView");
}else{
NSInteger focusRow = [indexPath row];
NSLog(@"%ld",(long)focusRow);
}
}
單元格重用
方法一:先取,沒有,自己新建
//先嘗試著從tableView中取昼伴,看有沒有回收了的cell
static NSString * identifier = @"MyCell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];
//如果沒有取到可重用的單元格匾旭,則新建
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MyCell"];
}
方法二:先取,沒有亩码,系統(tǒng)新建
step1:在viewDidLoad中,使用tableView的registerClass方法野瘦,提前注冊系統(tǒng)幫我們創(chuàng)建的類型是什么樣描沟。
spet2:在回答第三問時,使用帶有兩個參數(shù)的dequeueReusableCell即可
注意:寫完dequeue之后鞭光,再也不用判斷了吏廉,一定能返回一個cell實(shí)例,因?yàn)榫退闳〔坏娇芍赜枚栊恚到y(tǒng)在dequeue方法中席覆,會幫我們自動創(chuàng)建。
在單元格內(nèi)添加了控件汹买,重用表格內(nèi)容可能會覆蓋原有內(nèi)容佩伤,在使用之前應(yīng)該先進(jìn)行判斷
UILabel * label = [cell.contentView viewWithTag:1];
if (label == nil) {
label =[[UILabel alloc]init];
label.frame = CGRectMake(0, 0, cell.bounds.size.width, cell.bounds.size.height);
label.font = [UIFont italicSystemFontOfSize:35];
label.textColor = [UIColor redColor];
label.textAlignment = NSTextAlignmentCenter;
//為lebel添加一個tag值,做標(biāo)記
label.tag = 1;
[cell.contentView addSubview:label];
}
UITableViewCell的組成
contentView內(nèi)容視圖
1>系統(tǒng)版
四種樣式:
Default:imageView+textLabel (基本)
Value1:詳情在右側(cè)(右對齊)
Value2:textLabel+detailTextLabel(左對齊)
SubTitle:詳情在下
2>自定義
step1:創(chuàng)建顯示內(nèi)容的控件實(shí)例
step2:將這些控件以子視圖的形式晦毙,添加到cell.contentView中即可
accessoryView輔助視圖
1>系統(tǒng)版
通過cell的accessoryType屬性設(shè)置
四種類型:
checkmark:
->勾號
disclosureIndicator:
->大于號
detailButton:
->圓圈i
detailDisclosureButton:
->圓圈i+大于號
//有圓圈i時生巡,點(diǎn)擊i以外的響應(yīng)
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
//有圓圈i時,點(diǎn)擊i時的響應(yīng)
-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
2>自定義
step1:創(chuàng)建控件實(shí)例
step2:將實(shí)例賦值給cell.accessoryView即可
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
if (indexPath.row == 1) {
UISwitch * mySwitch = [[UISwitch alloc]init];
mySwitch.on = self.myChoose;
[mySwitch addTarget:self action:@selector(clickSwitch:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = mySwitch;
}
else{
//清除非第二行的復(fù)用窗口
cell.accessoryView = nil;
}
注意:contentView由系統(tǒng)創(chuàng)建實(shí)例见妒,我們直接拿來使用孤荣,添加子視圖即可,但accessoryView系統(tǒng)沒有創(chuàng)建實(shí)例须揣,只能先創(chuàng)建好UIView或其之類的實(shí)例盐股,然后賦給該屬性。
分區(qū)頭的特殊效果:
step1:tableView的style時plain樣式
step2:實(shí)現(xiàn)titleForheaderInSection方法設(shè)置分區(qū)頭
產(chǎn)生效果:分區(qū)頭不會滾動出超出屏幕耻卡,會懸停在屏幕的頂部疯汁,
表格的刷新
方式一:全部刷新reloadData
[self.tableView reloadData];
方式二:只更新某一個部分,insertRowsAtIndexPath
NSIndexPath * newIndexPath = [NSIndexPath indexPathForRow:self.allCitys.count-1 inSection:0];
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
表格行高設(shè)置
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.section == 0) {
return 100;
}
else{
return 44;
}
}
表頭表尾高度設(shè)置
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 10;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return 10;
}
自定義單元格
方式一:
在回答第三問時卵酪,自己創(chuàng)建顯示內(nèi)容的控件涛目,添加到contentView中,相當(dāng)于單元格的設(shè)計工作是在第三問中完成的凛澎。
弊端:
1》給子視圖加tag標(biāo)記霹肝,然后重用時判斷
2》如果一旦cell需要改變結(jié)構(gòu),那么就需要修改第三問的代碼
方式二:
step1:編寫一個類塑煎,繼承自UITableViewCell
step2:通過設(shè)計該類沫换,將單元格的樣式重新進(jìn)行設(shè)置
step3:回答第三問時,創(chuàng)建自定義的cell類的實(shí)例即可
表格的編輯模式
使得表格進(jìn)入編輯模式(出現(xiàn)編輯的按鈕):設(shè)置tableView的editing屬性為YES,就會開啟編輯模式
1》刪除和增加功能——兩問一答
問1:當(dāng)前行是否可以編輯
問2:當(dāng)前行的編輯樣式時紅色刪除還是綠色添加
答1:點(diǎn)擊了編輯按鈕后讯赏,如何響應(yīng)
#pragma mark - 表格的編輯功能
//問1:當(dāng)前行是否可以編輯
//此方法默認(rèn)返回YES;
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == 0) {
return NO;
}
else{
return YES;
}
}
//問2:當(dāng)前行是什么編輯樣式
//此方法默認(rèn)為UITableViewCellEditingStyleDelete
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == (self.allCitys.count-1)) {
return UITableViewCellEditingStyleInsert;
}
else{
return UITableViewCellEditingStyleDelete;
}
}
//答1:提交編輯動作后垮兑,如何響應(yīng)
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete) {
//刪除動作
//1 先改數(shù)據(jù)模型
[self.allCitys removeObjectAtIndex:indexPath.row];
//2 再刷新表格
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
else{
//增加動作
City * newCity = [[City alloc]init];
newCity.name = @"Test";
newCity.population = 1000;
//先改模型
[self.allCitys addObject:newCity];
//再刷新
NSIndexPath * newIndexPath = [NSIndexPath indexPathForRow:self.allCitys.count-1 inSection:0];
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic ];
}
}
2》行的移動功能——一問一答
問1:當(dāng)前行是否可以移動
答1:真得移動后,如何響應(yīng)
#pragma mark - 移動行
//問1:該行是否可以移動
-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
//答1:移動后做什么
-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
//按照舊的位置找到模型漱挎,找到模型
City * city = self.allCitys[sourceIndexPath.row];
//在數(shù)組中移除該元素
[self.allCitys removeObjectAtIndex:sourceIndexPath.row];
//按照新的位置插入回數(shù)組
[self.allCitys insertObject:city atIndex:destinationIndexPath.row];
}
獲得自定義cell中控件點(diǎn)擊對應(yīng)的indexPath
控件點(diǎn)擊事件
- (IBAction)recordButtonClick:(UIButton *)sender {
NSIndexPath * indexPath = [self.tableView indexPathForCell:(UITableViewCell *)sender.superview];
}
手勢點(diǎn)擊
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//重用機(jī)制
static NSString * identifier = @"Cell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
//設(shè)置cell
UILongPressGestureRecognizer * longGr = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longP:)];
[cell addGestureRecognizer:longGr];
return cell;
}
- (void)longP:(UILongPressGestureRecognizer *)gr {
CGPoint tmpPointTouch = [gr locationInView:self.table];
if (gr.state == UIGestureRecognizerStateBegan) {
//獲取行數(shù)
NSIndexPath *indexPath = [self.table indexPathForRowAtPoint:tmpPointTouch];
NSLog(@"%ld",(long)indexPath.row);
}
}
下拉刷新
步驟:
step1:創(chuàng)建UIRefreshControl的實(shí)例
step2:將實(shí)例賦給表視圖控制器的refreshControl屬性
step3:為RefreshControl控件添加valueChanged事件的監(jiān)聽
step4:檢測到valueChanged事件后系枪,判斷是否正在刷新,則執(zhí)行數(shù)據(jù)加載操作磕谅,等加載結(jié)束后私爷,修改RefreshControl為結(jié)束刷新即可
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"MyCell"];
//1 創(chuàng)建UIRefreshControl控件實(shí)例
UIRefreshControl * rc = [[UIRefreshControl alloc]init];
//2 將控件賦給控制器的refreshControl屬性
self.refreshControl = rc;
//3 添加valueChanged事件的監(jiān)聽
[rc addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];
}
-(void) refresh:(UIRefreshControl *)sender{
//判斷控件是否處于轉(zhuǎn)圈的狀態(tài)
//如果處于狀態(tài),則說明用戶有了下拉動作
//發(fā)網(wǎng)絡(luò)請求膊夹,傳輸新的數(shù)據(jù)
//等傳輸結(jié)束后衬浑,設(shè)置刷新控件為結(jié)束刷新,停止旋轉(zhuǎn)
if ([sender isRefreshing]) {
//發(fā)網(wǎng)絡(luò)請求
//模擬網(wǎng)絡(luò)請求3秒后放刨,得到了“測試”數(shù)據(jù)
//在refreshOver方法中工秩,將返回的“測試”數(shù)據(jù)保存到數(shù)據(jù)模型中,并更新界面
[self performSelector:@selector(refreshOver:) withObject:@"測試" afterDelay:3];
}
}
-(void)refreshOver:(NSString *)result{
//將數(shù)據(jù)保存到模型中
[self.allNames insertObject:result atIndex:0];
//更新界面
NSIndexPath * new = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:@[new] withRowAnimation:UITableViewRowAnimationTop];
//修改RefreshControl控件进统,停止旋轉(zhuǎn)
[self.refreshControl endRefreshing];
}
UISearchController搜索框
遵循UISearchResultsUpdating,UISearchBarDelegate代理
//實(shí)現(xiàn)searchBarDelegate協(xié)議方法
-(void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope{
[self updateSearchResultsForSearchController:self.searchController];
}
//實(shí)現(xiàn)UISearchResultsupdating協(xié)議方法
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController{
//獲得用戶輸入的搜索文本
NSString * searchText = searchController.searchBar.text;
//獲取用戶選擇的類別
NSInteger * selectedButtonIndex = searchController.searchBar.selectedScopeButtonIndex;
//聲明一個用于保存匹配比對后助币,數(shù)據(jù)一致的商品數(shù)組
NSMutableArray * resultArray = [NSMutableArray array];
//遍歷所有商品,一次比對商品名種時候包含輸入的文本及類別是否一致
for (Product * p in self.allProducts) {
NSRange range = [p.name rangeOfString:searchText];
//range.length 匹配上的長度
//range.location 匹配上的位置
//@"abcdef"——>@"def"
//length:3 location:3
if (range.length > 0 && p.type == selectedButtonIndex) {
//比對成功 記錄到resultArray中
[resultArray addObject:p];
}
}
//將要顯示的數(shù)據(jù)結(jié)果給showResultVC傳過去
self.showResultVC.resultData = resultArray;
//更新表視圖顯示
[self.showResultVC.tableView reloadData];
}
UICollectionViewController
創(chuàng)建
//創(chuàng)建布局屬性
UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc]init];
//水平布局
layout.scrollDirection=UICollectionViewScrollDirectionHorizontal;
//設(shè)置每個表情按鈕的大小為30*30
layout.itemSize=CGSizeMake(30, 30);
//計算每個分區(qū)的左右邊距
float xOffset = (SCREENWIDTH-7*30)/8;
//設(shè)置分區(qū)的內(nèi)容偏移
layout.sectionInset=UIEdgeInsetsMake(10, xOffset, 10, xOffset);
//設(shè)置行列間距
layout.minimumLineSpacing = (SCREENWIDTH - 7*30)/8;
layout.minimumInteritemSpacing=5;
UICollectionView * collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 160) collectionViewLayout:layout];
//打開分頁效果
collectionView.pagingEnabled = YES;
//設(shè)置代理屬性
collectionView.delegate= self;
collectionView.dataSource=self;
//注冊Cell
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"biaoqing"];
代理方法
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return (self.dataArray.count/28)+(self.dataArray.count%28==0?0:1);
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return 28;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"biaoqing" forIndexPath:indexPath];
for (int i=(int)cell.contentView.subviews.count; i>0; i--) {
[cell.contentView.subviews[i-1] removeFromSuperview];
}
UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 30, 30)];
label.font = [UIFont systemFontOfSize:25];
if (indexPath.row+indexPath.section*28 < self.dataArray.count) {
label.text =self.dataArray[indexPath.row+indexPath.section*28] ;
} else {
label.text = @"";
}
[cell.contentView addSubview:label];
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row+indexPath.section*28 < self.dataArray.count) {
NSString * str = self.dataArray[indexPath.section*28+indexPath.row];
}
}
UITableBarController
創(chuàng)建
AViewController * avc = [[AViewController alloc]init];
avc.tabBarItem.title = @"AVC";
UINavigationController * navi1 = [[UINavigationController alloc]initWithRootViewController:avc];
BViewController * bvc = [[BViewController alloc]init];
bvc.tabBarItem.title = @"BVC";
UINavigationController * navi2 = [[UINavigationController alloc]initWithRootViewController:bvc];
UITabBarController * tb = [[UITabBarController alloc]init];
//改變tabBar默認(rèn)渲染顏色
tb.tabBar.tintColor = [UIColor blackColor];
// tb.viewControllers = @[navi1,navi2];
CViewController * cvc = [[CViewController alloc]init];
cvc.tabBarItem.title = @"CVC";
UINavigationController * navi3 = [[UINavigationController alloc]initWithRootViewController:cvc];
[tb addChildViewController:navi1];
[tb addChildViewController:navi2];
[tb addChildViewController:navi3];
tintColor
特點(diǎn):不分視圖種類螟碎,只分父子關(guān)系奠支。
設(shè)置父視圖的tintColor,于是在該父視圖中得所有子視圖只要沒有單獨(dú)設(shè)置過tintColor抚芦,則都將使用父視圖的tintColor倍谜,但是有些視圖會有自己特定的tintColor,如導(dǎo)航條自己特有的barTintColor叉抡。這種特有的屬性是不受標(biāo)準(zhǔn)的tintColor影響尔崔。
self.view.tintColor = [UIColor blackColor];
UIAppearance
特點(diǎn):不分父子關(guān)系,只分種類
只針對程序中的某一類型的控件做統(tǒng)一風(fēng)格的設(shè)置褥民,如:希望整個應(yīng)用中的所有按鈕背景圖都是某一顏色季春。
使用:
調(diào)用指定類型的appearance方法,返回這種類型的對象實(shí)例消返,針對這個實(shí)例做樣式設(shè)定载弄,系統(tǒng)會自動將該樣式復(fù)制給應(yīng)用中所有與此對象一致的對象身上,在AppDelegate.m中設(shè)置按鈕背景
[[UIButton appearance] setBackgroundImage:[UIImage imageNamed:@"delete_btn"] forState:UIControlStateNormal];
自定義導(dǎo)航欄和TabBar
自定義導(dǎo)航欄
思路:
將導(dǎo)航欄的外觀設(shè)置記錄到一個獨(dú)立的類中撵颊,需要使用該設(shè)置的導(dǎo)航控制器與這個類綁定即可完成外觀的變化宇攻,而無需在故事版中針對每個導(dǎo)航欄重復(fù)的做同樣的設(shè)置
繼承自UINavigationController,在initital的類方法中倡勇,通過appearance將導(dǎo)航欄的外觀進(jìn)行了設(shè)置
/*第一次使用這個類或者這個類的的子類的時候調(diào)用*/
+(void)initialize
{
//使用Appearance對導(dǎo)航欄統(tǒng)一外觀設(shè)置
UINavigationBar *bar = [UINavigationBar appearance];
// 設(shè)置導(dǎo)航條的背景色
//[bar setBarTintColor:[UIColor redColor]];
//1.設(shè)置背景圖
[bar setBackgroundImage:[UIImage imageNamed:@"navibg"] forBarMetrics:UIBarMetricsDefault];
//2.設(shè)置導(dǎo)航欄的樣式(設(shè)置為black色系時逞刷,影響狀態(tài)欄為白色字)
[bar setBarStyle:UIBarStyleBlack];
//3.設(shè)置左右按鈕的渲染顏色
[bar setTintColor:[UIColor whiteColor]];
//4.設(shè)置導(dǎo)航欄中標(biāo)題文字的豎直方向位置
//[bar setTitleVerticalPositionAdjustment:-20 forBarMetrics:UIBarMetricsDefault];
//5.設(shè)置導(dǎo)航欄中標(biāo)題文字的樣式
NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
//添加文字顏色的設(shè)置
attributes[NSForegroundColorAttributeName] = [UIColor yellowColor];
attributes[NSFontAttributeName] = [UIFont systemFontOfSize:20];
[bar setTitleTextAttributes:attributes];
//6.設(shè)置返回按鈕的箭頭
[bar setBackIndicatorImage:[UIImage imageNamed:@"back_btn"]];
[bar setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"back_btn"]];
}
自定義TabBar
繼承自UITabBarController,做一個類,繼承自UITabBarButton夸浅,將視圖的修改寫在這個類中仑最,再使用kvc的方法將自定義的TabBar對象替換掉UITabBarController中原有的tabbar。
思路:
step1:建立一個類帆喇,繼承自UITabBarController警医,在tabBar的viewDidLoad中,將外觀的設(shè)置完成
step2:建立一個類坯钦,繼承自UITabBar
step3:在這個類的initWithFrame方法中预皇,手動創(chuàng)建一個需要顯示異型圖片還能響應(yīng)點(diǎn)擊動作的按鈕,并以子視圖的形式添加到TabBar中
step4:重寫layoutSubView方法葫笼,在此方法中深啤,將TabBar原有的按鈕和新增的異形按鈕手動重新布局拗馒,調(diào)整他們的顯示位置
step5:創(chuàng)建此自定義的TabBar的實(shí)例路星,使用KVC的方法將自定義的bar,替換掉原有TabBarController中的bar
step6:使用代理的方法時诱桂,為新添加的按鈕添加點(diǎn)擊后的響應(yīng)動作
**
繼承自UIView的子類洋丐,在創(chuàng)建實(shí)例時,系統(tǒng)會都自動調(diào)用
initwithFrame方法挥等,就算是使用時調(diào)用的是init方法友绝,
系統(tǒng)最后也是調(diào)用initWithFrame,只不過參數(shù)frame為0
**
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//創(chuàng)建一個UIButton的實(shí)例
UIButton *centerButton = [[UIButton alloc]init];
[centerButton setImage:[UIImage imageNamed:@"sports"] forState:UIControlStateNormal];
centerButton.frame = CGRectMake(0, 0, centerButton.currentImage.size.width, centerButton.currentImage.size.height);
//以子視圖的形式添加到TabBar中
[self addSubview:centerButton];
self.centerButton = centerButton;
}
return self;
}
**
UIView類中定義的一個方法
當(dāng)視圖的frame發(fā)生變化時肝劲,系統(tǒng)會自動調(diào)用該方法
對于該視圖內(nèi)部的子視圖如何布局迁客,就寫在
這個方法中
使用此方法時一定要調(diào)用super,先保證父類中原本做的
布局操作先實(shí)現(xiàn)辞槐,然后我們再寫代碼調(diào)整各個子視圖的位置
**
- (void)layoutSubviews
{
[super layoutSubviews];
//1.設(shè)置中間按鈕的位置
self.centerButton.center = CGPointMake(self.bounds.size.width*0.5, self.bounds.size.height*0.5-12);
//計算每個UITabBarButton的寬
CGFloat tabbarButtonW = self.bounds.size.width/5;
CGFloat buttonIndex = 0;
//2.設(shè)置系統(tǒng)根據(jù)子vc創(chuàng)建的4個UITabBarButton的位置
for (UIView *child in self.subviews) {
//根據(jù)字符串做類名掷漱,找到該類型的類型信息
Class class = NSClassFromString(@"UITabBarButton");
//判斷當(dāng)前遍歷到的子視圖是否是class類型
if ([child isKindOfClass:class]) {
//先拿出button原有的frame
CGRect frame = child.frame;
//改子視圖的寬
frame.size.width = tabbarButtonW;
//改子視圖的x
frame.origin.x = buttonIndex*tabbarButtonW;
//再把改完的frame賦會給button
child.frame = frame;
buttonIndex++;
if (buttonIndex==2) {
buttonIndex++;
}
}
}
}