1 @interface ViewController : UIViewController 2 3 @property(nonatomic, weak)IBOutlet UILabel *lable; 4 5 @end 6 7 8 9 @interface ViewController () 10 11 @end 12 13 @implementation ViewController 14 15 /** 16 紅色按鈕 17 */ 18 - (IBAction)redBtnClick 19 { 20 // -[ViewController redBtnClick] 21 NSLog(@"%s", __func__); 22 // 拿到UILabel對象, 修改對象的屬性, 讓label對象變爲紅色 23 self.lable.textColor = [UIColor redColor]; 24 self.lable.text = @"我是紅色文字"; 25 self.lable.backgroundColor = [UIColor purpleColor]; 26 self.lable.font = [UIFont systemFontOfSize:30]; 27 self.lable.textAlignment = NSTextAlignmentCenter; 28 } 29 /** 30 綠色按鈕 31 */ 32 - (IBAction)greenBtnClick 33 { 34 NSLog(@"%s", __func__); 35 self.lable.textColor = [UIColor greenColor]; 36 } 37 /** 38 藍色按鈕 39 */ 40 - (IBAction)blueBtnClick 41 { 42 NSLog(@"%s", __func__); 43 self.lable.textColor = [UIColor blueColor]; 44 } 45 @end
1.什麼是控制器:html
任何繼承於UIViewController的類,都稱之爲控制器java
2.控制器的做用:ios
管理UI界面(負責管理UI界面的建立和一些事件的處理)git
3.注意點:github
UI界面是能夠和它與之對應的控制器進行連線的,咱們能夠經過連線的方式,讓UI界面上的元素和控制器中的代碼產生必定的關係;默認狀況下,UI界面中的元素是不能和方法進行關聯的,要想關聯UI界面中的元素必須將方法的返回值修改成IBAction。web
- (IBAction)redBtnClick;編程
1. IBActionapi
1.1 從返回值角度上看,做用至關於void數組
1.2 只有返回值聲明爲IBAction的方法,才能跟storyboard中的控件進行連線
1.3 IBAction只能加在方法上, 不能加在屬性上
2. IBAction幾種連線方式
從"控制器"往"Storyboard"連線
從"Storyboard"往"控制器"連線
直接在"Storyboard"中往"Storyboard"上的界面頂部連線
直接在"Storyboard"中往"Storyboard"上的工具條連線
不用先定義方法, 直接從"Storyboard"往"控制器"連線(經常使用)
3.IBAction連線的注意點:
3.1 在Storyboard中拷貝元素的時候須要注意
拷貝的同時會將之前的連線一塊兒拷貝
一個方法能夠不少個控件關聯
一個控件能夠和不少方法進行連線,在開發中, 通常狀況下不會這樣寫
3.2 若是將按鈕關聯的方法刪除, 運行以後會報一個經典錯誤
reason: '-[ViewController redBtnClick]: unrecognized selector sent to instance 0x7fb4aa618e50'
3.3 IBAction只能做爲方法的返回值
@property(nonatomic, weak)IBOutlet UILabel *lable;
1. IBOutlet
1.1 只有聲明爲IBOutlet的屬性,才能跟storyboard中的控件進行連線
1.2 屬性要想可以連線必須在數據類型前面加上IBOutlet
2. IBOutlet的幾種連線方式
從"控制器"往"Storyboard"連線
從"Storyboard"往"控制器"連線
直接在"Storyboard"中往"Storyboard"上的界面頂部連線
直接在"Storyboard"中往"Storyboard"上的工具條連線
不用先定義方法, 直接從"Storyboard"往"控制器"連線
3. 注意點:
一個控件能夠關聯多個屬性
一個屬性不能夠關聯多個控件
在進行屬性連線的時候, Xcode會自動幫咱們進行類型檢測, 若是類型不匹配那麼不能連線
若是將屬性和控件連線以後又將屬性刪除了, 那麼只要程序運行就會報一個經典錯誤
'[<ViewController 0x7fe9d9f1a5d0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key lable.'
任何UI控件均可以和屬性進行連線, 可是並非任何控件均可以和方法連線. 只有繼承於UIControl的控件才能夠連線
+ 什麼是控件?
- 屏幕上的全部UI元素都叫作控件,也有人叫作視圖、組件
- 按鈕(UIButton)、文本(UILabel)都是控件
+ 控件的共同屬性有哪些?
- 尺寸
- 位置
- 背景色
- ......
+ 蘋果將控件的共同屬性都抽取到父類UIView中
- 全部的控件最終都繼承自UIView
- UIButton、UILabel都是繼承自UIView(能夠查看頭文件)
+ 每個控制器(UIViewController)內部都有個默認的UIView屬性
- @property(nonatomic,retain) UIView *view;
- 控制器中管理的其餘全部控件都是這個view的子控件(直接或者間接)
+ UIView常見屬性和方法
1 + @property(nonatomic,readonly) UIView *superview; 2 //得到本身的父控件對象 3 4 + @property(nonatomic,readonly,copy) NSArray *subviews; 5 //得到本身的全部子控件對象 6 7 + @property(nonatomic) NSInteger tag; 8 //控件的ID(標識),父控件能夠經過tag來找到對應的子控件 9 10 + @property(nonatomic) CGAffineTransform transform; 11 // 控件的形變屬性(能夠設置旋轉角度、比例縮放、平移等屬性) 12 13 + @property(nonatomic) CGRect frame; 14 // 控件矩形框在父控件中的位置和尺寸(以父控件的左上角爲座標原點) 15 16 + @property(nonatomic) CGRect bounds; 17 //控件矩形框的位置和尺寸(以本身左上角爲座標原點,因此bounds的x、y通常爲0) 18 19 + @property(nonatomic) CGPoint center; 20 // 控件中點的位置(以父控件的左上角爲座標原點) 21 22 23 24 25 - (void)addSubview:(UIView *)view; 26 //添加一個子控件view 27 28 - (void)removeFromSuperview; 29 //從父控件中移除 30 31 - (UIView *)viewWithTag:(NSInteger)tag; 32 //根據一個tag標識找出對應的控件(通常都是子控件)
2. 修改對象的結構體成員
在OC中,不容許直接修改「對象」的「結構體屬性」的「成員」,可是容許修改「對象」的「結構體屬性」
修改結構體屬性的成員方法以下:
(1)使用臨時變量記錄對象的結構體屬性
(2) 修改臨時變量的屬性
(3)將臨時變量從新設置給對象的結構體屬性
3. 在程序開發中須要避免出現魔法數字(Magic Number)
使用枚舉類型,能夠避免在程序中出現魔法數字
(1)枚舉類型實質上就是一個整數,其做用就是用來替代魔法數字
(2)枚舉類型中,指定了第一個整數以後,後面的數字會遞增
4. frame & bounds & center
1> frame能夠修改對象的位置和尺寸
2> bounds能夠修改對象的尺寸
3> center能夠修改對象的位置
1、
1.UIButton 按鈕
2.UILabel 文本標籤
3.UITextField 文本輸入框
4.UIImageView 圖片顯示
5.UIScrollView 滾動的控件
6.UITableView 表格
7.UICollectionView 九宮格
8.UIWebView 網頁顯示控件
9.UIAlertView 對話框(中間彈框)
10.UINavigationBar導航條
2、
1.UIPageControl 分頁控件
2.UITextView 能滾動的文字顯示控件
3.UIActivityIndicator 圈圈
4.UISwitch 開關
5.UIActionSheet 底部彈框
6.UIDatePicker 日期選擇器
3、
1.UIToolbar 工具條
2.UIProgressView 進度條
3.UISlider 滑塊
4.UISegmentControl 選項卡
5.UIPickerView 選擇器
紅色代表最經常使用,藍色表明通常,黑色表明幾乎不用(這不是絕對的,僅供參考)
4、控件使用的介紹;
(一)、
1.UIButton
有一個很是重要的UI控件---UIButton,俗稱「按鈕」 通常狀況下,點擊某個控件後,會作出相應反應的都是按鈕 按鈕的功能比較多,既能顯示文字,又能顯示圖片,還能隨時調整內部圖片和文字的位置
normal(普通狀態)
默認狀況(Default) 對應的枚舉常量:UIControlStateNormal
highlighted(高亮狀態) 按鈕被按下去的時候(手指還未鬆開) 對應的枚舉常量:UIControlStateHighlighted
disabled(失效狀態,不可用狀態) 若是enabled屬性爲NO,就是處於disable狀態,表明按鈕不能夠被點擊 對應的枚舉常量:UIControlStateDisabled
設置按鈕的背景圖片
設置按鈕在不一樣狀態下的背景圖片 (爲了保證高亮狀態下的圖片正常顯示,必須設置按鈕的type爲custom)
實際上,UIButton自帶了不少種不一樣的樣式
在用代碼建立按鈕的同時指定按鈕樣式 UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
UIButtonTypeCustom:無類型,按鈕的內容需要自定義
UIButtonTypeDetailDisclosure:
UIButtonTypeInfoLight:
UIButtonTypeInfoDark:
UIButtonTypeContactAdd:
UIButton的常見設置
- (void)setTitle:(NSString *)title forState:(UIControlState)state、;
設置按鈕的文字
- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state;
設置按鈕的文字顏色
- (void)setImage:(UIImage *)image forState:(UIControlState)state;
設置按鈕內部的小圖片
- (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state;
設置按鈕的背景圖片
設置按鈕的文字字體(須要拿到按鈕內部的label來設置)
btn.titleLabel.font = [UIFont systemFontOfSize:13];
- (NSString *)titleForState:(UIControlState)state;
得到按鈕的文字
- (UIColor *)titleColorForState:(UIControlState)state;
得到按鈕的文字顏色
- (UIImage *)imageForState:(UIControlState)state;
得到按鈕內部的小圖片
- (UIImage *)backgroundImageForState:(UIControlState)state;
得到按鈕的背景圖片
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(30, 360, 90, 35);
[btn setTitle:@"ZoomIn" forState:UIControlStateNormal];
[btn setTitle:@"ZoomIn" forState:UIControlStateHighlighted];
[btn addTarget:self action:@selector(zoomInAction:) forControlEvents:UIControlEventTouchUpInside];
//@selector能夠理解爲"選擇子",selector是一個指針變量,相似於sender。 這裏是將method的方法指定給新建的這個btn。
/*在 method 方法裏能夠將 sender 看做是 btn 了
好比設置btn的hidden屬性等等
btn.hidden = YES;
這樣btn被隱藏了
*/
[view addSubview:btn]; -(void)zoomInAction:(id)sender { }
從UIControl繼承:UIView的:UIResponder:NSObject的符合NSCoding NSCoding(UIView的)NSObject的(NSObject的)框架/系統/資源庫/框架/ UIKit.framework在iPhone OS 2.0和更高的可用性。聲明UIButton.h相關的代碼示例配件BubbleLevel HeadsUpUI TheElements UICatalog
目錄[ 隱藏 ] |
UIButton的類是一個UIControl子類,它實現了在觸摸屏上的按鈕。觸摸一個按鈕攔截事件和動做消息發送到目標對象時,它的挖掘。設定的目標和行動方法都繼承自UIControl。這個類提供了方法來設置標題,圖像,按鈕等外觀屬性。經過使用set方法,你能夠指定一個不一樣的外觀爲每一個按鈕狀態。
建立按鈕+ buttonWithType:配置按鈕的標題
ButtonType屬性字體屬性lineBreakMode財產titleShadowOffset財產reversesTitleShadowWhenHighlighted財產
- setTitle:forState: - setTitleColor:forState: - setTitleShadowColor:forState: - titleColorForState: - titleForState: - titleShadowColorForState:配置按鈕圖像
adjustsImageWhenHighlighted財產adjustsImageWhenDisabled財產showsTouchWhenHighlighted財產
- backgroundImageForState: - imageForState: - setBackgroundImage:forState: - setImage:forState:配置邊緣的Insets
titleEdgeInsets財產imageEdgeInsets財產contentEdgeInsets財產
獲取當前狀態
currentTitle財產currentTitleColor財產currentTitleShadowColor財產currentImage財產currentBackgroundImage財產
尺寸入門 - backgroundRectForBounds: - contentRectForBounds: - titleRectForContentRect: - imageRectForContentRect:
Objective - C的屬性,看到的Objective - C 2.0編程語言中的「屬性」。
一個布爾值,決定是否形象的變化時,該按鈕被禁用。
@屬性(非原子)BOOL adjustsImageWhenDisabled討論,若是是的話,圖像繪製較深時,按鈕被禁用。默認值是YES。
供貨狀況在iPhone OS 2.0和更高版本。另請參見
@財產adjustsImageWhenHighlighted
在UIButton.h宣佈相關的示例代碼BubbleLevel
一個布爾值,決定是否按鈕時,突出顯示圖像的變化。
@屬性(非原子)BOOL adjustsImageWhenHighlighted討論,若是是,繪製圖像較輕的按鈕時,突出顯示。默認值是YES。
供貨狀況在iPhone OS 2.0和更高版本。另請參見
@財產adjustsImageWhenDisabled
在UIButton.h宣佈相關的示例代碼BubbleLevel
按鈕類型。(只讀)
@屬性(非原子,只讀)UIButtonType按鈕類型的討論,見UIButtonType的可能值。
供貨狀況在iPhone OS 2.0和更高版本。聲明在UIButton.h
內容的插圖或一開始就爲每一個邊緣。
@屬性(非原子)UIEdgeInsets contentEdgeInsets若是每條邊的價值是積極的,指定的插圖,不然,指定一開始。一個插圖是周圍繪製矩形的保證金;每邊(左,右,頂部和底部),能夠有不一樣的值。使用UIEdgeInsetsMake功能設置此屬性。默認值是UIEdgeInsetsZero。
供貨狀況在iPhone OS 2.0和更高版本。另請參見
_AT_財產imageEdgeInsets
宣佈UIButton.h currentBackgroundImage按鈕上顯示當前的背景圖像。(只讀)
@屬性(只讀,非原子,保留)的UIImage * currentBackgroundImage討論這個值能夠爲零。
供貨狀況在iPhone OS 2.0和更高版本。另請參見
_AT_財產currentImage
聲明在UIButton.h
當前圖像上顯示的按鈕。(只讀)
@屬性(只讀,非原子,保留)的UIImage * currentImage討論這個值能夠爲零。
供貨狀況在iPhone OS 2.0和更高版本。另請參見
_AT_財產currentBackgroundImage
聲明在UIButton.h
當前標題,按鈕上顯示的。(只讀)
@屬性(只讀,非原子,保留)的NSString * currentTitle討論這個值可能爲零。
供貨狀況在iPhone OS 2.0和更高版本。另請參見
@財產currentTitleColor財產currentTitleShadowColor
聲明在UIButton.h
顏色用於顯示標題。(只讀)
@屬性(只讀,非原子,保留)UIColor * currentTitleColor討論這個值是保證不會是零。默認值是白色。
供貨狀況在iPhone OS 2.0和更高版本。另請參見
@財產currentTitle財產currentTitleShadowColor
聲明在UIButton.h
標題的陰影的顏色。(只讀)
@屬性(只讀,非原子,保留)UIColor * currentTitleShadowColor討論默認值是白色。
供貨狀況在iPhone OS 2.0和更高版本。另請參見
@財產currentTitle財產currentTitleColor
聲明在UIButton.h
字體用來顯示按鈕上的文字。
@屬性(非原子,保留)UIFont *字體的討論,若是爲零,使用系統字體。默認值是零。
供貨狀況在iPhone OS 2.0和更高版本。聲明在UIButton.h
圖像插圖或一開始就爲每一個邊緣。
@屬性(非原子)UIEdgeInsets imageEdgeInsets若是每條邊的價值是積極的,指定的插圖,不然,指定一開始。一個插圖是周圍繪製矩形的保證金;每邊(左,右,頂部和底部),能夠有不一樣的值。使用UIEdgeInsetsMake功能設置此屬性。默認值是UIEdgeInsetsZero。
供貨狀況在iPhone OS 2.0和更高版本。另請參見
_AT_財產titleEdgeInsets
聲明在UIButton.h
繪製文本時使用的換行模式。
屬性(非原子)UILineBreakMode lineBreakMode討論這個屬性是UILineBreakMode描述的常量之一。默認值是UILineBreakModeMiddleTruncation。
供貨狀況在iPhone OS 2.0和更高版本。在UIButton.h聲明reversesTitleShadowWhenHighlighted一個布爾值,決定是否按鈕時,突出的標題陰影的變化。
若是有屬性(非原子)BOOL reversesTitleShadowWhenHighlighted討論,從雕刻的影子時,突出浮雕外觀的變化。默認值是NO。
供貨狀況在iPhone OS 2.0和更高版本。聲明在UIButton.h
一個布爾值,決定是否點擊按鈕會致使其發光。
@屬性(非原子)BOOL showsTouchWhenHighlighted討論,若是是的話,按鈕發光時挖掘出來,不然,它不會。圖像和按鈕的行爲是沒有改變的輝光。默認值是NO。
供貨狀況在iPhone OS 2.0和更高版本。另請參見
@財產adjustsImageWhenHighlighted
聲明在UIButton.h
標題插圖或一開始就爲每一個邊緣。
@屬性(非原子)UIEdgeInsets titleEdgeInsets若是每條邊的價值是積極的,指定的插圖,不然,指定一開始。一個插圖是周圍繪製矩形的保證金;每邊(左,右,頂部和底部),能夠有不一樣的值。使用UIEdgeInsetsMake功能設置此屬性。默認值是UIEdgeInsetsZero。
供貨狀況在iPhone OS 2.0和更高版本。另請參見
_AT_財產imageEdgeInsets
聲明在UIButton.h
用於顯示接收的標題陰影的偏移。
屬性(非原子)CGSize titleShadowOffset討論的水平和垂直偏移值,使用CGSize數據類型的寬度和高度場指定的。正面的價值觀老是向上延伸的權利,從用戶的角度來看。默認值是CGSizeZero。
供貨狀況在iPhone OS 2.0和更高版本。宣佈UIButton.h類方法
buttonWithType:建立並返回一個指定類型的新按鈕。
+(ID)buttonWithType:(UIButtonType)按鈕類型
按鈕類型。見的可能值UIButtonType。
返回值一個新建立的按鈕。
供貨狀況在iPhone OS 2.0和更高版本。相關的示例代碼配件BubbleLevel TheElements TouchCells UICatalog宣佈UIButton.h實例方法
返回一個按鈕的狀態中使用的背景圖像。
- (UIImage的*)backgroundImageForState:(UIControlState)狀態
參數狀態的狀態使用的背景圖像。可能的值是在UIControlState描述。
返回值用於指定的狀態背景圖像。
供貨狀況在iPhone OS 2.0和更高版本。又見 - setBackgroundImage:forState:UIButton.h聲明
返回矩形的接收繪製其背景。
- (CGRect)backgroundRectForBounds:(CGRect)邊界
參數範圍接收器的邊界矩形。
返回值的矩形接收機,繪製其背景。
供貨狀況在iPhone OS 2.0和更高版本。又見 - contentRectForBounds:UIButton.h聲明
返回矩形的接收提請其所有內容。
- (CGRect)contentRectForBounds:(CGRect)邊界
參數限定爲接收器的邊界矩形。
返回值的矩形接收提請其所有內容。
討論內容的矩形來顯示圖像和標題對齊和其餘設置,包括任何填充和調整所需的面積。
供貨狀況在iPhone OS 2.0和更高版本。 - titleRectForContentRect: - imageRectForContentRect: - backgroundRectForBounds:UIButton.h imageForState中聲明:返回一個按鈕的狀態所使用的圖像。
- (UIImage的*)imageForState:(UIControlState)狀態
參數狀態使用圖像的狀態。可能的值是在UIControlState描述。
返回值用於指定狀態的圖像。
供貨狀況在iPhone OS 2.0和更高版本。又見 - setImage:forState:UIButton.h imageRectForContentRect宣佈:返回接收繪製其圖像的矩形。
- (CGRect)imageRectForContentRect:(CGRect)contentRect
參數contentRect接收的內容矩形。
返回值接收繪製其圖像的矩形。
供貨狀況在iPhone OS 2.0和更高版本。又見 - contentRectForBounds: - titleRectForContentRect:forState::UIButton.h setBackgroundImage宣佈設置背景圖像使用指定的按鈕狀態。
- (無效)setBackgroundImage:(UIImage的*)圖像forState:(UIControlState)狀態
參數圖像背景圖像使用指定的狀態。
狀態的狀態使用指定的圖像。在UIControlState值的描述。
在通常性討論,若是沒有一個國家指定一個屬性,默認是使用UIControlStateNormal的價值。若是UIControlStateNormal值未設置,則屬性默認爲一個系統的價值。所以,至少,你應該設置爲正常狀態的價值。
供貨狀況在iPhone OS 2.0和更高版本。又見 - backgroundImageForState:相關示例代碼配件BubbleLevel TheElements UICatalog UIButton.h setImage宣佈:forState:設置圖像使用指定的狀態。
- (無效)setImage:(UIImage的*)圖像forState:(UIControlState)狀態
參數圖像的圖像使用指定的狀態。
狀態的狀態使用指定的標題。在UIControlState值的描述。
在通常性討論,若是沒有一個國家指定一個屬性,默認是使用UIControlStateNormal的價值。若是UIControlStateNormal值未設置,則屬性默認爲一個系統的價值。所以,至少,你應該設置爲正常狀態的價值。
供貨狀況在iPhone OS 2.0和更高版本。又見 - imageForState:forState::相關示例代碼BubbleLevel在UIButton.h setTitle聲明TouchCells設置標題使用指定的狀態。
- (無效)setTitle是:(NSString的*)forState標題:(UIControlState)狀態
參數標題標題使用指定的狀態。
狀態的狀態使用指定的標題。在UIControlState值的描述。
在通常性討論,若是沒有一個國家指定一個屬性,默認是使用UIControlStateNormal的價值。若是UIControlStateNormal價值不設置,則屬性默認爲系統值。所以,至少,你應該設置爲正常狀態的價值。
供貨狀況在iPhone OS 2.0和更高版本。又見 - titleForState:UIButton.h setTitleColor:forState相關的示例代碼BubbleLevel UICatalog宣佈:設置標題使用指定的狀態的顏色。
- (無效)setTitleColor:(UIColor *)顏色forState:(UIControlState)狀態
參數顏色的標題使用指定的狀態的顏色。
狀態的狀態使用指定的顏色。在UIControlState值的描述。
在通常性討論,若是沒有一個國家指定一個屬性,默認是使用UIControlStateNormal的價值。若是UIControlStateNormal值未設置,則屬性默認爲一個系統的價值。所以,至少,你應該設置爲正常狀態的價值。
供貨狀況在iPhone OS 2.0和更高版本。又見 - titleColorForState:UIButton.h setTitleShadowColor:forState相關的示例代碼BubbleLevel UICatalog宣佈:設置標題陰影的顏色,使用指定的狀態。
- (無效)setTitleShadowColor:(UIColor *)顏色forState:(UIControlState)狀態
參數顏色的標題陰影的顏色,使用指定的狀態。
狀態的狀態使用指定的顏色。在UIControlState值的描述。
在通常性討論,若是沒有一個國家指定一個屬性,默認是使用UIControlStateNormal的價值。若是UIControlStateNormal值未設置,則屬性默認爲一個系統的價值。所以,至少,你應該設置爲正常狀態的價值。
供貨狀況在iPhone OS 2.0和更高版本。又見 - titleShadowColorForState:UIButton.h titleColorForState宣佈:返回一個國家使用的標題的顏色。
- (UIColor *)titleColorForState:(UIControlState)狀態
參數狀態的國家,使用的標題顏色。可能的值是在UIControlState描述。
返回值指定的狀態標題的顏色。
供貨狀況在iPhone OS 2.0和更高版本。又見 - setTitleColor:forState:UIButton.h titleForState宣佈:返回一個國家所使用的標題。
- (NSString的*)titleForState:(UIControlState)狀態
參數狀態的國家,使用的標題。可能的值是在UIControlState描述。
返回值指定的狀態標題。
供貨狀況在iPhone OS 2.0和更高版本。又見 - setTitle:forState:UIButton.h titleRectForContentRect宣佈:返回矩形的接收器繪製它的標題。
- (CGRect)titleRectForContentRect:(CGRect)contentRect
參數contentRect接收的內容矩形。
返回值的矩形接收器繪製它的標題。
供貨狀況在iPhone OS 2.0和更高版本。又見 - contentRectForBounds: - imageRectForContentRect:UIButton.h titleShadowColorForState宣佈:返回的陰影顏色爲國家所用的標題。
- (UIColor *)titleShadowColorForState:(UIControlState)狀態
參數狀態的國家,使用的標題陰影顏色。可能的值是在UIControlState描述。
返回值指定的狀態標題的影子顏色。
供貨狀況在iPhone OS 2.0和更高版本。又見 - setTitleShadowColor:forState:UIButton.h常量聲明
UIButtonType指定一個按鈕的風格。
的typedef枚舉{
UIButtonTypeCustom = 0,UIButtonTypeRoundedRect,UIButtonTypeDetailDisclosure,UIButtonTypeInfoLight,UIButtonTypeInfoDark,UIButtonTypeContactAdd
} UIButtonType;常量UIButtonTypeCustom無按鈕的樣式。
在iPhone OS 2.0及更高版本。
聲明中UIButton.h。
UIButtonTypeRoundedRect一個圓角矩形樣式的按鈕。
在iPhone OS 2.0及更高版本。
聲明中UIButton.h。
UIButtonTypeDetailDisclosure一個詳細披露按鈕。
在iPhone OS 2.0及更高版本。
聲明中UIButton.h。
UIButtonTypeInfoLight一個信息按鈕,有一個淺色背景。
在iPhone OS 2.0及更高版本。
聲明中UIButton.h。
UIButtonTypeInfoDark一個信息按鈕,有一個黑暗的背景。
在iPhone OS 2.0及更高版本。
聲明中UIButton.h。
UIButtonTypeContactAdd一個聯繫人添加「按鈕。
在iPhone OS 2.0及更高版本。
聲明中UIButton.h。
供貨狀況在iPhone OS 2.0和更高版本。聲明在UIButton.h
(一)2.UILabel
UILabel極其經常使用,功能比較專注:顯示文字
UILabel的常見屬性
@property(nonatomic,copy) NSString *text;
顯示的文字
@property(nonatomic,retain) UIFont *font;
字體
@property(nonatomic,retain) UIColor *textColor;
文字顏色
@property(nonatomic) NSTextAlignment textAlignment;
對齊模式(好比左對齊、居中對齊、右對齊)
@property(nonatomic) NSInteger numberOfLines;
文字行數
@property(nonatomic) NSLineBreakMode lineBreakMode;
換行模式
UIFont
UIFont表明字體,常見建立方法有如下幾個:
+ (UIFont *)systemFontOfSize:(CGFloat)fontSize; 系統默認字體
+ (UIFont *)boldSystemFontOfSize:(CGFloat)fontSize; 粗體
+ (UIFont *)italicSystemFontOfSize:(CGFloat)fontSize; 斜體
#import "LabelTestViewController.h"
@implementation LabelTestViewController
/*
Accessing the Text Attributes
text property
font property
textColor property
textAlignment property
lineBreakMode property
enabled property
Sizing the Label’s Text
adjustsFontSizeToFitWidth property
baselineAdjustment property
minimumFontSize property 無例
numberOfLines property
Managing Highlight Values
highlightedTextColor property
highlighted property
Drawing a Shadow
shadowColor property
shadowOffset property
Drawing and Positioning Overrides
– textRectForBounds:limitedToNumberOfLines: 無例
– drawTextInRect: 無例
Setting and Getting Attributes
userInteractionEnabled property
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
UILabel *label1 = [[UILabel alloc]initWithFrame:CGRectMake(50.0, 20.0, 200.0, 50.0)];
UILabel *label2 = [[UILabel alloc]initWithFrame:CGRectMake(50.0, 80.0, 200.0, 50.0)];
UILabel *label3 = [[UILabel alloc]initWithFrame:CGRectMake(50.0, 140.0, 200.0, 50.0)];
UILabel *label4 = [[UILabel alloc]initWithFrame:CGRectMake(50.0, 200.0, 200.0, 50.0)];
UILabel *label5 = [[UILabel alloc]initWithFrame:CGRectMake(50.0, 260.0, 200.0, 50.0)];
UILabel *label6 = [[UILabel alloc]initWithFrame:CGRectMake(50.0, 320.0, 200.0, 50.0)];
UILabel *label7 = [[UILabel alloc]initWithFrame:CGRectMake(50.0, 380.0, 200.0, 50.0)];
//設置顯示文字
label1.text = @"label1";
label2.text = @"label2";
label3.text = @"label3--label3--label3--label3--label3--label3--label3--label3--label3--label3--label3--";
label4.text = @"label4--label4--label4--label4--";
label5.text = @"label5--label5--label5--label5--label5--label5--";
label6.text = @"label6";
label7.text = @"label7";
//設置字體:粗體,正常的是 SystemFontOfSize
label1.font = [UIFont boldSystemFontOfSize:20];
//設置文字顏色
label1.textColor = [UIColor orangeColor];
label2.textColor = [UIColor purpleColor];
//設置文字位置
label1.textAlignment = UITextAlignmentRight;
label2.textAlignment = UITextAlignmentCenter;
//設置字體大小適應label寬度
label4.adjustsFontSizeToFitWidth = YES;
//設置label的行數
UIlabel.backgroudColor=[UIColor clearColor]; //能夠去掉背景色
//設置高亮
label6.highlighted = YES;
label6.highlightedTextColor = [UIColor orangeColor];
//設置陰影
label7.shadowColor = [UIColor redColor];
label7.shadowOffset = CGSizeMake(1.0,1.0);
//設置是否能與用戶進行交互
label7.userInteractionEnabled = YES;
//設置label中的文字是否可變,默認值是YES
label3.enabled = NO;
//設置文字過長時的顯示格式
label3.lineBreakMode = UILineBreakModeMiddleTruncation;//截去中間
// typedef enum {
// UILineBreakModeWordWrap = 0,
// UILineBreakModeCharacterWrap,
// UILineBreakModeClip,//截去多餘部分
// UILineBreakModeHeadTruncation,//截去頭部
// UILineBreakModeTailTruncation,//截去尾部
// UILineBreakModeMiddleTruncation,//截去中間
// } UILineBreakMode;
//若是adjustsFontSizeToFitWidth屬性設置爲YES,這個屬性就來控制文本基線的行爲
label4.baselineAdjustment = UIBaselineAdjustmentNone;
// typedef enum {
// UIBaselineAdjustmentAlignBaselines,
// UIBaselineAdjustmentAlignCenters,
// UIBaselineAdjustmentNone,
// } UIBaselineAdjustment;
[self.view addSubview:label1];
[self.view addSubview:label2];
[self.view addSubview:label3];
[self.view addSubview:label4];
[self.view addSubview:label5];
[self.view addSubview:label6];
[self.view addSubview:label7];
[label1 release];
[label2 release];
[label3 release];
[label4 release];
[label5 release];
[label6 release];
[label7 release];
[super viewDidLoad];
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
@end
UITextField – 文本輸入框
1.UITextField的初始化和設置
textField = [[UITextField alloc] initWithFrame:CGRectMake(120.0f, 80.0f, 150.0f, 30.0f)];
[textField setBorderStyle:UITextBorderStyleRoundedRect]; //外框類型
textField.placeholder = @"password"; //默認顯示的字
textField.secureTextEntry = YES; //密碼
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
textField.returnKeyType = UIReturnKeyDone;
textField.clearButtonMode = UITextFieldViewModeWhileEditing; //編輯時會出現個修改X
textField.delegate = self;
2.要實現的Delegate方法,關閉鍵盤
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[self.textField resignFirstResponder];
return YES;
}
3. 能夠在UITextField使用下面方法,按return鍵返回
-(IBAction) textFieldDone:(id) sender
{
[textFieldName resignFirstResponder];
}
連接TextField控件的"Did end on exit"
最右側加圖片是如下代碼,
UIImageView *imgv=[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"right.png"]];
text.rightView=imgv;
text.rightViewMode = UITextFieldViewModeAlways;
若是是在最左側加圖片就換成:
text.leftView=imgv;
text.leftViewMode = UITextFieldViewModeAlways;
UITextField 繼承自 UIControl,此類中有一個屬性contentVerticalAlignment
因此想讓UITextField裏面的text垂直居中能夠這樣寫:
text.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
查看函數的方法:
按住command鍵雙擊進入函數聲明
按住alt鍵雙擊進入doc文檔
///////////////////////////////////////////////////////////////
文本框經常使用方法:
如何用程序刪除文本框中選中的文本
[textView delete: nil];
///////////////////////////////////////////////////////////////
如何限制文本框只能輸入數字:
創建NSNumberFormatter的子類,增長這個方法,將formatter連接至文本框。
- (BOOL) isPartialStringValid: (NSString **) partialStringPtr
proposedSelectedRange: (NSRangePointer) proposedSelRangePtr
originalString: (NSString *) origString
originalSelectedRange: (NSRange) origSelRange
errorDescription: (NSString **) error
{
NSCharacterSet *nonDigits;
NSRange newStuff;
NSString *newStuffString;
nonDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
newStuff = NSMakeRange(origSelRange.location,
proposedSelRangePtr->location
- origSelRange.location);
newStuffString = [*partialStringPtr substringWithRange: newStuff];
if ([newStuffString rangeOfCharacterFromSet: nonDigits
options: NSLiteralSearch].location != NSNotFound) {
*error = @"不是數字";
return (NO);
} else {
*error = nil;
return (YES);
}
}
///////////////////////////////////////////////////////////////
從文本框獲取十六進制數據的代碼
char singleNumberString[3] = {'\0','\0','\0'};
uint32_t singleNumber = 0;
uint32_t i = 0;
NSMutableData *data = [NSMutableData data];
//從文本框獲取到得數據
const char *buf = [[_hexToSendTextField text] UTF8String];
//轉換爲十六進制
for(i = 0; i < strlen(buf); i+=2)
{
if(((i+1) < len && isxdigit(buf) && (isxdigit(buf[i+1])))
{
singleNumberString[0] = buf;
singleNumberString[1] = buf[i+1];
sscanf(singleNumberString, "%x", &singleNumber);
[data appendBytes:(void*)(&tmp) length:1];
}
else
{
break;
}
}
//輸出
NSLog(@"%@", data);
/////////////////////////////////////////////////////////////
點擊 UITextView 輸入文字,光標都從最初點開始
- (void)textViewDidChangeSelection:(UITextView *)textView
{
NSRange range;
range.location = 0;
range.length = 0;
textView.selectedRange = range;
}
///////////////////////////////////////////////////////////
軟鍵盤
在登陸頁面要實現用戶名和密碼,密碼要是點點格式,引入當前頁面光標要停留在用戶名選項,軟鍵盤要彈出界面。以下圖:
彈出鍵盤:
[username becomeFirstResponder];
取消鍵盤:
[username resignFirstResponder];
密碼保護:
password.secureTextEntry=YES;
//////////////////////////////////////////////////////////////////
1.UITextField的初始化和設置
textField = [[UITextField alloc] initWithFrame:CGRectMake(120.0f, 80.0f, 150.0f, 30.0f)];
[textField setBorderStyle:UITextBorderStyleRoundedRect]; //外框類型
textField.placeholder = @"password"; //默認顯示的字
textField.secureTextEntry = YES; //密碼
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
textField.returnKeyType = UIReturnKeyDone;
textField.clearButtonMode = UITextFieldViewModeWhileEditing; //編輯時會出現個修改X
textField.delegate = self;
2.要實現的Delegate方法,關閉鍵盤
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[self.textField resignFirstResponder];
return YES;
}
3. 能夠在UITextField使用下面方法,按return鍵返回
-(IBAction) textFieldDone:(id) sender
{
[textFieldName resignFirstResponder];
}
連接TextField控件的"Did end on exit"
////////////////////////////////////////////////////////////////////
限制輸入文本的長度
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (range.location >= MAX_LENGTH)
return NO; // return NO to not change text
return YES;
}
if (textField.text.length >= 10 && range.length == 0)
return NO;
return YES;
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if ([textField.text length] > MAXLENGTH)
{
textField.text = [textField.text substringToIndex:MAXLENGTH-1];
return NO;
}
return YES;
}
//////////////////////////////////////////////////////////////////////
使用UITextFieldDelegate來隱藏鍵盤
在iPhone界面上,時常會須要當用戶輸入完內容後,隱藏鍵盤。 固然有不少方法,今天只介紹使用UITextFieldDelegate這個協議實現隱藏鍵盤。
其實很簡單, 須要三步:
1. 在你的控制器類中,加入UITextFieldDelegate這個協議
如:@interface AddItemViewController : UIViewController <UITextFieldDelegate>
2. 在使用了UITextFieldDelegate協議的控制器類的實現中,加入- (BOOL)textFieldShouldReturn:方法。
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
//設置焦點:
[UITextField becomeFirstResponder];
3. 將xib文件中的TextField控件的delegate變量指向到以前使用UITextFieldDelegate協議的那個控制器類,將 TextField的delegate IBOutlet變量右鍵連接到前面的控制器類的實例上。或者使用代碼方式,指定相關TextField的delegate變量。
- (void)viewDidLoad
{
[super viewDidLoad];
itemNameField.delegate = self;
priceField.delegate = self;
}
(一)4.UIImageView
UIImageView的常見屬性
@property(nonatomic,retain) UIImage *image;
顯示的圖片
@property(nonatomic,copy) NSArray *animationImages;
顯示的動畫圖片
@property(nonatomic) NSTimeInterval animationDuration;
動畫圖片的持續時間
@property(nonatomic) NSInteger animationRepeatCount;
動畫的播放次數(默認是0,表明無限播放)
UIImageView的常見方法
- (void)startAnimating; // 開始動畫
- (void)stopAnimating; // 中止動畫
- (BOOL)isAnimating; // 是否正在執行動畫
UIImage
一個UIImage對象表明一張圖片,通常經過imageNamed:方法就能夠經過文件名加載項目中的圖片
UIImage *image = [UIImage imageNamed:@"lufy"];
(一)5.UIScrollvView
UIScrollView – 滾動的控件
1.UIScrollView控件是什麼?
(1)移動設備的屏幕⼤大⼩小是極其有限的,所以直接展⽰示在⽤用戶眼前的內容也至關有限
(2)當展⽰示的內容較多,超出⼀一個屏幕時,⽤用戶可經過滾動⼿手勢來查看屏幕之外的內容
(3)普通的UIView不具有滾動功能,不能顯⽰示過多的內容
(4)UIScrollView是一個可以滾動的視圖控件,能夠⽤用來展⽰示⼤大量的內容,而且能夠經過滾 動查看全部的內容
(5) 舉例:手機上的「設置」、其餘⽰示例程序
2.UIScrollView的簡單使用
(1)將須要展⽰的內容添加到UIScrollView中
(2)設置UIScrollView的contentSize屬性,告訴UIScrollView全部內容的尺⼨寸,也就是告訴 它滾動的範圍(能滾多遠,滾到哪⾥裏是盡頭)
3.屬性
(1)經常使用屬性:
1)@property(nonatomic)CGPointcontentOffset; 這個屬性⽤用來表⽰示UIScrollView滾動的位置
2)@property(nonatomic)CGSizecontentSize;這個屬性⽤用來表⽰示UIScrollView內容的尺⼨寸,滾動範圍(能滾多遠)
3)@property(nonatomic)UIEdgeInsetscontentInset; 這個屬性可以在UIScrollView的4周增長額外的滾動區域
(2)其餘屬性:
1)@property(nonatomic) BOOL bounces; 設置UIScrollView是否須要彈簧效果
2)@property(nonatomic,getter=isScrollEnabled)BOOLscrollEnabled; 設置UIScrollView是否能滾動
3)@property(nonatomic) BOOL showsHorizontalScrollIndicator; 是否顯⽰示⽔水平滾動條
4)@property(nonatomic) BOOL showsVerticalScrollIndicator; 是否顯⽰示垂直滾動條
4.注意點
• 若是UIScrollView⽆沒法滾動,多是如下緣由:
(1)沒有設置contentSize
(2) scrollEnabled = NO
(3) 沒有接收到觸摸事件:userInteractionEnabled = NO
(4)沒有取消autolayout功能(要想scrollView滾動,必須取消autolayout)
2、關於UIScrollView常見屬性的一些說明
1.屬性使用的代碼示例
1 #import "MJViewController.h" 2 3 @interface MJViewController () 4 { 5 //在私有擴展中建立一個屬性 6 UIScrollView *_scrollView; 7 } 8 @end 9 10 @implementation MJViewController 11 12 - (void)viewDidLoad 13 { 14 [super viewDidLoad]; 15 16 // 1.建立UIScrollView 17 UIScrollView *scrollView = [[UIScrollView alloc] init]; 18 scrollView.frame = CGRectMake(0, 0, 250, 250); // frame中的size指UIScrollView的可視範圍 19 scrollView.backgroundColor = [UIColor grayColor]; 20 [self.view addSubview:scrollView]; 21 22 // 2.建立UIImageView(圖片) 23 UIImageView *imageView = [[UIImageView alloc] init]; 24 imageView.image = [UIImage imageNamed:@"big.jpg"]; 25 CGFloat imgW = imageView.image.size.width; // 圖片的寬度 26 CGFloat imgH = imageView.image.size.height; // 圖片的高度 27 imageView.frame = CGRectMake(0, 0, imgW, imgH); 28 [scrollView addSubview:imageView]; 29 30 // 3.設置scrollView的屬性 31 32 // 設置UIScrollView的滾動範圍(內容大小) 33 scrollView.contentSize = imageView.image.size; 34 35 // 隱藏水平滾動條 36 scrollView.showsHorizontalScrollIndicator = NO; 37 scrollView.showsVerticalScrollIndicator = NO; 38 39 // 用來記錄scrollview滾動的位置 40 // scrollView.contentOffset = ; 41 42 // 去掉彈簧效果 43 // scrollView.bounces = NO; 44 45 // 增長額外的滾動區域(逆時針,上、左、下、右) 46 // top left bottom right 47 scrollView.contentInset = UIEdgeInsetsMake(20, 20, 20, 20); 48 49 _scrollView = scrollView; 50 } 51 52 - (IBAction)down:(UIButton *)sender { 53 [UIView animateWithDuration:1.0 animations:^{ 54 //三個步驟 55 CGPoint offset = _scrollView.contentOffset; 56 offset.y += 150; 57 _scrollView.contentOffset = offset; 58 59 //_scrollView.contentOffset = CGPointMake(0, 0); 60 }]; 61 } 62 @end
2.幾個屬性座標示意圖
3.重要說明
(1)UIScrollView的frame與contentsize屬性的區分:UIScrollView的frame指的是這個scrollview的可視範圍(可看見的區域),contentsize是其滾動範圍。
(2)contentinset(不帶*號的通常不是結構體就是枚舉),爲UIScrollView增長額外的滾動區域。(上,左,下,右)逆時針。contentinset可使用代碼或者是視圖控制器進行設置,但二者有區別(注意區分)。
(3)contentsize屬性只能使用代碼設置。
(4)contentoffset是個CGpoint類型的結構體,用來記錄ScrollView的滾動位置,即記錄着「框」跑到了哪裏。知道了這個屬性,就知道了其位置,能夠經過設置這個屬性來控制這個「框」的移動。
(5)不容許直接修改某個對象內部結構體屬性的成員,三個步驟(先拿到值,修改之,再把修改後的值賦回去)。
(6)增長了額外區域後,contentoffset的原點在哪裏?
3、有助於理解的幾個截圖
模型圖:
對比圖:
座標圖:
(一)6UITableView
在iOS開發中UITableView能夠說是使用最普遍的控件,咱們平時使用的軟件中處處均可以看到它的影子,相似於微信、QQ、新浪微博等軟件基本上隨處都是UITableView。固然它的普遍使用天然離不開它強大的功能,今天這篇文章將針對UITableView重點展開討論。今天的主要內容包括:
UITableView有兩種風格:UITableViewStylePlain和UITableViewStyleGrouped。這二者操做起來其實並無本質區別,只是後者按分組樣式顯示前者按照普通樣式顯示而已。你們先看一下二者的應用:
1>分組樣式
2>不分組樣式
你們能夠看到在UITableView中數據只有行的概念,並無列的概念,由於在手機操做系統中顯示多列是不利於操做的。UITableView中每行數據都是一個UITableViewCell,在這個控件中爲了顯示更多的信息,iOS已經在其內部設置好了多個子控件以供開發者使用。若是咱們查看UITableViewCell的聲明文件能夠發如今內部有一個UIView控件(contentView,做爲其餘元素的父控件)、兩個UILable控件(textLabel、detailTextLabel)、一個UIImage控件(imageView),分別用於容器、顯示內容、詳情和圖片。使用效果相似於微信、QQ信息列表:
固然,這些子控件並不必定要所有使用,具體操做時能夠經過UITableViewCellStyle進行設置,具體每一個枚舉表示的意思已經在代碼中進行了註釋:
typedef NS_ENUM(NSInteger, UITableViewCellStyle) { UITableViewCellStyleDefault, // 左側顯示textLabel(不顯示detailTextLabel),imageView可選(顯示在最左邊) UITableViewCellStyleValue1, // 左側顯示textLabel、右側顯示detailTextLabel(默認藍色),imageView可選(顯示在最左邊) UITableViewCellStyleValue2, // 左側依次顯示textLabel(默認藍色)和detailTextLabel,imageView可選(顯示在最左邊) UITableViewCellStyleSubtitle // 左上方顯示textLabel,左下方顯示detailTextLabel(默認灰色),imageView可選(顯示在最左邊) };
因爲iOS是遵循MVC模式設計的,不少操做都是經過代理和外界溝通的,但對於數據源控件除了代理還有一個數據源屬性,經過它和外界進行數據交互。 對於UITableView設置完dataSource後須要實現UITableViewDataSource協議,在這個協議中定義了多種 數據操做方法,下面經過建立一個簡單的聯繫人管理進行演示:
首先咱們須要建立一個聯繫人模型KCContact
KCContact.h
// // Contact.h // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import <Foundation/Foundation.h> @interface KCContact : NSObject #pragma mark 姓 @property (nonatomic,copy) NSString *firstName; #pragma mark 名 @property (nonatomic,copy) NSString *lastName; #pragma mark 手機號碼 @property (nonatomic,copy) NSString *phoneNumber; #pragma mark 帶參數的構造函數 -(KCContact *)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName andPhoneNumber:(NSString *)phoneNumber; #pragma mark 取得姓名 -(NSString *)getName; #pragma mark 帶參數的靜態對象初始化方法 +(KCContact *)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName andPhoneNumber:(NSString *)phoneNumber; @end
KCContact.m
// // Contact.m // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import "KCContact.h" @implementation KCContact -(KCContact *)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName andPhoneNumber:(NSString *)phoneNumber{ if(self=[super init]){ self.firstName=firstName; self.lastName=lastName; self.phoneNumber=phoneNumber; } return self; } -(NSString *)getName{ return [NSString stringWithFormat:@"%@ %@",_lastName,_firstName]; } +(KCContact *)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName andPhoneNumber:(NSString *)phoneNumber{ KCContact *contact1=[[KCContact alloc]initWithFirstName:firstName andLastName:lastName andPhoneNumber:phoneNumber]; return contact1; } @end
爲了演示分組顯示咱們不妨將一組數據也抽象成模型KCContactGroup
KCContactGroup.h
// // KCContactGroup.h // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import <Foundation/Foundation.h> #import "KCContact.h" @interface KCContactGroup : NSObject #pragma mark 組名 @property (nonatomic,copy) NSString *name; #pragma mark 分組描述 @property (nonatomic,copy) NSString *detail; #pragma mark 聯繫人 @property (nonatomic,strong) NSMutableArray *contacts; #pragma mark 帶參數個構造函數 -(KCContactGroup *)initWithName:(NSString *)name andDetail:(NSString *)detail andContacts:(NSMutableArray *)contacts; #pragma mark 靜態初始化方法 +(KCContactGroup *)initWithName:(NSString *)name andDetail:(NSString *)detail andContacts:(NSMutableArray *)contacts; @end
KCContactGroup.m
// // KCContactGroup.m // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import "KCContactGroup.h" @implementation KCContactGroup -(KCContactGroup *)initWithName:(NSString *)name andDetail:(NSString *)detail andContacts:(NSMutableArray *)contacts{ if (self=[super init]) { self.name=name; self.detail=detail; self.contacts=contacts; } return self; } +(KCContactGroup *)initWithName:(NSString *)name andDetail:(NSString *)detail andContacts:(NSMutableArray *)contacts{ KCContactGroup *group1=[[KCContactGroup alloc]initWithName:name andDetail:detail andContacts:contacts]; return group1; } @end
而後在viewDidLoad方法中建立一些模擬數據同時實現數據源協議方法:
KCMainViewController.m
// // KCMainViewController.m // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import "KCMainViewController.h" #import "KCContact.h" #import "KCContactGroup.h" @interface KCMainViewController ()<UITableViewDataSource>{ UITableView *_tableView; NSMutableArray *_contacts;//聯繫人模型 } @end @implementation KCMainViewController - (void)viewDidLoad { [super viewDidLoad]; //初始化數據 [self initData]; //建立一個分組樣式的UITableView _tableView=[[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped]; //設置數據源,注意必須實現對應的UITableViewDataSource協議 _tableView.dataSource=self; [self.view addSubview:_tableView]; } #pragma mark 加載數據 -(void)initData{ _contacts=[[NSMutableArray alloc]init]; KCContact *contact1=[KCContact initWithFirstName:@"Cui" andLastName:@"Kenshin" andPhoneNumber:@"18500131234"]; KCContact *contact2=[KCContact initWithFirstName:@"Cui" andLastName:@"Tom" andPhoneNumber:@"18500131237"]; KCContactGroup *group1=[KCContactGroup initWithName:@"C" andDetail:@"With names beginning with C" andContacts:[NSMutableArray arrayWithObjects:contact1,contact2, nil]]; [_contacts addObject:group1]; KCContact *contact3=[KCContact initWithFirstName:@"Lee" andLastName:@"Terry" andPhoneNumber:@"18500131238"]; KCContact *contact4=[KCContact initWithFirstName:@"Lee" andLastName:@"Jack" andPhoneNumber:@"18500131239"]; KCContact *contact5=[KCContact initWithFirstName:@"Lee" andLastName:@"Rose" andPhoneNumber:@"18500131240"]; KCContactGroup *group2=[KCContactGroup initWithName:@"L" andDetail:@"With names beginning with L" andContacts:[NSMutableArray arrayWithObjects:contact3,contact4,contact5, nil]]; [_contacts addObject:group2]; KCContact *contact6=[KCContact initWithFirstName:@"Sun" andLastName:@"Kaoru" andPhoneNumber:@"18500131235"]; KCContact *contact7=[KCContact initWithFirstName:@"Sun" andLastName:@"Rosa" andPhoneNumber:@"18500131236"]; KCContactGroup *group3=[KCContactGroup initWithName:@"S" andDetail:@"With names beginning with S" andContacts:[NSMutableArray arrayWithObjects:contact6,contact7, nil]]; [_contacts addObject:group3]; KCContact *contact8=[KCContact initWithFirstName:@"Wang" andLastName:@"Stephone" andPhoneNumber:@"18500131241"]; KCContact *contact9=[KCContact initWithFirstName:@"Wang" andLastName:@"Lucy" andPhoneNumber:@"18500131242"]; KCContact *contact10=[KCContact initWithFirstName:@"Wang" andLastName:@"Lily" andPhoneNumber:@"18500131243"]; KCContact *contact11=[KCContact initWithFirstName:@"Wang" andLastName:@"Emily" andPhoneNumber:@"18500131244"]; KCContact *contact12=[KCContact initWithFirstName:@"Wang" andLastName:@"Andy" andPhoneNumber:@"18500131245"]; KCContactGroup *group4=[KCContactGroup initWithName:@"W" andDetail:@"With names beginning with W" andContacts:[NSMutableArray arrayWithObjects:contact8,contact9,contact10,contact11,contact12, nil]]; [_contacts addObject:group4]; KCContact *contact13=[KCContact initWithFirstName:@"Zhang" andLastName:@"Joy" andPhoneNumber:@"18500131246"]; KCContact *contact14=[KCContact initWithFirstName:@"Zhang" andLastName:@"Vivan" andPhoneNumber:@"18500131247"]; KCContact *contact15=[KCContact initWithFirstName:@"Zhang" andLastName:@"Joyse" andPhoneNumber:@"18500131248"]; KCContactGroup *group5=[KCContactGroup initWithName:@"Z" andDetail:@"With names beginning with Z" andContacts:[NSMutableArray arrayWithObjects:contact13,contact14,contact15, nil]]; [_contacts addObject:group5]; } #pragma mark - 數據源方法 #pragma mark 返回分組數 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ NSLog(@"計算分組數"); return _contacts.count; } #pragma mark 返回每組行數 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ NSLog(@"計算每組(組%i)行數",section); KCContactGroup *group1=_contacts[section]; return group1.contacts.count; } #pragma mark返回每行的單元格 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //NSIndexPath是一個結構體,記錄了組和行信息 NSLog(@"生成單元格(組:%i,行%i)",indexPath.section,indexPath.row); KCContactGroup *group=_contacts[indexPath.section]; KCContact *contact=group.contacts[indexPath.row]; UITableViewCell *cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil]; cell.textLabel.text=[contact getName]; cell.detailTextLabel.text=contact.phoneNumber; return cell; } #pragma mark 返回每組頭標題名稱 -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ NSLog(@"生成組(組%i)名稱",section); KCContactGroup *group=_contacts[section]; return group.name; } #pragma mark 返回每組尾部說明 -(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{ NSLog(@"生成尾部(組%i)詳情",section); KCContactGroup *group=_contacts[section]; return group.detail; } @end
運行能夠看到以下效果:
你們在使用iPhone通信錄時會發現右側能夠按字母檢索,使用起來很方便,其實這個功能使用UITableView實現很簡單,只要實現數據源協議的一個方法,構建一個分組標題的數組便可實現。數組元素的內容和組標題內容未必徹底一致,UITableView是按照數組元素的索引和每組數據索引順序來定位的而不是按內容查找。
#pragma mark 返回每組標題索引 -(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{ NSLog(@"生成組索引"); NSMutableArray *indexs=[[NSMutableArray alloc]init]; for(KCContactGroup *group in _contacts){ [indexs addObject:group.name]; } return indexs; }
效果以下:
須要注意的是上面幾個重點方法的執行順序,請看下圖:
值得指出的是生成單元格的方法並非一次所有調用,而是隻會生產當前顯示在界面上的單元格,當用戶滾動操做時再顯示其餘單元格。
注意:隨着咱們的應用愈來愈複雜,可能常常須要調試程序,在iOS中默認狀況下不能定位到錯誤代碼行,咱們能夠經過以下設置讓程序定位到出錯代碼行:Show the Breakpoint navigator—Add Exception breakpoint。
上面咱們已經看到通信錄的簡單實現,可是咱們發現單元格高度、分組標題高度以及尾部說明的高度都須要調整,此時就須要使用代理方法。UITableView代理方法有不少,例如監聽單元格顯示週期、監聽單元格選擇編輯操做、設置是否高亮顯示單元格、設置行高等。
#pragma mark - 代理方法 #pragma mark 設置分組標題內容高度 -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ if(section==0){ return 50; } return 40; } #pragma mark 設置每行高度(每行高度能夠不同) -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 45; } #pragma mark 設置尾部說明內容高度 -(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ return 40; }
在iOS中點擊某聯繫我的就能夠呼叫這個聯繫人,這時就須要監聽點擊操做,這裏就不演示呼叫聯繫人操做了,咱們演示一下修改人員信息的操做。
KCMainViewContrller.m
// // KCMainViewController.m // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import "KCMainViewController.h" #import "KCContact.h" #import "KCContactGroup.h" @interface KCMainViewController ()<UITableViewDataSource,UITableViewDelegate,UIAlertViewDelegate>{ UITableView *_tableView; NSMutableArray *_contacts;//聯繫人模型 NSIndexPath *_selectedIndexPath;//當前選中的組和行 } @end @implementation KCMainViewController - (void)viewDidLoad { [super viewDidLoad]; //初始化數據 [self initData]; //建立一個分組樣式的UITableView _tableView=[[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped]; //設置數據源,注意必須實現對應的UITableViewDataSource協議 _tableView.dataSource=self; //設置代理 _tableView.delegate=self; [self.view addSubview:_tableView]; } #pragma mark 加載數據 -(void)initData{ _contacts=[[NSMutableArray alloc]init]; KCContact *contact1=[KCContact initWithFirstName:@"Cui" andLastName:@"Kenshin" andPhoneNumber:@"18500131234"]; KCContact *contact2=[KCContact initWithFirstName:@"Cui" andLastName:@"Tom" andPhoneNumber:@"18500131237"]; KCContactGroup *group1=[KCContactGroup initWithName:@"C" andDetail:@"With names beginning with C" andContacts:[NSMutableArray arrayWithObjects:contact1,contact2, nil]]; [_contacts addObject:group1]; KCContact *contact3=[KCContact initWithFirstName:@"Lee" andLastName:@"Terry" andPhoneNumber:@"18500131238"]; KCContact *contact4=[KCContact initWithFirstName:@"Lee" andLastName:@"Jack" andPhoneNumber:@"18500131239"]; KCContact *contact5=[KCContact initWithFirstName:@"Lee" andLastName:@"Rose" andPhoneNumber:@"18500131240"]; KCContactGroup *group2=[KCContactGroup initWithName:@"L" andDetail:@"With names beginning with L" andContacts:[NSMutableArray arrayWithObjects:contact3,contact4,contact5, nil]]; [_contacts addObject:group2]; KCContact *contact6=[KCContact initWithFirstName:@"Sun" andLastName:@"Kaoru" andPhoneNumber:@"18500131235"]; KCContact *contact7=[KCContact initWithFirstName:@"Sun" andLastName:@"Rosa" andPhoneNumber:@"18500131236"]; KCContactGroup *group3=[KCContactGroup initWithName:@"S" andDetail:@"With names beginning with S" andContacts:[NSMutableArray arrayWithObjects:contact6,contact7, nil]]; [_contacts addObject:group3]; KCContact *contact8=[KCContact initWithFirstName:@"Wang" andLastName:@"Stephone" andPhoneNumber:@"18500131241"]; KCContact *contact9=[KCContact initWithFirstName:@"Wang" andLastName:@"Lucy" andPhoneNumber:@"18500131242"]; KCContact *contact10=[KCContact initWithFirstName:@"Wang" andLastName:@"Lily" andPhoneNumber:@"18500131243"]; KCContact *contact11=[KCContact initWithFirstName:@"Wang" andLastName:@"Emily" andPhoneNumber:@"18500131244"]; KCContact *contact12=[KCContact initWithFirstName:@"Wang" andLastName:@"Andy" andPhoneNumber:@"18500131245"]; KCContactGroup *group4=[KCContactGroup initWithName:@"W" andDetail:@"With names beginning with W" andContacts:[NSMutableArray arrayWithObjects:contact8,contact9,contact10,contact11,contact12, nil]]; [_contacts addObject:group4]; KCContact *contact13=[KCContact initWithFirstName:@"Zhang" andLastName:@"Joy" andPhoneNumber:@"18500131246"]; KCContact *contact14=[KCContact initWithFirstName:@"Zhang" andLastName:@"Vivan" andPhoneNumber:@"18500131247"]; KCContact *contact15=[KCContact initWithFirstName:@"Zhang" andLastName:@"Joyse" andPhoneNumber:@"18500131248"]; KCContactGroup *group5=[KCContactGroup initWithName:@"Z" andDetail:@"With names beginning with Z" andContacts:[NSMutableArray arrayWithObjects:contact13,contact14,contact15, nil]]; [_contacts addObject:group5]; } #pragma mark - 數據源方法 #pragma mark 返回分組數 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ NSLog(@"計算分組數"); return _contacts.count; } #pragma mark 返回每組行數 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ NSLog(@"計算每組(組%i)行數",section); KCContactGroup *group1=_contacts[section]; return group1.contacts.count; } #pragma mark返回每行的單元格 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //NSIndexPath是一個對象,記錄了組和行信息 NSLog(@"生成單元格(組:%i,行%i)",indexPath.section,indexPath.row); KCContactGroup *group=_contacts[indexPath.section]; KCContact *contact=group.contacts[indexPath.row]; UITableViewCell *cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil]; cell.textLabel.text=[contact getName]; cell.detailTextLabel.text=contact.phoneNumber; return cell; } #pragma mark 返回每組頭標題名稱 -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ NSLog(@"生成組(組%i)名稱",section); KCContactGroup *group=_contacts[section]; return group.name; } #pragma mark 返回每組尾部說明 -(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{ NSLog(@"生成尾部(組%i)詳情",section); KCContactGroup *group=_contacts[section]; return group.detail; } #pragma mark 返回每組標題索引 -(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{ NSLog(@"生成組索引"); NSMutableArray *indexs=[[NSMutableArray alloc]init]; for(KCContactGroup *group in _contacts){ [indexs addObject:group.name]; } return indexs; } #pragma mark - 代理方法 #pragma mark 設置分組標題內容高度 -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ if(section==0){ return 50; } return 40; } #pragma mark 設置每行高度(每行高度能夠不同) -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 45; } #pragma mark 設置尾部說明內容高度 -(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ return 40; } #pragma mark 點擊行 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ _selectedIndexPath=indexPath; KCContactGroup *group=_contacts[indexPath.section]; KCContact *contact=group.contacts[indexPath.row]; //建立彈出窗口 UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"System Info" message:[contact getName] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil]; alert.alertViewStyle=UIAlertViewStylePlainTextInput; //設置窗口內容樣式 UITextField *textField= [alert textFieldAtIndex:0]; //取得文本框 textField.text=contact.phoneNumber; //設置文本框內容 [alert show]; //顯示窗口 } #pragma mark 窗口的代理方法,用戶保存數據 -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ //當點擊了第二個按鈕(OK) if (buttonIndex==1) { UITextField *textField= [alertView textFieldAtIndex:0]; //修改模型數據 KCContactGroup *group=_contacts[_selectedIndexPath.section]; KCContact *contact=group.contacts[_selectedIndexPath.row]; contact.phoneNumber=textField.text; //刷新表格 [_tableView reloadData]; } } #pragma mark 重寫狀態樣式方法 -(UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleLightContent; } @end
在上面的代碼中咱們經過修改模型來改變UI顯示,這種方式是經典的MVC應用,在後面的代碼中會常常看到。固然UI的刷新使用了UITableView的reloadData方法,該方法會從新調用數據源方法,包括計算分組、計算每一個分組的行數,生成單元格等刷新整個UITableView。固然這種方式在實際開發中是不可取的,咱們不可能由於修改了一我的的信息就刷新整個UITableViewView,此時咱們須要採用局部刷新。局部刷新使用起來很簡單,只須要調用UITableView的另一個方法:
#pragma mark 窗口的代理方法,用戶保存數據 -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ //當點擊了第二個按鈕(OK) if (buttonIndex==1) { UITextField *textField= [alertView textFieldAtIndex:0]; //修改模型數據 KCContactGroup *group=_contacts[_selectedIndexPath.section]; KCContact *contact=group.contacts[_selectedIndexPath.row]; contact.phoneNumber=textField.text; //刷新表格 NSArray *indexPaths=@[_selectedIndexPath];//須要局部刷新的單元格的組、行 [_tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationLeft];//後面的參數表明更新時的動畫 } }
前面已經說過UITableView中的單元格cell是在顯示到用戶可視區域後建立的,那麼若是用戶往下滾動就會繼續建立顯示在屏幕上的單元格,若是用戶向上滾動返回到查看過的內容時一樣會從新建立以前已經建立過的單元格。如此一來即便UITableView的內容不是太多,若是用戶反覆的上下滾動,內存也會瞬間飆升,更況且不少時候UITableView的內容是不少的(例如微博展現列表,基本向下滾動是沒有底限的)。
前面一節中咱們曾經提到過如何優化UIScrollView,當時就是利用有限的UIImageView動態切換其內容來儘量減小資源佔用。一樣的,在UITableView中也能夠採用相似的方式,只是這時咱們不是在滾動到指定位置後更改滾動的位置而是要將當前沒有顯示的Cell從新顯示在將要顯示的Cell的位置而後更新其內容。緣由就是UITableView中的Cell結構佈局多是不一樣的,經過從新定位是不可取的,而是須要重用已經再也不界面顯示的已建立過的Cell。
固然,聽起來這麼作比較複雜,其實實現起來很簡單,由於UITableView已經爲咱們實現了這種機制。在UITableView內部有一個緩存池,初始化時使用initWithStyle:(UITableViewCellStyle) reuseIdentifier:(NSString *)方法指定一個可重用標識,就能夠將這個cell放到緩存池。而後在使用時使用指定的標識去緩存池中取得對應的cell而後修改cell內容便可。
#pragma mark返回每行的單元格 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //NSIndexPath是一個對象,記錄了組和行信息 NSLog(@"生成單元格(組:%i,行%i)",indexPath.section,indexPath.row); KCContactGroup *group=_contacts[indexPath.section]; KCContact *contact=group.contacts[indexPath.row]; //因爲此方法調用十分頻繁,cell的標示聲明成靜態變量有利於性能優化 static NSString *cellIdentifier=@"UITableViewCellIdentifierKey1"; //首先根據標識去緩存池取 UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; //若是緩存池沒有到則從新建立並放到緩存池中 if(!cell){ cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier]; } cell.textLabel.text=[contact getName]; cell.detailTextLabel.text=contact.phoneNumber; NSLog(@"cell:%@",cell); return cell; }
上面的代碼中已經打印了cell的地址,若是你們運行測試上下滾動UITableView會發現滾動時建立的cell地址是初始化時已經建立的。
這裏再次給你們強調兩點:
UITableViewCell是構建一個UITableView的基礎,在UITableViewCell內部有一個UIView控件做爲其餘內容的容器,它上面有一個UIImageView和兩個UILabel,經過UITableViewCellStyle屬性能夠對其樣式進行控制。其結構以下:
有時候咱們會發現不少UITableViewCell右側能夠顯示不一樣的圖標,在iOS中稱之爲訪問器,點擊能夠觸發不一樣的事件,例如設置功能:
要設置這些圖標只須要設置UITableViewCell的accesoryType屬性,這是一個枚舉類型具體含義以下:
typedef NS_ENUM(NSInteger, UITableViewCellAccessoryType) { UITableViewCellAccessoryNone, // 不顯示任何圖標 UITableViewCellAccessoryDisclosureIndicator, // 跳轉指示圖標 UITableViewCellAccessoryDetailDisclosureButton, // 內容詳情圖標和跳轉指示圖標 UITableViewCellAccessoryCheckmark, // 勾選圖標 UITableViewCellAccessoryDetailButton NS_ENUM_AVAILABLE_IOS(7_0) // 內容詳情圖標 };
例如在最近通話中咱們一般設置爲詳情圖標,點擊能夠查看聯繫人詳情:
很明顯iOS設置中第一個accessoryType不在枚舉之列,右側的訪問器類型是UISwitch控件,那麼如何顯示自定義的訪問器呢?其實只要設置UITableViewCell的accessoryView便可,它支持任何UIView控件。假設咱們在通信錄每組第一行放一個UISwitch,同時切換時能夠輸出對應信息:
// // KCMainViewController.m // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import "KCMainViewController.h" #import "KCContact.h" #import "KCContactGroup.h" @interface KCMainViewController ()<UITableViewDataSource,UITableViewDelegate,UIAlertViewDelegate>{ UITableView *_tableView; NSMutableArray *_contacts;//聯繫人模型 NSIndexPath *_selectedIndexPath;//當前選中的組和行 } @end @implementation KCMainViewController - (void)viewDidLoad { [super viewDidLoad]; //初始化數據 [self initData]; //建立一個分組樣式的UITableView _tableView=[[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped]; //設置數據源,注意必須實現對應的UITableViewDataSource協議 _tableView.dataSource=self; //設置代理 _tableView.delegate=self; [self.view addSubview:_tableView]; } #pragma mark 加載數據 -(void)initData{ _contacts=[[NSMutableArray alloc]init]; KCContact *contact1=[KCContact initWithFirstName:@"Cui" andLastName:@"Kenshin" andPhoneNumber:@"18500131234"]; KCContact *contact2=[KCContact initWithFirstName:@"Cui" andLastName:@"Tom" andPhoneNumber:@"18500131237"]; KCContactGroup *group1=[KCContactGroup initWithName:@"C" andDetail:@"With names beginning with C" andContacts:[NSMutableArray arrayWithObjects:contact1,contact2, nil]]; [_contacts addObject:group1]; KCContact *contact3=[KCContact initWithFirstName:@"Lee" andLastName:@"Terry" andPhoneNumber:@"18500131238"]; KCContact *contact4=[KCContact initWithFirstName:@"Lee" andLastName:@"Jack" andPhoneNumber:@"18500131239"]; KCContact *contact5=[KCContact initWithFirstName:@"Lee" andLastName:@"Rose" andPhoneNumber:@"18500131240"]; KCContactGroup *group2=[KCContactGroup initWithName:@"L" andDetail:@"With names beginning with L" andContacts:[NSMutableArray arrayWithObjects:contact3,contact4,contact5, nil]]; [_contacts addObject:group2]; KCContact *contact6=[KCContact initWithFirstName:@"Sun" andLastName:@"Kaoru" andPhoneNumber:@"18500131235"]; KCContact *contact7=[KCContact initWithFirstName:@"Sun" andLastName:@"Rosa" andPhoneNumber:@"18500131236"]; KCContactGroup *group3=[KCContactGroup initWithName:@"S" andDetail:@"With names beginning with S" andContacts:[NSMutableArray arrayWithObjects:contact6,contact7, nil]]; [_contacts addObject:group3]; KCContact *contact8=[KCContact initWithFirstName:@"Wang" andLastName:@"Stephone" andPhoneNumber:@"18500131241"]; KCContact *contact9=[KCContact initWithFirstName:@"Wang" andLastName:@"Lucy" andPhoneNumber:@"18500131242"]; KCContact *contact10=[KCContact initWithFirstName:@"Wang" andLastName:@"Lily" andPhoneNumber:@"18500131243"]; KCContact *contact11=[KCContact initWithFirstName:@"Wang" andLastName:@"Emily" andPhoneNumber:@"18500131244"]; KCContact *contact12=[KCContact initWithFirstName:@"Wang" andLastName:@"Andy" andPhoneNumber:@"18500131245"]; KCContactGroup *group4=[KCContactGroup initWithName:@"W" andDetail:@"With names beginning with W" andContacts:[NSMutableArray arrayWithObjects:contact8,contact9,contact10,contact11,contact12, nil]]; [_contacts addObject:group4]; KCContact *contact13=[KCContact initWithFirstName:@"Zhang" andLastName:@"Joy" andPhoneNumber:@"18500131246"]; KCContact *contact14=[KCContact initWithFirstName:@"Zhang" andLastName:@"Vivan" andPhoneNumber:@"18500131247"]; KCContact *contact15=[KCContact initWithFirstName:@"Zhang" andLastName:@"Joyse" andPhoneNumber:@"18500131248"]; KCContactGroup *group5=[KCContactGroup initWithName:@"Z" andDetail:@"With names beginning with Z" andContacts:[NSMutableArray arrayWithObjects:contact13,contact14,contact15, nil]]; [_contacts addObject:group5]; } #pragma mark - 數據源方法 #pragma mark 返回分組數 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ NSLog(@"計算分組數"); return _contacts.count; } #pragma mark 返回每組行數 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ NSLog(@"計算每組(組%i)行數",section); KCContactGroup *group1=_contacts[section]; return group1.contacts.count; } #pragma mark返回每行的單元格 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //NSIndexPath是一個對象,記錄了組和行信息 NSLog(@"生成單元格(組:%i,行%i)",indexPath.section,indexPath.row); KCContactGroup *group=_contacts[indexPath.section]; KCContact *contact=group.contacts[indexPath.row]; //因爲此方法調用十分頻繁,cell的標示聲明成靜態變量有利於性能優化 static NSString *cellIdentifier=@"UITableViewCellIdentifierKey1"; static NSString *cellIdentifierForFirstRow=@"UITableViewCellIdentifierKeyWithSwitch"; //首先根據標示去緩存池取 UITableViewCell *cell; if (indexPath.row==0) { cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifierForFirstRow]; }else{ cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; } //若是緩存池沒有取到則從新建立並放到緩存池中 if(!cell){ if (indexPath.row==0) { cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierForFirstRow]; UISwitch *sw=[[UISwitch alloc]init]; [sw addTarget:self action:@selector(switchValueChange:) forControlEvents:UIControlEventValueChanged]; cell.accessoryView=sw; }else{ cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier]; cell.accessoryType=UITableViewCellAccessoryDetailButton; } } if(indexPath.row==0){ ((UISwitch *)cell.accessoryView).tag=indexPath.section; } cell.textLabel.text=[contact getName]; cell.detailTextLabel.text=contact.phoneNumber; NSLog(@"cell:%@",cell); return cell; } #pragma mark 返回每組頭標題名稱 -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ NSLog(@"生成組(組%i)名稱",section); KCContactGroup *group=_contacts[section]; return group.name; } #pragma mark 返回每組尾部說明 -(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{ NSLog(@"生成尾部(組%i)詳情",section); KCContactGroup *group=_contacts[section]; return group.detail; } #pragma mark 返回每組標題索引 -(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{ NSLog(@"生成組索引"); NSMutableArray *indexs=[[NSMutableArray alloc]init]; for(KCContactGroup *group in _contacts){ [indexs addObject:group.name]; } return indexs; } #pragma mark - 代理方法 #pragma mark 設置分組標題內容高度 -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ if(section==0){ return 50; } return 40; } #pragma mark 設置每行高度(每行高度能夠不同) -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 45; } #pragma mark 設置尾部說明內容高度 -(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ return 40; } #pragma mark 點擊行 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ _selectedIndexPath=indexPath; KCContactGroup *group=_contacts[indexPath.section]; KCContact *contact=group.contacts[indexPath.row]; //建立彈出窗口 UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"System Info" message:[contact getName] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil]; alert.alertViewStyle=UIAlertViewStylePlainTextInput; //設置窗口內容樣式 UITextField *textField= [alert textFieldAtIndex:0]; //取得文本框 textField.text=contact.phoneNumber; //設置文本框內容 [alert show]; //顯示窗口 } #pragma mark 窗口的代理方法,用戶保存數據 -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ //當點擊了第二個按鈕(OK) if (buttonIndex==1) { UITextField *textField= [alertView textFieldAtIndex:0]; //修改模型數據 KCContactGroup *group=_contacts[_selectedIndexPath.section]; KCContact *contact=group.contacts[_selectedIndexPath.row]; contact.phoneNumber=textField.text; //刷新表格 NSArray *indexPaths=@[_selectedIndexPath];//須要局部刷新的單元格的組、行 [_tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationLeft];//後面的參數代碼更新時的動畫 } } #pragma mark 重寫狀態樣式方法 -(UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleLightContent; } #pragma mark 切換開關轉化事件 -(void)switchValueChange:(UISwitch *)sw{ NSLog(@"section:%i,switch:%i",sw.tag, sw.on); } @end
最終運行效果:
注意:
雖然系統自帶的UITableViewCell已經夠強大了,可是不少時候這並不能知足咱們的需求。例如新浪微博的Cell就沒有那麼簡單:
沒錯,這個界面佈局也是UITableView實現的,其中的內容就是UITableViewCell,只是這個UITableViewCell是用戶自定義實現的。固然要實現上面的UITableViewCell三言兩語咱們是說不完的,這裏咱們實現一個簡化版本,界面原型以下:
咱們對具體控件進行拆分:
在這個界面中有2個UIImageView控件和4個UILabel,整個界面顯示效果相似於新浪微博的消息內容界面,可是又在新浪微博基礎上進行了精簡以致於利用現有知識可以順利開發出來。
在前面的內容中咱們的數據都是手動構建的,在實際開發中天然不會這麼作,這裏咱們不妨將微博數據存儲到plist文件中而後從plist文件讀取數據構建模型對象(實際開發微博固然須要進行網絡數據請求,這裏只是進行模擬就再也不演示網絡請求的內容)。假設plist文件內容以下:
接下來就定義一個KCStatusTableViewCell實現UITableViewCell,通常實現自定義UITableViewCell須要分爲兩步:第一初始化控件;第二設置數據,從新設置控件frame。緣由就是自定義Cell通常沒法固定高度,不少時候高度須要隨着內容改變。此外因爲在單元格內部是沒法控制單元格高度的,所以通常會定義一個高度屬性用於在UITableView的代理事件中設置每一個單元格高度。
1.首先看一下微博模型KCStatus,這個模型主要的方法就是根據plist字典內容生成微博對象:
KCStatus.h
// // KCStatus.h // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import <Foundation/Foundation.h> @interface KCStatus : NSObject #pragma mark - 屬性 @property (nonatomic,assign) long long Id;//微博id @property (nonatomic,copy) NSString *profileImageUrl;//頭像 @property (nonatomic,copy) NSString *userName;//發送用戶 @property (nonatomic,copy) NSString *mbtype;//會員類型 @property (nonatomic,copy) NSString *createdAt;//建立時間 @property (nonatomic,copy) NSString *source;//設備來源 @property (nonatomic,copy) NSString *text;//微博內容 #pragma mark - 方法 #pragma mark 根據字典初始化微博對象 -(KCStatus *)initWithDictionary:(NSDictionary *)dic; #pragma mark 初始化微博對象(靜態方法) +(KCStatus *)statusWithDictionary:(NSDictionary *)dic; @end
KCStatus.m
// // KCStatus.m // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import "KCStatus.h" @implementation KCStatus #pragma mark 根據字典初始化微博對象 -(KCStatus *)initWithDictionary:(NSDictionary *)dic{ if(self=[super init]){ self.Id=[dic[@"Id"] longLongValue]; self.profileImageUrl=dic[@"profileImageUrl"]; self.userName=dic[@"userName"]; self.mbtype=dic[@"mbtype"]; self.createdAt=dic[@"createdAt"]; self.source=dic[@"source"]; self.text=dic[@"text"]; } return self; } #pragma mark 初始化微博對象(靜態方法) +(KCStatus *)statusWithDictionary:(NSDictionary *)dic{ KCStatus *status=[[KCStatus alloc]initWithDictionary:dic]; return status; } -(NSString *)source{ return [NSString stringWithFormat:@"來自 %@",_source]; } @end
2.而後看一下自定義的Cell
KCStatusTableViewCell.h
// // KCStatusTableViewCell.h // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import <UIKit/UIKit.h> @class KCStatus; @interface KCStatusTableViewCell : UITableViewCell #pragma mark 微博對象 @property (nonatomic,strong) KCStatus *status; #pragma mark 單元格高度 @property (assign,nonatomic) CGFloat height; @end
KCStatusTableViewCell.m
// // KCStatusTableViewCell.m // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import "KCStatusTableViewCell.h" #import "KCStatus.h" #define KCColor(r,g,b) [UIColor colorWithHue:r/255.0 saturation:g/255.0 brightness:b/255.0 alpha:1] //顏色宏定義 #define kStatusTableViewCellControlSpacing 10 //控件間距 #define kStatusTableViewCellBackgroundColor KCColor(251,251,251) #define kStatusGrayColor KCColor(50,50,50) #define kStatusLightGrayColor KCColor(120,120,120) #define kStatusTableViewCellAvatarWidth 40 //頭像寬度 #define kStatusTableViewCellAvatarHeight kStatusTableViewCellAvatarWidth #define kStatusTableViewCellUserNameFontSize 14 #define kStatusTableViewCellMbTypeWidth 13 //會員圖標寬度 #define kStatusTableViewCellMbTypeHeight kStatusTableViewCellMbTypeWidth #define kStatusTableViewCellCreateAtFontSize 12 #define kStatusTableViewCellSourceFontSize 12 #define kStatusTableViewCellTextFontSize 14 @interface KCStatusTableViewCell(){ UIImageView *_avatar;//頭像 UIImageView *_mbType;//會員類型 UILabel *_userName; UILabel *_createAt; UILabel *_source; UILabel *_text; } @end @implementation KCStatusTableViewCell - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { [self initSubView]; } return self; } #pragma mark 初始化視圖 -(void)initSubView{ //頭像控件 _avatar=[[UIImageView alloc]init]; [self.contentView addSubview:_avatar]; //用戶名 _userName=[[UILabel alloc]init]; _userName.textColor=kStatusGrayColor; _userName.font=[UIFont systemFontOfSize:kStatusTableViewCellUserNameFontSize]; [self.contentView addSubview:_userName]; //會員類型 _mbType=[[UIImageView alloc]init]; [self.contentView addSubview:_mbType]; //日期 _createAt=[[UILabel alloc]init]; _createAt.textColor=kStatusLightGrayColor; _createAt.font=[UIFont systemFontOfSize:kStatusTableViewCellCreateAtFontSize]; [self.contentView addSubview:_createAt]; //設備 _source=[[UILabel alloc]init]; _source.textColor=kStatusLightGrayColor; _source.font=[UIFont systemFontOfSize:kStatusTableViewCellSourceFontSize]; [self.contentView addSubview:_source]; //內容 _text=[[UILabel alloc]init]; _text.textColor=kStatusGrayColor; _text.font=[UIFont systemFontOfSize:kStatusTableViewCellTextFontSize]; _text.numberOfLines=0; // _text.lineBreakMode=NSLineBreakByWordWrapping; [self.contentView addSubview:_text]; } #pragma mark 設置微博 -(void)setStatus:(KCStatus *)status{ //設置頭像大小和位置 CGFloat avatarX=10,avatarY=10; CGRect avatarRect=CGRectMake(avatarX, avatarY, kStatusTableViewCellAvatarWidth, kStatusTableViewCellAvatarHeight); _avatar.image=[UIImage imageNamed:status.profileImageUrl]; _avatar.frame=avatarRect; //設置會員圖標大小和位置 CGFloat userNameX= CGRectGetMaxX(_avatar.frame)+kStatusTableViewCellControlSpacing ; CGFloat userNameY=avatarY; //根據文本內容取得文本佔用空間大小 CGSize userNameSize=[status.userName sizeWithAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:kStatusTableViewCellUserNameFontSize]}]; CGRect userNameRect=CGRectMake(userNameX, userNameY, userNameSize.width,userNameSize.height); _userName.text=status.userName; _userName.frame=userNameRect; //設置會員圖標大小和位置 CGFloat mbTypeX=CGRectGetMaxX(_userName.frame)+kStatusTableViewCellControlSpacing; CGFloat mbTypeY=avatarY; CGRect mbTypeRect=CGRectMake(mbTypeX, mbTypeY, kStatusTableViewCellMbTypeWidth, kStatusTableViewCellMbTypeHeight); _mbType.image=[UIImage imageNamed:status.mbtype]; _mbType.frame=mbTypeRect; //設置發佈日期大小和位置 CGSize createAtSize=[status.createdAt sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:kStatusTableViewCellCreateAtFontSize]}]; CGFloat createAtX=userNameX; CGFloat createAtY=CGRectGetMaxY(_avatar.frame)-createAtSize.height; CGRect createAtRect=CGRectMake(createAtX, createAtY, createAtSize.width, createAtSize.height); _createAt.text=status.createdAt; _createAt.frame=createAtRect; //設置設備信息大小和位置 CGSize sourceSize=[status.source sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:kStatusTableViewCellSourceFontSize]}]; CGFloat sourceX=CGRectGetMaxX(_createAt.frame)+kStatusTableViewCellControlSpacing; CGFloat sourceY=createAtY; CGRect sourceRect=CGRectMake(sourceX, sourceY, sourceSize.width,sourceSize.height); _source.text=status.source; _source.frame=sourceRect; //設置微博內容大小和位置 CGFloat textX=avatarX; CGFloat textY=CGRectGetMaxY(_avatar.frame)+kStatusTableViewCellControlSpacing; CGFloat textWidth=self.frame.size.width-kStatusTableViewCellControlSpacing*2; CGSize textSize=[status.text boundingRectWithSize:CGSizeMake(textWidth, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:kStatusTableViewCellTextFontSize]} context:nil].size; CGRect textRect=CGRectMake(textX, textY, textSize.width, textSize.height); _text.text=status.text; _text.frame=textRect; _height=CGRectGetMaxY(_text.frame)+kStatusTableViewCellControlSpacing; } #pragma mark 重寫選擇事件,取消選中 -(void)setSelected:(BOOL)selected animated:(BOOL)animated{ } @end
這是咱們自定義Cell這個例子的核心,自定義Cell分爲兩個步驟:首先要進行各類控件的初始化工做,這個過程當中只要將控件放到Cell的View中同時設置控件顯示內容的格式(字體大小、顏色等)便可;而後在數據對象設置方法中進行各個控件的佈局(大小、位置)。在代碼中有幾點須要重點提示你們:
3.最後咱們看一下自定義Cell的使用過程:
KCStatusViewController.m
// // KCCutomCellViewController.m // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import "KCStatusCellViewController.h" #import "KCStatus.h" #import "KCStatusTableViewCell.h" @interface KCStatusCellViewController ()<UITableViewDataSource,UITableViewDelegate,UIAlertViewDelegate>{ UITableView *_tableView; NSMutableArray *_status; NSMutableArray *_statusCells;//存儲cell,用於計算高度 } @end @implementation KCStatusCellViewController - (void)viewDidLoad { [super viewDidLoad]; //初始化數據 [self initData]; //建立一個分組樣式的UITableView _tableView=[[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped]; //設置數據源,注意必須實現對應的UITableViewDataSource協議 _tableView.dataSource=self; //設置代理 _tableView.delegate=self; [self.view addSubview:_tableView]; } #pragma mark 加載數據 -(void)initData{ NSString *path=[[NSBundle mainBundle] pathForResource:@"StatusInfo" ofType:@"plist"]; NSArray *array=[NSArray arrayWithContentsOfFile:path]; _status=[[NSMutableArray alloc]init]; _statusCells=[[NSMutableArray alloc]init]; [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { [_status addObject:[KCStatus statusWithDictionary:obj]]; KCStatusTableViewCell *cell=[[KCStatusTableViewCell alloc]init]; [_statusCells addObject:cell]; }]; } #pragma mark - 數據源方法 #pragma mark 返回分組數 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } #pragma mark 返回每組行數 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return _status.count; } #pragma mark返回每行的單元格 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *cellIdentifier=@"UITableViewCellIdentifierKey1"; KCStatusTableViewCell *cell; cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if(!cell){ cell=[[KCStatusTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } //在此設置微博,以便從新佈局 KCStatus *status=_status[indexPath.row]; cell.status=status; return cell; } #pragma mark - 代理方法 #pragma mark 從新設置單元格高度 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ //KCStatusTableViewCell *cell=[tableView cellForRowAtIndexPath:indexPath]; KCStatusTableViewCell *cell= _statusCells[indexPath.row]; cell.status=_status[indexPath.row]; return cell.height; } #pragma mark 重寫狀態樣式方法 -(UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleLightContent; } @end
這個類中須要重點強調一下:Cell的高度須要從新設置(前面說過不管Cell內部設置多高都沒有用,須要從新設置),這裏採用的方法是首先建立對應的Cell,而後在- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;方法中設置微博數據計算高度通知UITableView。
最後咱們看一下運行的效果:
UITableView和UITableViewCell提供了強大的操做功能,這一節中會重點討論刪除、增長、排序等操做。爲了方便演示咱們仍是在以前的通信錄的基礎上演示,在此以前先來給視圖控制器添加一個工具條,在工具條左側放一個刪除按鈕,右側放一個添加按鈕:
#pragma mark 添加工具欄 -(void)addToolbar{ CGRect frame=self.view.frame; _toolbar=[[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, kContactToolbarHeight)]; // _toolbar.backgroundColor=[UIColor colorWithHue:246/255.0 saturation:246/255.0 brightness:246/255.0 alpha:1]; [self.view addSubview:_toolbar]; UIBarButtonItem *removeButton=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(remove)]; UIBarButtonItem *flexibleButton=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; UIBarButtonItem *addButton=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(add)]; NSArray *buttonArray=[NSArray arrayWithObjects:removeButton,flexibleButton,addButton, nil]; _toolbar.items=buttonArray; }
在UITableView中不管是刪除操做仍是添加操做都是經過修改UITableView的編輯狀態來改變的(除非你不用UITableView自帶的刪除功能)。在刪除按鈕中咱們設置UITableView的編輯狀態:
#pragma mark 刪除 -(void)remove{ //直接經過下面的方法設置編輯狀態沒有動畫 //_tableView.editing=!_tableView.isEditing; [_tableView setEditing:!_tableView.isEditing animated:true]; }
點擊刪除按鈕會在Cell的左側顯示刪除按鈕:
此時點擊左側刪除圖標右側出現刪除:
用過iOS的朋友都知道,通常這種Cell若是向左滑動右側就會出現刪除按鈕直接刪除就能夠了。其實實現這個功能只要實現代理-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;方法,只要實現了此方法向左滑動就會顯示刪除按鈕。只要點擊刪除按鈕這個方法就會調用,可是須要注意的是不管是刪除仍是添加都是執行這個方法,只是第二個參數類型不一樣。下面看一下具體的刪除實現:
#pragma mark 刪除操做 //實現了此方法向左滑動就會顯示刪除按鈕 -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ KCContactGroup *group =_contacts[indexPath.section]; KCContact *contact=group.contacts[indexPath.row]; if (editingStyle==UITableViewCellEditingStyleDelete) { [group.contacts removeObject:contact]; //考慮到性能這裏不建議使用reloadData //[tableView reloadData]; //使用下面的方法既能夠局部刷新又有動畫效果 [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom]; //若是當前組中沒有數據則移除組刷新整個表格 if (group.contacts.count==0) { [_contacts removeObject:group]; [tableView reloadData]; } } }
從這段代碼咱們再次看到了MVC的思想,要修改UI先修改數據。並且咱們看到了另外一個刷新表格的方法- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;,使用這個方法能夠再刪除以後刷新對應的單元格。效果以下:
添加和刪除操做都是設置UITableView的編輯狀態,具體是添加仍是刪除須要根據代理方法-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;的返回值來肯定。所以這裏咱們定義一個變量來記錄點擊了哪一個按鈕,根據點擊按鈕的不一樣在這個方法中返回不一樣的值。
#pragma mark 取得當前操做狀態,根據不一樣的狀態左側出現不一樣的操做按鈕 -(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{ if (_isInsert) { return UITableViewCellEditingStyleInsert; } return UITableViewCellEditingStyleDelete; }
#pragma mark 編輯操做(刪除或添加) //實現了此方法向左滑動就會顯示刪除(或添加)圖標 -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ KCContactGroup *group =_contacts[indexPath.section]; KCContact *contact=group.contacts[indexPath.row]; if (editingStyle==UITableViewCellEditingStyleDelete) { [group.contacts removeObject:contact]; //考慮到性能這裏不建議使用reloadData //[tableView reloadData]; //使用下面的方法既能夠局部刷新又有動畫效果 [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom]; //若是當前組中沒有數據則移除組刷新整個表格 if (group.contacts.count==0) { [_contacts removeObject:group]; [tableView reloadData]; } }else if(editingStyle==UITableViewCellEditingStyleInsert){ KCContact *newContact=[[KCContact alloc]init]; newContact.firstName=@"first"; newContact.lastName=@"last"; newContact.phoneNumber=@"12345678901"; [group.contacts insertObject:newContact atIndex:indexPath.row]; [tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];//注意這裏沒有使用reladData刷新 } }
運行效果:
只要實現-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;代理方法當UITableView處於編輯狀態時就能夠排序。
#pragma mark 排序 //只要實現這個方法在編輯狀態右側就有排序圖標 -(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{ KCContactGroup *sourceGroup =_contacts[sourceIndexPath.section]; KCContact *sourceContact=sourceGroup.contacts[sourceIndexPath.row]; KCContactGroup *destinationGroup =_contacts[destinationIndexPath.section]; [sourceGroup.contacts removeObject:sourceContact]; if(sourceGroup.contacts.count==0){ [_contacts removeObject:sourceGroup]; [tableView reloadData]; } [destinationGroup.contacts insertObject:sourceContact atIndex:destinationIndexPath.row]; }
運行效果:
最後給你們附上上面幾種操做的完整代碼:
// // KCContactViewController.m // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import "KCContactViewController.h" #import "KCContact.h" #import "KCContactGroup.h" #define kContactToolbarHeight 44 @interface KCContactViewController ()<UITableViewDataSource,UITableViewDelegate,UIAlertViewDelegate>{ UITableView *_tableView; UIToolbar *_toolbar; NSMutableArray *_contacts;//聯繫人模型 NSIndexPath *_selectedIndexPath;//當前選中的組和行 BOOL _isInsert;//記錄是點擊了插入仍是刪除按鈕 } @end @implementation KCContactViewController - (void)viewDidLoad { [super viewDidLoad]; //初始化數據 [self initData]; //建立一個分組樣式的UITableView _tableView=[[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped]; _tableView.contentInset=UIEdgeInsetsMake(kContactToolbarHeight, 0, 0, 0); [self.view addSubview:_tableView]; //添加工具欄 [self addToolbar]; //設置數據源,注意必須實現對應的UITableViewDataSource協議 _tableView.dataSource=self; //設置代理 _tableView.delegate=self; } #pragma mark 加載數據 -(void)initData{ _contacts=[[NSMutableArray alloc]init]; KCContact *contact1=[KCContact initWithFirstName:@"Cui" andLastName:@"Kenshin" andPhoneNumber:@"18500131234"]; KCContact *contact2=[KCContact initWithFirstName:@"Cui" andLastName:@"Tom" andPhoneNumber:@"18500131237"]; KCContactGroup *group1=[KCContactGroup initWithName:@"C" andDetail:@"With names beginning with C" andContacts:[NSMutableArray arrayWithObjects:contact1,contact2, nil]]; [_contacts addObject:group1]; KCContact *contact3=[KCContact initWithFirstName:@"Lee" andLastName:@"Terry" andPhoneNumber:@"18500131238"]; KCContact *contact4=[KCContact initWithFirstName:@"Lee" andLastName:@"Jack" andPhoneNumber:@"18500131239"]; KCContact *contact5=[KCContact initWithFirstName:@"Lee" andLastName:@"Rose" andPhoneNumber:@"18500131240"]; KCContactGroup *group2=[KCContactGroup initWithName:@"L" andDetail:@"With names beginning with L" andContacts:[NSMutableArray arrayWithObjects:contact3,contact4,contact5, nil]]; [_contacts addObject:group2]; KCContact *contact6=[KCContact initWithFirstName:@"Sun" andLastName:@"Kaoru" andPhoneNumber:@"18500131235"]; KCContact *contact7=[KCContact initWithFirstName:@"Sun" andLastName:@"Rosa" andPhoneNumber:@"18500131236"]; KCContactGroup *group3=[KCContactGroup initWithName:@"S" andDetail:@"With names beginning with S" andContacts:[NSMutableArray arrayWithObjects:contact6,contact7, nil]]; [_contacts addObject:group3]; KCContact *contact8=[KCContact initWithFirstName:@"Wang" andLastName:@"Stephone" andPhoneNumber:@"18500131241"]; KCContact *contact9=[KCContact initWithFirstName:@"Wang" andLastName:@"Lucy" andPhoneNumber:@"18500131242"]; KCContact *contact10=[KCContact initWithFirstName:@"Wang" andLastName:@"Lily" andPhoneNumber:@"18500131243"]; KCContact *contact11=[KCContact initWithFirstName:@"Wang" andLastName:@"Emily" andPhoneNumber:@"18500131244"]; KCContact *contact12=[KCContact initWithFirstName:@"Wang" andLastName:@"Andy" andPhoneNumber:@"18500131245"]; KCContactGroup *group4=[KCContactGroup initWithName:@"W" andDetail:@"With names beginning with W" andContacts:[NSMutableArray arrayWithObjects:contact8,contact9,contact10,contact11,contact12, nil]]; [_contacts addObject:group4]; KCContact *contact13=[KCContact initWithFirstName:@"Zhang" andLastName:@"Joy" andPhoneNumber:@"18500131246"]; KCContact *contact14=[KCContact initWithFirstName:@"Zhang" andLastName:@"Vivan" andPhoneNumber:@"18500131247"]; KCContact *contact15=[KCContact initWithFirstName:@"Zhang" andLastName:@"Joyse" andPhoneNumber:@"18500131248"]; KCContactGroup *group5=[KCContactGroup initWithName:@"Z" andDetail:@"With names beginning with Z" andContacts:[NSMutableArray arrayWithObjects:contact13,contact14,contact15, nil]]; [_contacts addObject:group5]; } #pragma mark 添加工具欄 -(void)addToolbar{ CGRect frame=self.view.frame; _toolbar=[[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, kContactToolbarHeight)]; // _toolbar.backgroundColor=[UIColor colorWithHue:246/255.0 saturation:246/255.0 brightness:246/255.0 alpha:1]; [self.view addSubview:_toolbar]; UIBarButtonItem *removeButton=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(remove)]; UIBarButtonItem *flexibleButton=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; UIBarButtonItem *addButton=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(add)]; NSArray *buttonArray=[NSArray arrayWithObjects:removeButton,flexibleButton,addButton, nil]; _toolbar.items=buttonArray; } #pragma mark 刪除 -(void)remove{ //直接經過下面的方法設置編輯狀態沒有動畫 //_tableView.editing=!_tableView.isEditing; _isInsert=false; [_tableView setEditing:!_tableView.isEditing animated:true]; } #pragma mark 添加 -(void)add{ _isInsert=true; [_tableView setEditing:!_tableView.isEditing animated:true]; } #pragma mark - 數據源方法 #pragma mark 返回分組數 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return _contacts.count; } #pragma mark 返回每組行數 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ KCContactGroup *group1=_contacts[section]; return group1.contacts.count; } #pragma mark返回每行的單元格 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //NSIndexPath是一個對象,記錄了組和行信息 KCContactGroup *group=_contacts[indexPath.section]; KCContact *contact=group.contacts[indexPath.row]; static NSString *cellIdentifier=@"UITableViewCellIdentifierKey1"; //首先根據標識去緩存池取 UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; //若是緩存池沒有取到則從新建立並放到緩存池中 if(!cell){ cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier]; } cell.textLabel.text=[contact getName]; cell.detailTextLabel.text=contact.phoneNumber; return cell; } #pragma mark - 代理方法 #pragma mark 設置分組標題 -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ KCContactGroup *group=_contacts[section]; return group.name; } #pragma mark 編輯操做(刪除或添加) //實現了此方法向左滑動就會顯示刪除(或添加)圖標 -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ KCContactGroup *group =_contacts[indexPath.section]; KCContact *contact=group.contacts[indexPath.row]; if (editingStyle==UITableViewCellEditingStyleDelete) { [group.contacts removeObject:contact]; //考慮到性能這裏不建議使用reloadData //[tableView reloadData]; //使用下面的方法既能夠局部刷新又有動畫效果 [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom]; //若是當前組中沒有數據則移除組刷新整個表格 if (group.contacts.count==0) { [_contacts removeObject:group]; [tableView reloadData]; } }else if(editingStyle==UITableViewCellEditingStyleInsert){ KCContact *newContact=[[KCContact alloc]init]; newContact.firstName=@"first"; newContact.lastName=@"last"; newContact.phoneNumber=@"12345678901"; [group.contacts insertObject:newContact atIndex:indexPath.row]; [tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];//注意這裏沒有使用reladData刷新 } } #pragma mark 排序 //只要實現這個方法在編輯狀態右側就有排序圖標 -(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{ KCContactGroup *sourceGroup =_contacts[sourceIndexPath.section]; KCContact *sourceContact=sourceGroup.contacts[sourceIndexPath.row]; KCContactGroup *destinationGroup =_contacts[destinationIndexPath.section]; [sourceGroup.contacts removeObject:sourceContact]; [destinationGroup.contacts insertObject:sourceContact atIndex:destinationIndexPath.row]; if(sourceGroup.contacts.count==0){ [_contacts removeObject:sourceGroup]; [tableView reloadData]; } } #pragma mark 取得當前操做狀態,根據不一樣的狀態左側出現不一樣的操做按鈕 -(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{ if (_isInsert) { return UITableViewCellEditingStyleInsert; } return UITableViewCellEditingStyleDelete; } #pragma mark 重寫狀態樣式方法 -(UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleLightContent; } @end
經過前面的演示這裏簡單總結一些UITableView的刷新方法:
- (void)reloadData;刷新整個表格。
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);刷新指定的分組和行。
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);刷新指定的分組。
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;刪除時刷新指定的行數據。
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;添加時刷新指定的行數據。
不少時候一個UIViewController中只有一個UITableView,所以蘋果官方爲了方便你們開發直接提供了一個UITableViewController,這個控制器 UITableViewController實現了UITableView數據源和代理協議,內部定義了一個tableView屬性供外部訪問,同時自動鋪滿整個屏幕、自動伸縮以方便咱們的開發。固然UITableViewController也並非簡單的幫咱們定義完UITableView而且設置了數據源、代理而已,它還有其餘強大的功能,例如刷新控件、滾動過程當中固定分組標題等。
有時候一個表格中的數據特別多,檢索起來就顯得麻煩,這個時候能夠實現一個搜索功能幫助用戶查找數據,其實搜索的原理很簡單:修改模型、刷新表格。下面使用UITableViewController簡單演示一下這個功能:
// // KCContactTableViewController.m // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import "KCContactTableViewController.h" #import "KCContact.h" #import "KCContactGroup.h" #define kSearchbarHeight 44 @interface KCContactTableViewController ()<UISearchBarDelegate>{ UITableView *_tableView; UISearchBar *_searchBar; //UISearchDisplayController *_searchDisplayController; NSMutableArray *_contacts;//聯繫人模型 NSMutableArray *_searchContacts;//符合條件的搜索聯繫人 BOOL _isSearching; } @end @implementation KCContactTableViewController - (void)viewDidLoad { [super viewDidLoad]; //初始化數據 [self initData]; //添加搜索框 [self addSearchBar]; } #pragma mark - 數據源方法 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { if (_isSearching) { return 1; } return _contacts.count;; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (_isSearching) { return _searchContacts.count; } KCContactGroup *group1=_contacts[section]; return group1.contacts.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { KCContact *contact=nil; if (_isSearching) { contact=_searchContacts[indexPath.row]; }else{ KCContactGroup *group=_contacts[indexPath.section]; contact=group.contacts[indexPath.row]; } static NSString *cellIdentifier=@"UITableViewCellIdentifierKey1"; //首先根據標識去緩存池取 UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; //若是緩存池沒有取到則從新建立並放到緩存池中 if(!cell){ cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier]; } cell.textLabel.text=[contact getName]; cell.detailTextLabel.text=contact.phoneNumber; return cell; } #pragma mark - 代理方法 #pragma mark 設置分組標題 -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ KCContactGroup *group=_contacts[section]; return group.name; } #pragma mark - 搜索框代理 #pragma mark 取消搜索 -(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{ _isSearching=NO; _searchBar.text=@""; [self.tableView reloadData]; } #pragma mark 輸入搜索關鍵字 -(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{ if([_searchBar.text isEqual:@""]){ _isSearching=NO; [self.tableView reloadData]; return; } [self searchDataWithKeyWord:_searchBar.text]; } #pragma mark 點擊虛擬鍵盤上的搜索時 -(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{ [self searchDataWithKeyWord:_searchBar.text]; [_searchBar resignFirstResponder];//放棄第一響應者對象,關閉虛擬鍵盤 } #pragma mark 重寫狀態樣式方法 -(UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleLightContent; } #pragma mark 加載數據 -(void)initData{ _contacts=[[NSMutableArray alloc]init]; KCContact *contact1=[KCContact initWithFirstName:@"Cui" andLastName:@"Kenshin" andPhoneNumber:@"18500131234"]; KCContact *contact2=[KCContact initWithFirstName:@"Cui" andLastName:@"Tom" andPhoneNumber:@"18500131237"]; KCContactGroup *group1=[KCContactGroup initWithName:@"C" andDetail:@"With names beginning with C" andContacts:[NSMutableArray arrayWithObjects:contact1,contact2, nil]]; [_contacts addObject:group1]; KCContact *contact3=[KCContact initWithFirstName:@"Lee" andLastName:@"Terry" andPhoneNumber:@"18500131238"]; KCContact *contact4=[KCContact initWithFirstName:@"Lee" andLastName:@"Jack" andPhoneNumber:@"18500131239"]; KCContact *contact5=[KCContact initWithFirstName:@"Lee" andLastName:@"Rose" andPhoneNumber:@"18500131240"]; KCContactGroup *group2=[KCContactGroup initWithName:@"L" andDetail:@"With names beginning with L" andContacts:[NSMutableArray arrayWithObjects:contact3,contact4,contact5, nil]]; [_contacts addObject:group2]; KCContact *contact6=[KCContact initWithFirstName:@"Sun" andLastName:@"Kaoru" andPhoneNumber:@"18500131235"]; KCContact *contact7=[KCContact initWithFirstName:@"Sun" andLastName:@"Rosa" andPhoneNumber:@"18500131236"]; KCContactGroup *group3=[KCContactGroup initWithName:@"S" andDetail:@"With names beginning with S" andContacts:[NSMutableArray arrayWithObjects:contact6,contact7, nil]]; [_contacts addObject:group3]; KCContact *contact8=[KCContact initWithFirstName:@"Wang" andLastName:@"Stephone" andPhoneNumber:@"18500131241"]; KCContact *contact9=[KCContact initWithFirstName:@"Wang" andLastName:@"Lucy" andPhoneNumber:@"18500131242"]; KCContact *contact10=[KCContact initWithFirstName:@"Wang" andLastName:@"Lily" andPhoneNumber:@"18500131243"]; KCContact *contact11=[KCContact initWithFirstName:@"Wang" andLastName:@"Emily" andPhoneNumber:@"18500131244"]; KCContact *contact12=[KCContact initWithFirstName:@"Wang" andLastName:@"Andy" andPhoneNumber:@"18500131245"]; KCContactGroup *group4=[KCContactGroup initWithName:@"W" andDetail:@"With names beginning with W" andContacts:[NSMutableArray arrayWithObjects:contact8,contact9,contact10,contact11,contact12, nil]]; [_contacts addObject:group4]; KCContact *contact13=[KCContact initWithFirstName:@"Zhang" andLastName:@"Joy" andPhoneNumber:@"18500131246"]; KCContact *contact14=[KCContact initWithFirstName:@"Zhang" andLastName:@"Vivan" andPhoneNumber:@"18500131247"]; KCContact *contact15=[KCContact initWithFirstName:@"Zhang" andLastName:@"Joyse" andPhoneNumber:@"18500131248"]; KCContactGroup *group5=[KCContactGroup initWithName:@"Z" andDetail:@"With names beginning with Z" andContacts:[NSMutableArray arrayWithObjects:contact13,contact14,contact15, nil]]; [_contacts addObject:group5]; } #pragma mark 搜索造成新數據 -(void)searchDataWithKeyWord:(NSString *)keyWord{ _isSearching=YES; _searchContacts=[NSMutableArray array]; [_contacts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { KCContactGroup *group=obj; [group.contacts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { KCContact *contact=obj; if ([contact.firstName.uppercaseString containsString:keyWord.uppercaseString]||[contact.lastName.uppercaseString containsString:keyWord.uppercaseString]||[contact.phoneNumber containsString:keyWord]) { [_searchContacts addObject:contact]; } }]; }]; //刷新表格 [self.tableView reloadData]; } #pragma mark 添加搜索欄 -(void)addSearchBar{ CGRect searchBarRect=CGRectMake(0, 0, self.view.frame.size.width, kSearchbarHeight); _searchBar=[[UISearchBar alloc]initWithFrame:searchBarRect]; _searchBar.placeholder=@"Please input key word..."; //_searchBar.keyboardType=UIKeyboardTypeAlphabet;//鍵盤類型 //_searchBar.autocorrectionType=UITextAutocorrectionTypeNo;//自動糾錯類型 //_searchBar.autocapitalizationType=UITextAutocapitalizationTypeNone;//哪一次shitf被自動按下 _searchBar.showsCancelButton=YES;//顯示取消按鈕 //添加搜索框到頁眉位置 _searchBar.delegate=self; self.tableView.tableHeaderView=_searchBar; } @end
運行效果:
在上面的搜索中除了使用一個_contacts變量去保存聯繫人數據還專門定義了一個_searchContact變量用於保存搜索的結果。在輸入搜索關鍵字時咱們刷新了表格,此時會調用表格的數據源方法,在這個方法中咱們根據定義的搜索狀態去決定顯示原始數據仍是搜索結果。
咱們發現每次搜索完後都須要手動刷新表格來顯示搜索結果,並且當沒有搜索關鍵字的時候還須要將當前的tableView從新設置爲初始狀態。也就是這個過程當中咱們要用一個tableView顯示兩種狀態的不一樣數據,天然會提升程序邏輯複雜度。爲了簡化這個過程,咱們可使用UISearchDisplayController,UISearchDisplayController內部也有一個UITableView類型的對象searchResultsTableView,若是咱們設置它的數據源代理爲當前控制器,那麼它徹底能夠像UITableView同樣加載數據。同時它自己也有搜索監聽的方法,咱們沒必要在監聽UISearchBar輸入內容,直接使用它的方法便可自動刷新其內部表格。爲了和前面的方法對比在下面的代碼中沒有直接刪除原來的方式而是註釋了對應代碼你們能夠對照學習:
// // KCContactTableViewController.m // UITableView // // Created by Kenshin Cui on 14-3-1. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import "KCContactTableViewControllerWithUISearchDisplayController.h" #import "KCContact.h" #import "KCContactGroup.h" #define kSearchbarHeight 44 @interface KCContactTableViewControllerWithUISearchDisplayController ()<UISearchBarDelegate,UISearchDisplayDelegate>{ UITableView *_tableView; UISearchBar *_searchBar; UISearchDisplayController *_searchDisplayController; NSMutableArray *_contacts;//聯繫人模型 NSMutableArray *_searchContacts;//符合條件的搜索聯繫人 //BOOL _isSearching; } @end @implementation KCContactTableViewControllerWithUISearchDisplayController - (void)viewDidLoad { [super viewDidLoad]; //初始化數據 [self initData]; //添加搜索框 [self addSearchBar]; } #pragma mark - 數據源方法 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // if (_isSearching) { // return 1; // } //若是當前是UISearchDisplayController內部的tableView則不分組 if (tableView==self.searchDisplayController.searchResultsTableView) { return 1; } return _contacts.count;; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // if (_isSearching) { // return _searchContacts.count; // } //若是當前是UISearchDisplayController內部的tableView則使用搜索數據 if (tableView==self.searchDisplayController.searchResultsTableView) { return _searchContacts.count; } KCContactGroup *group1=_contacts[section]; return group1.contacts.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { KCContact *contact=nil; // if (_isSearching) { // contact=_searchContacts[indexPath.row]; // }else{ // KCContactGroup *group=_contacts[indexPath.section]; // contact=group.contacts[indexPath.row]; // } //若是當前是UISearchDisplayController內部的tableView則使用搜索數據 if (tableView==self.searchDisplayController.searchResultsTableView) { contact=_searchContacts[indexPath.row]; }else{ KCContactGroup *group=_contacts[indexPath.section]; contact=group.contacts[indexPath.row]; } static NSString *cellIdentifier=@"UITableViewCellIdentifierKey1"; //首先根據標識去緩存池取 UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; //若是緩存池沒有取到則從新建立並放到緩存池中 if(!cell){ cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier]; } cell.textLabel.text=[contact getName]; cell.detailTextLabel.text=contact.phoneNumber; return cell; } #pragma mark - 代理方法 #pragma mark 設置分組標題 -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ if (tableView==self.searchDisplayController.searchResultsTableView) { return @"搜索結果"; } KCContactGroup *group=_contacts[section]; return group.name; } #pragma mark 選中以前 -(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [_searchBar resignFirstResponder];//退出鍵盤 return indexPath; } #pragma mark - 搜索框代理 //#pragma mark 取消搜索 //-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{ // //_isSearching=NO; // _searchBar.text=@""; // //[self.tableView reloadData]; // [_searchBar resignFirstResponder]; //} // //#pragma mark 輸入搜索關鍵字 //-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{ // if([_searchBar.text isEqual:@""]){ // //_isSearching=NO; // //[self.tableView reloadData]; // return; // } // [self searchDataWithKeyWord:_searchBar.text]; //} //#pragma mark 點擊虛擬鍵盤上的搜索時 //-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{ // // [self searchDataWithKeyWord:_searchBar.text]; // // [_searchBar resignFirstResponder];//放棄第一響應者對象,關閉虛擬鍵盤 //} #pragma mark - UISearchDisplayController代理方法 -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString{ [self searchDataWithKeyWord:searchString]; return YES; } #pragma mark 重寫狀態樣式方法 -(UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleLightContent; } #pragma mark 加載數據 -(void)initData{ _contacts=[[NSMutableArray alloc]init]; KCContact *contact1=[KCContact initWithFirstName:@"Cui" andLastName:@"Kenshin" andPhoneNumber:@"18500131234"]; KCContact *contact2=[KCContact initWithFirstName:@"Cui" andLastName:@"Tom" andPhoneNumber:@"18500131237"]; KCContactGroup *group1=[KCContactGroup initWithName:@"C" andDetail:@"With names beginning with C" andContacts:[NSMutableArray arrayWithObjects:contact1,contact2, nil]]; [_contacts addObject:group1]; KCContact *contact3=[KCContact initWithFirstName:@"Lee" andLastName:@"Terry" andPhoneNumber:@"18500131238"]; KCContact *contact4=[KCContact initWithFirstName:@"Lee" andLastName:@"Jack" andPhoneNumber:@"18500131239"]; KCContact *contact5=[KCContact initWithFirstName:@"Lee" andLastName:@"Rose" andPhoneNumber:@"18500131240"]; KCContactGroup *group2=[KCContactGroup initWithName:@"L" andDetail:@"With names beginning with L" andContacts:[NSMutableArray arrayWithObjects:contact3,contact4,contact5, nil]]; [_contacts addObject:group2]; KCContact *contact6=[KCContact initWithFirstName:@"Sun" andLastName:@"Kaoru" andPhoneNumber:@"18500131235"]; KCContact *contact7=[KCContact initWithFirstName:@"Sun" andLastName:@"Rosa" andPhoneNumber:@"18500131236"]; KCContactGroup *group3=[KCContactGroup initWithName:@"S" andDetail:@"With names beginning with S" andContacts:[NSMutableArray arrayWithObjects:contact6,contact7, nil]]; [_contacts addObject:group3]; KCContact *contact8=[KCContact initWithFirstName:@"Wang" andLastName:@"Stephone" andPhoneNumber:@"18500131241"]; KCContact *contact9=[KCContact initWithFirstName:@"Wang" andLastName:@"Lucy" andPhoneNumber:@"18500131242"]; KCContact *contact10=[KCContact initWithFirstName:@"Wang" andLastName:@"Lily" andPhoneNumber:@"18500131243"]; KCContact *contact11=[KCContact initWithFirstName:@"Wang" andLastName:@"Emily" andPhoneNumber:@"18500131244"]; KCContact *contact12=[KCContact initWithFirstName:@"Wang" andLastName:@"Andy" andPhoneNumber:@"18500131245"]; KCContactGroup *group4=[KCContactGroup initWithName:@"W" andDetail:@"With names beginning with W" andContacts:[NSMutableArray arrayWithObjects:contact8,contact9,contact10,contact11,contact12, nil]]; [_contacts addObject:group4]; KCContact *contact13=[KCContact initWithFirstName:@"Zhang" andLastName:@"Joy" andPhoneNumber:@"18500131246"]; KCContact *contact14=[KCContact initWithFirstName:@"Zhang" andLastName:@"Vivan" andPhoneNumber:@"18500131247"]; KCContact *contact15=[KCContact initWithFirstName:@"Zhang" andLastName:@"Joyse" andPhoneNumber:@"18500131248"]; KCContactGroup *group5=[KCContactGroup initWithName:@"Z" andDetail:@"With names beginning with Z" andContacts:[NSMutableArray arrayWithObjects:contact13,contact14,contact15, nil]]; [_contacts addObject:group5]; } #pragma mark 搜索造成新數據 -(void)searchDataWithKeyWord:(NSString *)keyWord{ //_isSearching=YES; _searchContacts=[NSMutableArray array]; [_contacts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { KCContactGroup *group=obj; [group.contacts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { KCContact *contact=obj; if ([contact.firstName.uppercaseString containsString:keyWord.uppercaseString]||[contact.lastName.uppercaseString containsString:keyWord.uppercaseString]||[contact.phoneNumber containsString:keyWord]) { [_searchContacts addObject:contact]; } }]; }]; //刷新表格 //[self.tableView reloadData]; } #pragma mark 添加搜索欄 -(void)addSearchBar{ _searchBar=[[UISearchBar alloc]init]; [_searchBar sizeToFit];//大小自適應容器 _searchBar.placeholder=@"Please input key word..."; _searchBar.autocapitalizationType=UITextAutocapitalizationTypeNone; _searchBar.showsCancelButton=YES;//顯示取消按鈕 //添加搜索框到頁眉位置 _searchBar.delegate=self; self.tableView.tableHeaderView=_searchBar; _searchDisplayController=[[UISearchDisplayController alloc]initWithSearchBar:_searchBar contentsController:self]; _searchDisplayController.delegate=self; _searchDisplayController.searchResultsDataSource=self; _searchDisplayController.searchResultsDelegate=self; [_searchDisplayController setActive:NO animated:YES]; } @end
運行效果:
注意若是使用Storyboard或xib方式建立上述代碼則無需定義UISearchDisplayController成員變量,由於每一個UIViewController中已經有一個searchDisplayController對象。
經過UITableView的學習相信你們對於iOS的MVC已經有一個大體的瞭解,這裏簡單的分析一下iOS中MVC模式的設計方式。在iOS中多數數據源視圖控件(View)都有一個dataSource屬性用於和控制器(Controller)交互,而數據來源咱們通常會以數據模型(Model)的形式進行定義,View不直接和模型交互,而是經過Controller間接讀取數據。
就拿前面的聯繫人應用舉例,UITableView做爲視圖(View)並不能直接訪問模型Contact,它要顯示聯繫人信息只能經過控制器(Controller)來提供數據源方法。一樣的控制器自己就擁有視圖控件,能夠操做視圖,也就是說視圖和控制器之間能夠互相訪問。而模型既不能訪問視圖也不能訪問控制器。具體依賴關係以下圖:
UIWebView是iOS sdk中一個最經常使用的控件。是內置的瀏覽器控件,咱們能夠用它來瀏覽網頁、打開文檔等等。這篇文章我將使用這個控件,作一個簡易的瀏覽器。以下圖:
咱們建立一個Window-based Application程序命名爲:UIWebViewDemo
UIWebView的loadRequest能夠用來加載一個url地址,它須要一個NSURLRequest參數。咱們定義一個方法用來加載url。在UIWebViewDemoViewController中定義下面方法:
- (void)loadWebPageWithString:(NSString*)urlString
{
NSURL *url =[NSURL URLWithString:urlString];
NSLog(urlString);
NSURLRequest *request =[NSURLRequest requestWithURL:url];
[webView loadRequest:request];
}
在界面上放置3個控件,一個textfield、一個button、一個uiwebview,佈局以下:
在代碼中定義相關的控件:webView用於展現網頁、textField用於地址欄、activityIndicatorView用於加載的動畫、buttonPress用於按鈕的點擊事件。
@interface
UIWebViewDemoViewController :UIViewController<UIWebViewDelegate> {
IBOutlet
UIWebView *webView;
IBOutlet
UITextField *textField;
UIActivityIndicatorView *activityIndicatorView;
}
- (
IBAction
)buttonPress:(
id
) sender;
- (
void
)loadWebPageWithString:(
NSString
*)urlString;
@end
|
使用IB關聯他們。
設置UIWebView,初始化UIActivityIndicatorView:
- (void)viewDidLoad
{
[super viewDidLoad];
webView.scalesPageToFit =YES;
webView.delegate =self;
activityIndicatorView = [[UIActivityIndicatorView alloc]
initWithFrame : CGRectMake(0.0f, 0.0f, 32.0f, 32.0f)] ;
[activityIndicatorView setCenter: self.view.center] ;
[activityIndicatorView setActivityIndicatorViewStyle: UIActivityIndicatorViewStyleWhite] ;
[self.view addSubview : activityIndicatorView] ;
[self buttonPress:nil];
// Do any additional setup after loading the view from its nib.
}
UIWebView主要有下面幾個委託方法:
一、- (void)webViewDidStartLoad:(UIWebView *)webView;開始加載的時候執行該方法。
二、- (void)webViewDidFinishLoad:(UIWebView *)webView;加載完成的時候執行該方法。
三、- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;加載出錯的時候執行該方法。
咱們能夠將activityIndicatorView放置到前面兩個委託方法中。
- (void)webViewDidStartLoad:(UIWebView *)webView
{
[activityIndicatorView startAnimating] ;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
[activityIndicatorView stopAnimating];
}
buttonPress方法很簡單,調用咱們開始定義好的loadWebPageWithString方法就好了:
- (
IBAction
)buttonPress:(
id
) sender
{
[textField resignFirstResponder];
[
self
loadWebPageWithString:textField.text];
}
|
當請求頁面出現錯誤的時候,咱們給予提示:
- (
void
)webView:(UIWebView *)webView didFailLoadWithError:(
NSError
*)error
{
UIAlertView *alterview = [[UIAlertView alloc] initWithTitle:@
""
message:[error localizedDescription] delegate:
nil
cancelButtonTitle:
nil
otherButtonTitles:@
"OK"
,
nil
];
[alterview show];
[alterview release];
}
|
總結:本文經過實現一個簡單的瀏覽器,說明了uiwebview的方法和屬性,相信經過這個例子,應該明白uiwebview的使用了。
1.基本用法
1 UIAlertView *view = [[UIAlertView alloc]initWithTitle:@"Test" //標題 2 message:@"this is a alert view " //顯示內容 3 delegate:nil //委託,能夠點擊事件進行處理 4 cancelButtonTitle:@"取消" 5 otherButtonTitles:@"肯定" 6 //,@"其餘", //添加其餘按鈕 7 nil]; 8 [view show];
效果圖:
2.多個按鈕
取消上面代碼@「其餘」的註釋後,運行效果以下
能夠以此類推,添加多個
3.一些系統樣式參數
UIAlertViewStyle這個枚舉提供了幾個樣式
1 typedef NS_ENUM(NSInteger, UIAlertViewStyle) { 2 UIAlertViewStyleDefault = 0, //缺省樣式 3 UIAlertViewStyleSecureTextInput, //密文輸入框 4 UIAlertViewStylePlainTextInput, //明文輸入框 5 UIAlertViewStyleLoginAndPasswordInput //登陸用輸入框,有明文用戶名,和密文密碼輸入二個輸入框 6 };
使用代碼以下:
1 UIAlertView *view = [[UIAlertView alloc]initWithTitle:@"請等待" //標題 2 message:@"this is a alert view " //顯示內容 3 delegate:nil //委託,能夠點擊事件進行處理 4 cancelButtonTitle:@"取消" 5 otherButtonTitles:@"肯定", 6 //,@"其餘", //添加其餘按鈕 7 nil]; 8 [view setAlertViewStyle:UIAlertViewStyleLoginAndPasswordInput]; //控制樣式
效果圖:
這是參數爲:UIAlertViewStyleLoginAndPasswordInput 效果圖,其餘的自行查看
不過這幾個類型,我我的以爲太醜了,不能接受,便自定義了個彈出框,用來接受輸入
實現也不難,有須要的朋友能夠聯繫我
4.判斷用戶點了哪一個按鈕
UIAlertView的委託UIAlertViewDelegate ,實現該委託來實現點擊事件,以下:
.h文件
1 @interface ViewController : UIViewController<UIAlertViewDelegate> { 2 3 }
在.m實現委託的方法
1 - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 2 { 3 NSString* msg = [[NSString alloc] initWithFormat:@"您按下的第%d個按鈕!",buttonIndex]; 4 NSLog(@"%@",msg); 5 }
在這個方法中的參數 buttonIndex,表示的是按鈕的索引,上圖的三按鍵 「取消」,「肯定」,「其餘」對應的索引分別爲「0」,「1」,「2」.
用Delegate的方式處理點擊時候,會帶來一個問題比較麻煩,好比在一個頁面裏,有好幾個UIAlertView的時候,處理點擊的時候,會增長處理邏輯的複雜度,得作一些判斷
這種狀況有一個解決辦法,就是用Block,添加Block的回調,代替Delegate,target和selector.(下次展開寫這個內容)
5.添加子視圖
這個用得也是比較多的,貼幾個使用實例
添加 UIActivityIndicatorView
實現代碼:
1 UIAlertView *view = [[UIAlertView alloc]initWithTitle:@"請等待" 2 message:nil 3 delegate:nil 4 cancelButtonTitle:nil 5 otherButtonTitles:nil, 6 nil]; 7 [view show]; 8 UIActivityIndicatorView *activeView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 9 activeView.center = CGPointMake(view.bounds.size.width/2.0f, view.bounds.size.height-40.0f); 10 [activeView startAnimating]; 11 [view addSubview:activeView]; 12 13 //[view show];
添加UITableView
這個列表的幾行代碼也說不清楚,就說下思路吧,UIAlertView之因此有這麼大的空間顯示UITableView,用了比較取巧的一個辦法
1 UIAlertView *view = [[UIAlertView alloc]initWithTitle:@"請選擇" 2 message:@"\n\n\n\n\n\n\n\n\n\n" 3 delegate:nil 4 cancelButtonTitle:nil 5 otherButtonTitles:nil, 6 nil]; 7 //其中用了10個換行符來撐大UIAlertView的
而後再來添加UITableView,能夠自行實現,若是有須要,請留言
基本上這是一些比較經常使用且實用的東西了,而後還有一個比較重要的東西,就是自定義和美化UIAlertView,相信不少人關心這個,自定義和美化的內容放在下一篇來細說,分析幾個我的以爲不錯的Demo源碼
1.title
獲取或設置UIAlertView上的標題。
2.message
獲取或設置UIAlertView上的消息
1
2
3
4
5
|
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Title" message:@"message" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"肯定", nil];
alertView.title = @"T";
alertView.message = @"M";
[alertView show];
|
3.numberOfButtons (只讀)
返回UIAlertView上有多少按鈕.
1
2
3
|
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Title" message:@"message" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"肯定", nil];
NSLog(@"%d",alertView.numberOfButtons);
[alertView show];
|
4.cancelButtonIndex
1
2
3
4
5
6
7
8
|
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示"
message:@"請選擇一個按鈕:"
delegate:nil
cancelButtonTitle:@"取消"
otherButtonTitles:@"按鈕一", @"按鈕二", @"按鈕三",nil];
[alert show];
NSLog(@"UIAlertView中取消按鈕的角標是%d",alert.cancelButtonIndex);
|
注意不要認爲取消按鈕的角標是4,「取消」,「按鈕一」,「按鈕二」,「按鈕三」的索引buttonIndex分別是0,1,2,3
5. alertViewStyle樣式
UIAlertViewStyleLoginAndPasswordInput
1
2
3
4
5
6
|
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"產品信息展現" message:p.name delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"肯定", nil];
alert.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
// 彈出UIAlertView
[alert show];
|
UIAlertViewStylePlainTextInput
1
2
3
4
5
6
|
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"產品信息展現" message:p.name delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"肯定", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
// 彈出UIAlertView
[alert show];
|
UIAlertViewStyleSecureTextInput
1
2
3
4
5
6
|
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"產品信息展現" message:p.name delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"肯定", nil];
alert.alertViewStyle = UIAlertViewStyleSecureTextInput;
// 彈出UIAlertView
[alert show];
|
6. - (UITextField *)textFieldAtIndex:(NSInteger)textFieldIndex
返回textFieldIndex角標對應的文本框,取出文本框文字。
7.手動的取消對話框
1
|
[alert dismissWithClickedButtonIndex:0 animated:YES];
|
8. delegate
做爲UIAlertView的代理,必須遵照UIAlertViewDelegate。
當點擊UIAlertView上的按鈕時,就會調用,而且當方法調完後,UIAlertView會自動消失。
1
|
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
|
當UIAlertView即將出現的時候調用
1
|
- (void)willPresentAlertView:(UIAlertView *)alertView;
|
當UIAlertView徹底出現的時候調用
1
|
- (void)didPresentAlertView:(UIAlertView *)alertView;
|
當UIAlertView即將消失的時候調用
1
|
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex;
|
當UIAlertView徹底消失的時候調用
1
|
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
|
9.注意UIAlertView調用show顯示出來的時候,系統會自動強引用它,不會被釋放。
10. 爲UIAlertView添加子視圖
在爲UIAlertView對象太添加子視圖的過程當中,有點是須要注意的地方,若是刪除按鈕,也就是取消UIAlerView視圖中全部的按鈕的時候,可能會致使整個顯示結構失衡。按鈕佔用的空間不會消失,咱們也能夠理解爲這些按鈕沒有真正的刪除,僅僅是他不可見了而已。若是在UIAlertview對象中僅僅用來顯示文本,那麼,能夠在消息的開頭添加換行符(@"\n)有助於平衡按鈕底部和頂部的空間。
下面的代碼用來演示如何爲UIAlertview對象添加子視圖的方法。
1
2
3
4
5
6
7
8
9
10
|
UIAlertView*alert = [[UIAlertView alloc]initWithTitle:@"請等待"
message:nil
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:nil];
[alert show];
UIActivityIndicatorView*activeView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activeView.center = CGPointMake(alert.bounds.size.width / 2.0f, alert.bounds.size.height - 40.0f);
[activeView startAnimating];
[alert addSubview:activeView];
|
11. UIAlertView小例子
UIAlertView默認狀況下全部的text是居中對齊的。 那若是須要將文本向左對齊或者添加其餘控件好比輸入框時該怎麼辦呢? 不用擔憂, iPhone SDK仍是很靈活的, 有不少delegate消息供調用程序使用。 所要作的就是在
1
|
- (void)willPresentAlertView:(UIAlertView *)alertView
|
中按照本身的須要修改或添加便可, 好比須要將消息文本左對齊,下面的代碼便可實現:
1
2
3
4
5
6
7
8
|
- (void)willPresentAlertView:(UIAlertView *)alertView {
for( UIView * view in alertView.subviews ) {
if( [view isKindOfClass:[UILabel class]] ) {
UILabel* label = (UILabel*) view;
label.textAlignment=UITextAlignmentLeft;
}
}
}
|
(二)1。UIPageControl 分頁控件
UIPageControl控件在程序中出現的比較頻繁,尤爲在和UIScrollView配合來顯示大量數據時,會使用它來控制UIScrollView的翻頁。在滾動ScrollView時可經過PageControll中的小白點來觀察當前頁面的位置,也可經過點擊PageContrll中的小白點來滾動到指定的頁面。下面以一個簡單但實用的例子來說解PageControll的用法。
如上圖中的曲線圖和表格即是由ScrollView加載兩個控件(UIWebView 和 UITableView)實用其翻頁屬性實現的頁面滾動。而PageControll但當配合角色,頁面滾動小白點會跟着變化位置,而點擊小白點ScrollView會滾動到指定的頁面。
代碼:(只羅列主要代碼)
- (void)viewDidLoad
{
[superviewDidLoad];
self.view.backgroundColor = [UIColorcolorWithPatternImage:[UIImageimageNamed:@"bg_blank.png"]];
// self.view.backgroundColor = [UIColor clearColor];
//定義UIScrollView
scrollview = [[UIScrollViewalloc] init];
scrollview.frame = CGRectMake(10, 0, 300, 108);
scrollview.contentSize = CGSizeMake(600, 108); //scrollview的滾動範圍
scrollview.showsVerticalScrollIndicator = NO;
scrollview.showsHorizontalScrollIndicator = NO;
//myScrollView.clipsToBounds = YES;
scrollview.delegate = self;
scrollview.scrollEnabled = YES;
scrollview.pagingEnabled = YES; //使用翻頁屬性
scrollview.bounces = NO;
//定義WebView加載曲線圖
webview = [[UIWebViewalloc] init];
webview.frame = CGRectMake(-7, -10, 307, 118);
webview.delegate = self;
[webviewsetBackgroundColor:[UIColorclearColor]];
[webviewsetOpaque:NO];
NSString *fullPath = [NSBundlepathForResource:@"sline"ofType:@"htm"inDirectory:[[NSBundlemainBundle] bundlePath]];
[self.webviewloadRequest:[NSURLRequestrequestWithURL:[NSURLfileURLWithPath:fullPath]]];
//用來制定邊框
view22 = [[UIViewalloc] init];
//將圖層的邊框設置爲圓腳
view22.layer.cornerRadius = 10;
view22.layer.masksToBounds = YES;
//給圖層添加一個有色邊框
view22.layer.borderWidth = 1;
//view1.layer.borderColor = [[UIColor colorWithRed:0.52 green:0.09 blue:0.07 alpha:1] CGColor];
view22.layer.borderColor = [[UIColorcolorWithRed:0green:0blue:0alpha:1] CGColor];
view22.frame = CGRectMake(0, 0, 300, 108);
view22.backgroundColor = [UIColorcolorWithRed:0.31green:0.31blue:0.31alpha:1];
tableview.frame = CGRectMake(0, 21, 300, 87);
tableview.allowsSelection = NO;
tableview.backgroundColor = [UIColorcolorWithRed:0.31green:0.31blue:0.31alpha:1];
//用來制定邊框
view11 = [[UIViewalloc] init];
//將圖層的邊框設置爲圓腳
view11.layer.cornerRadius = 10;
view11.layer.masksToBounds = YES;
//給圖層添加一個有色邊框
view11.layer.borderWidth = 1;
//view1.layer.borderColor = [[UIColor colorWithRed:0.52 green:0.09 blue:0.07 alpha:1] CGColor];
view11.layer.borderColor = [[UIColorcolorWithRed:0green:0blue:0alpha:1] CGColor];
view11.frame = CGRectMake(300, 0, 300, 108);
view11.backgroundColor = [UIColorblackColor];
[view11addSubview:tableview];
[scrollviewaddSubview:view11];
[view22addSubview:webview];
[scrollviewaddSubview:view22];
//定義PageControll
pageControl = [[UIPageControlalloc] init];
pageControl.frame = CGRectMake(150, 100, 20, 20);//指定位置大小
pageControl.numberOfPages = 2;//指定頁面個數
pageControl.currentPage = 0;//指定pagecontroll的值,默認選中的小白點(第一個)
[pageControladdTarget:selfaction:@selector(changePage:)forControlEvents:UIControlEventValueChanged];
//添加委託方法,當點擊小白點就執行此方法
[self.viewaddSubview:scrollview];
[self.viewaddSubview:pageControl];
}
//scrollview的委託方法,當滾動時執行
- (void)scrollViewDidScroll:(UIScrollView *)sender {
int page = scrollview.contentOffset.x / 290;//經過滾動的偏移量來判斷目前頁面所對應的小白點
pageControl.currentPage = page;//pagecontroll響應值的變化
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
}
//pagecontroll的委託方法
- (IBAction)changePage:(id)sender {
int page = pageControl.currentPage;//獲取當前pagecontroll的值
[scrollview setContentOffset:CGPointMake(300 * page, 0)];//根據pagecontroll的值來改變scrollview的滾動位置,以此切換到指定的頁面
}
以上是一種簡單的方法來實現pagecontroll的切換頁面功能,之後會爲你們添加 「無限循環切換頁面」和「動態的增長和減小頁面」。
1.建立並初始化
建立UITextView的文件,並在.h文件中寫入以下代碼:
#import <UIKit/UIKit.h>
@interface TextViewController : UIViewController <UITextViewDelegate>
{
UITextView *textView;
}
@property (nonatomic, retain) UITextView *textView;
@end
在.m文件中初始化這個textview,寫入代碼以下:
self.textView = [[[UITextView alloc] initWithFrame:self.view.frame] autorelease]; //初始化大小並自動釋放 |
self.textView.textColor = [UIColor blackColor]; //設置textview裏面的字體顏色 |
self.textView.font = [UIFont fontWithName: @"Arial" size:18.0]; //設置字體名字和字體大小 |
self.textView. delegate = self; //設置它的委託方法 |
self.textView.backgroundColor = [UIColor whiteColor]; //設置它的背景顏色 |
self.textView.text = @"Now is the time for all good developers to come to serve their country.\n\nNow is the time for all good developers to come to serve their country." ; //設置它顯示的內容 |
self.textView.returnKeyType = UIReturnKeyDefault; //返回鍵的類型 |
self.textView.keyboardType = UIKeyboardTypeDefault; //鍵盤類型 |
self.textView.scrollEnabled = YES; //是否能夠拖動 |
self.textView.autoresizingMask = UIViewAutoresizingFlexibleHeight; //自適應高度 |
[self.view addSubview: self.textView]; //加入到整個頁面中 |
2. UITextView退出鍵盤的幾種方式
由於你點擊UITextView會出現鍵盤,若是你退出鍵盤,有以下幾種方式:
(1)若是你程序是有導航條的,能夠在導航條上面加多一個Done的按鈕,用來退出鍵盤,固然要先實UITextViewDelegate。
代碼以下:
- ( void )textViewDidBeginEditing:(UITextView *)textView { |
UIBarButtonItem *done = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(leaveEditMode)] autorelease]; |
self.navigationItem.rightBarButtonItem = done; |
} |
- ( void )textViewDidEndEditing:(UITextView *)textView { |
self.navigationItem.rightBarButtonItem = nil; |
} |
- ( void )leaveEditMode { |
[self.textView resignFirstResponder]; |
} |
(2)若是你的textview裏不用回車鍵,能夠把回車鍵當作退出鍵盤的響應鍵。
代碼以下:
#pragma mark - UITextView Delegate Methods |
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text |
{ |
|
|
|
|
|
|
這樣不管你是使用電腦鍵盤上的回車鍵仍是使用彈出鍵盤裏的return鍵均可以達到退出鍵盤的效果。
(3)還有你也能夠自定義其餘加載鍵盤上面用來退出,好比在彈出的鍵盤上面加一個view來放置退出鍵盤的Done按鈕。
代碼以下:
UIToolbar * topView = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 30)]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(4)設置UITextView圓角問題
作法是在 #import QuartzCore/QuartzCore.h 後,便能調用 [textView.layer setCornerRadius:10]; 來把 UITextView 設定圓角
(5)UITextView根據文本大小自適應高度
經過實現文本字數來肯定高度,以下:
NSString * desc = @"Description it is a test font, and don't become angry for which i use to do here.Now here is a very nice party from american or not!" ; |
|
而後須要定義UITextView的numberoflines爲0,即不作行數的限制。以下:
[textView setNumberOfLines:0]; |
|
|
UIMenuItem *menuItem = [[UIMenuItem alloc]initWithTitle: @"分享到新浪微博" action:@selector(changeColor:)]; |
UIMenuController *menu = [UIMenuController sharedMenuController]; |
[menu setMenuItems:[NSArray arrayWithObject:menuItem]]; |
[menuItem release]; |
固然上面那個@selector裏面的changeColor方法仍是本身寫吧,也就是說點擊了咱們自定義的菜單項後會觸發的方法。
而後還得在代碼里加上一個方法:
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender |
{ |
if (action == @selector(changeColor:)) |
{ |
if (textView.selectedRange.length>0) |
return YES; |
} |
return NO; |
} |
(二)3.UIActivityIndicator 圈圈
(1)建立
(二)4.UISwitch 開關
開關(UISwitch)提供了一個簡單的開/關UI元素,相似於傳統的物理開關,開關的可配置選項不多,應將其用於處理布爾值。咱們使用其Value Changed事件來檢測開關切換,並經過屬性on或實例方法isOn來獲取當前值。
1.UISwitch的初始化
UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectMake(54.0f, 16.0f, 100.0f, 28.0f)];
2.設置UISwitch的初始化狀態
switchView.on = YES;//設置初始爲ON的一邊
3.UISwitch事件的響應
[switchView addTarget:self action:@selector(switchAction:) forControlEvents:UIControlEventValueChanged];
由於項目須要在UISwitch按鈕上寫文字,系統自帶的UISwitch是這樣的:
既不能寫字,也不能改顏色,因而在網上找到了這麼一個自定義的Switch按鈕,具體出處找不見了。記錄一下,怕之後找不見了。
先看下效果圖:
按鈕的樣式不少,能夠文字,能夠寫多行,文字大小和顏色均可以設置。
看下它的源碼:
.m文件
如何在代碼中使用它呢?很簡單:
- (void)loadView
{
UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.view = contentView;
代碼下載地址: https://github.com/schelling/HMCustomSwitch
UIActionSheet是在IOS彈出的選擇按鈕項,能夠添加多項,併爲每項添加點擊事件。
爲了快速完成這例子,咱們打開Xcode 4.3.2, 先創建一個single view application。而後再xib文件添加一個button,用來彈出sheet view。
一、首先在.h文件中實現協議,加代碼的地方在@interface那行的最後添加<UIActionSheetDelegate>,協議至關於java裏的接口,實現協議裏的方法。
@interface sheetviewViewController : UIViewController<UIActionSheetDelegate> @end
二、添加button,命名button爲showSheetView.
三、爲button創建Action映射,映射到.h文件上,事件類型爲Action ,命名爲showSheet。
四、在.m文件上添加點擊事件代碼
圖的效果是這樣的:
- (IBAction)showSheet:(id)sender { UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"title,nil時不顯示" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"肯定" otherButtonTitles:@"第一項", @"第二項",nil]; actionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque; [actionSheet showInView:self.view]; }
actionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;//設置樣式
參數解釋:
cancelButtonTitle destructiveButtonTitle是系統自動的兩項。
otherButtonTitles是本身定義的項,注意,最後一個參數要是nil。
[actionSheet showInView:self.view];這行語句的意思是在當前view顯示Action sheet。固然還能夠用其餘方法顯示Action sheet。
對應上面的圖和代碼,一目瞭然了把
五、接下來咱們怎麼相應Action Sheet的選項的事件呢?實現協議裏的方法。爲了能看出點擊Action sheet每一項的效果,咱們加入UIAlertView來作信息顯示。下面是封裝的一個方法,傳入對應的信息,在UIAlertView顯示對應的信息。
-(void)showAlert:(NSString *)msg { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Action Sheet選擇項" message:msg delegate:self cancelButtonTitle:@"肯定" otherButtonTitles: nil]; [alert show]; }
那相應被Action Sheet選項執行的代碼以下:
(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { if (buttonIndex == 0) { [self showAlert:@"肯定"]; }else if (buttonIndex == 1) { [self showAlert:@"第一項"]; }else if(buttonIndex == 2) { [self showAlert:@"第二項"]; }else if(buttonIndex == 3) { [self showAlert:@"取消"]; } } - (void)actionSheetCancel:(UIActionSheet *)actionSheet{ } -(void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex{ } -(void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex{ }
能夠看到 buttonIndex 是對應的項的索引。
看到那個紅色的按鈕沒?那是ActionSheet支持的一種所謂的銷燬按鈕,對某戶的某個動做起到警示做用,
好比永久性刪除一條消息或圖像時。若是你指定了一個銷燬按鈕他就會以紅色高亮顯示:
actionSheet.destructiveButtonIndex=1;
與導航欄相似,操做表單也支持三種風格 :
UIActionSheetStyleDefault //默認風格:灰色背景上顯示白色文字
UIActionSheetStyleBlackTranslucent //透明黑色背景,白色文字
UIActionSheetStyleBlackOpaque //純黑背景,白色文字
用法:
actionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;//設置樣式
我選sheet 裏的第一項,顯示以下:
六、注意事項,在開發過程當中,發現有時候UIActionSheet的最後一項點擊失效,點最後一項的上半區域時有效,這是在特定狀況下才會發生,這個場景就是試用了UITabBar的時候纔有。解決辦法:
在showView時這樣使用,[actionSheet showInView:[UIApplication sharedApplication].keyWindow];
或者[sheet showInView:[AppDelegate sharedDelegate].tabBarController.view];這樣就不會發生遮擋現象了。
代碼獲取:http://download.csdn.net/detail/totogo2010/4343267
UIActionSheet類系IOS開發中實現警告框的重要的類,而在好多應用中,都對它進行了擴展,今天介紹一下自定義風格的UIActionSheet
1、自定義CustomActionSheet類
CustomActionSheet類繼承UIActionSheet,具體的實現以下所示:
1)CustomActionSheet.h頭文件
#import <Foundation/Foundation.h>
@interface CustomActionSheet : UIActionSheet {
UIToolbar* toolBar;
UIView* view;
}
@property(nonatomic,retain)UIView* view;
@property(nonatomic,retain)UIToolbar* toolBar;
/*由於是經過給ActionSheet 加 Button來改變ActionSheet, 因此大小要與actionsheet的button數有關
*height = 84, 134, 184, 234, 284, 334, 384, 434, 484
*若是要用self.view = anotherview. 那麼another的大小也必須與view的大小同樣
*/
-(id)initWithHeight:(float)height WithSheetTitle:(NSString*)title;
@end
2)CustomActionSheet.m實現文件
#import "CustomActionSheet.h"
@implementation CustomActionSheet
@synthesize view;
@synthesize toolBar;
-(id)initWithHeight:(float)height WithSheetTitle:(NSString*)title
{
self = [super init];
if (self)
{
int theight = height - 40;
int btnnum = theight/50;
for(int i=0; i<btnnum; i++)
{
[self addButtonWithTitle:@" "];
}
toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
toolBar.barStyle = UIBarStyleBlackOpaque;
UIBarButtonItem *titleButton = [[UIBarButtonItem alloc] initWithTitle:title
style:UIBarButtonItemStylePlain
target:nil
action:nil];
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:@"Done"
style:UIBarButtonItemStyleDone
target:self
action:@selector(done)];
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(docancel)];
UIBarButtonItem *fixedButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
NSArray *array = [[NSArray alloc] initWithObjects:leftButton,fixedButton,titleButton,fixedButton,rightButton,nil];
[toolBar setItems: array];
[titleButton release];
[leftButton release];
[rightButton release];
[fixedButton release];
[array release];
[self addSubview:toolBar];
view = [[UIView alloc] initWithFrame:CGRectMake(0, 44, 320, height-44)];
view.backgroundColor = [UIColor groupTableViewBackgroundColor];
[self addSubview:view];
}
return self;
}
-(void)done
{
[self dismissWithClickedButtonIndex:0 animated:YES];
}
-(void)docancel
{
[self dismissWithClickedButtonIndex:0 animated:YES];
}
-(void)dealloc
{
[view release];
[super dealloc];
}
@end
2、利用自定義的CustomActionSheet類顯示提示框
#import "TestActionSheetViewController.h"
#import "CustomActionSheet.h"
@implementation TestActionSheetViewController
-(IBAction)btndown
{
CustomActionSheet* sheet = [[CustomActionSheet alloc] initWithHeight:284.0f
WithSheetTitle:@"自定義ActionSheet"];
UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0,50, 320, 50)];
label.text = @"這裏是要自定義放的控制";
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentCenter;
[sheet.view addSubview:label];
[sheet showInView:self.view];
[sheet release];
}
@end
這裏的UILabel是做一個示例,在這個位置你能夠換成你本身的內容便可;
3、效果圖
(二)6.UIDatePicker 日期選擇器
UIDatePicker
這是兩種能夠上下滾動的控件。
這是UIDatePicker,能夠顯示日期和時間。
這個是UIPickerView,顯示相似幾個選擇項的界面。
注意點:PickerView的高度不能改,默認162,PickerView裏面每行的高度 能夠改,不要弄混淆了。
作一個簡單界面進行練習。單擊生日輸入框彈出自定義UIDatePicker,單擊城市彈出自定義UIPickerView選擇城市。
在點擊過文本輸入框後彈出日期選中鍵盤。須要給UITextField控件的inutView屬性指定須要顯示的界面。
這裏顯示的代碼以下:
- (void)setBirthdayFieldKeyboard
{
//
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
_datePicker = datePicker;
// 只顯示時間
datePicker.datePickerMode = UIDatePickerModeDate;
// 顯示中文
datePicker.locale = [NSLocalelocaleWithLocaleIdentifier:@"zh"];
// 監聽值得改變
[datePicker addTarget:selfaction:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
self.birthdayField.inputView = datePicker;
}
在程序加載時進行設定
- (void)viewDidLoad {
[superviewDidLoad];
[selfsetBirthdayFieldKeyboard];
}
而後對UITextField的一些屬性進行設置,好比說不能輸入日期,只能選擇顯示日期。能夠在如下代理方法中實現
#pragma mark - textField代理方法
// 是否容許修改填充字符串
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
returnNO;
}
固然使用以前要指定代理並遵照協議。
而後再選擇過期間後,同步更新到文本輸入框中,這裏須要監聽控件的valueChanged的方法
[datePicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
響應方法
- (void)datePickerValueChanged:(UIDatePicker *)datePicker
{
NSDateFormatter *formatter = [[NSDateFormatteralloc] init];
// 格式化日期格式
formatter.dateFormat = @"yyyy-MM-dd";
NSString *date = [formatter stringFromDate:datePicker.date];
// 顯示時間
self.birthdayField.text = date;
}
最後要設置如下UITextField控件的默認值,默認顯示0行0列的值
在改變文本輸入框狀態時進行設置默認值。
// 是否容許開始編輯(代理方法)
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
// 添加自定義窗口
[selfdatePickerValueChanged:self.datePicker];
}
先將城市選擇鍵盤添加到文本輸入框
// 設置城市鍵盤
- (void)setCitiesFieldKeyboard
{
//
UIPickerView *picker = [[UIPickerViewalloc] init];
_cityPicker = picker;
picker.dataSource = self;
picker.delegate = self;
self.cityField.inputView = picker;
}
設置代理和數據源爲控制器,實現響應的方法
#pragma mark UIPickerView 數據源
// 列數
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
// 某一列行數
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == 0) // 省會
{
return self.provinces.count;
}
else // 其餘城市
{
SLQProvince *pro = self.provinces[_proIndex];
return pro.cities.count;
}
}
#pragma mark UIPickerView 代理
// 每行的標題
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == 0) // 省會
{
// 獲取省會
SLQProvince *pro = self.provinces[row];
return pro.name;
}
else // 其餘城市
{
SLQProvince *pro = self.provinces[_proIndex];
return pro.cities[row];
}
}
// 是否選中某行
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// 滾動省會刷新城市
if(component == 0)
{
// 記錄當前省會
_proIndex = [pickerView selectedRowInComponent:0];
[pickerView reloadComponent:1];
}
// 獲取選中省會
SLQProvince *pro = self.provinces[_proIndex];
NSInteger cityIndex = [pickerView selectedRowInComponent:1];
NSString *cityName = pro.cities[cityIndex];
_cityField.text = [NSString stringWithFormat:@"%@-%@",pro.name,cityName];
}
而後在文本輸入框的代理方法中添加默認顯示對象
// 是否容許開始編輯
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
if (textField == self.birthdayField)
{
// 添加自定義窗口
[selfdatePickerValueChanged:self.datePicker];
}
else
{
[selfpickerView:self.cityPickerdidSelectRow:0inComponent:0]; // 默認顯示0行0列
}
}
效果
主要代碼參考
注意點:PickerView的高度不能改,默認162,PickerView裏面每行的高度 能夠改,不要弄混淆了。
1.Locale
設置DatePicker的地區,即設置DatePicker顯示的語言。
1
2
3
4
5
6
7
8
|
// 1.跟蹤全部可用的地區,取出想要的地區
NSLog(@"%@", [NSLocale availableLocaleIdentifiers]);
// 2. 設置日期選擇控件的地區
[datePicker setLocale:[[NSLocale alloc]initWithLocaleIdentifier:@"zh_Hans_CN"]];
// 2) 設置日期選擇控件的地區
[datePicker setLocale:[[NSLocale alloc]initWithLocaleIdentifier:@"en_SC"]];
|
2.Calendar
設置DatePicker的日曆,默認爲當天。
1
|
[datePicker setCalendar:[NSCalendar currentCalendar]];
|
3.timeZone
設置DatePicker的時區,默認爲設置爲:
1
|
[datePicker setTimeZone:[NSTimeZone defaultTimeZone]];
|
4.date
設置DatePicker的日期,默認設置爲:
1
|
[datePicker setDate:[NSDate date]];
|
5.minimumDate
設置DatePicker的容許的最小日期。
6.maximumDate
設置DatePicker的容許的最大日期。
7.countDownDuration
設置DatePicker的倒計時間.
1
2
3
4
5
6
7
8
9
10
11
|
// 1) 設置日期選擇的模
[self.datePicker setDatePickerMode:UIDatePickerModeCountDownTimer];
// 2) 設置倒計時的時長
// 注意:設置倒計時時長鬚要在肯定模式以後指定
// 倒計時的時長,以秒爲單位
[self.datePicker setCountDownDuration:10 * 60];
|
8.minuteInterval
你能夠將分鐘錶盤設置爲以不一樣的時間間隔來顯示分鐘,前提是該間隔要可以讓60整除。默認間隔是一分鐘。若是要使用不一樣的間隔,須要改變 minuteInterval屬性:
1
2
3
|
// 設置分鐘間隔
datePicker.minuteInterval = 15;
|
9.datePickerMode
UIDatePickerModeTime, 顯示小時,分鐘和AM/PM,這個的名稱是根據本地設置的
1
|
[datePicker setDatePickerMode:UIDatePickerModeTime];
|
UIDatePickerModeDate, 顯示年月日,名稱根據本地設置的
1
|
[datePicker setDatePickerMode:UIDatePickerModeDate];
|
UIDatePickerModeDateAndTime, 顯示日期,小時,分鐘,和AM/PM,名稱是根據本地設置的
1
|
[datePicker setDatePickerMode:UIDatePickerModeDateAndTime];
|
UIDatePickerModeCountDownTimer 顯示小時和分鐘
1
|
[datePicker setDatePickerMode:UIDatePickerModeCountDownTimer];
|
10.UIDatePicker使用教程一
10.1初始化
1
2
3
|
// 不用設置寬高,由於它的寬高是固定的
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
|
10.2經常使用設置
1
2
3
4
5
6
7
8
9
|
// 設置區域爲中國簡體中文
datePicker.locale = [[NSLocale alloc]
initWithLocaleIdentifier:@"zh_CN"];
// 設置picker的顯示模式:只顯示日期
datePicker.datePickerMode = UIDatePickerModeDate;
|
10.3UIDatePicker須要監聽值的改變
1
2
3
|
[datePicker addTarget:self action:@selector(dateChange:)
forControlEvents:UIControlEventValueChanged];
|
11.UIDatePicker使用教程二
你能夠經過設置mininumDate 和 maxinumDate 屬性,來指定使用的日期範圍。若是用戶試圖滾動到超出這一範圍的日期,錶盤會回滾到最近的有效日期。兩個方法都須要NSDate 對象做參數:
1
2
3
4
5
6
7
|
NSDate* minDate = [[NSDate alloc]initWithString:@"1900-01-01 00:00:00 -0500"];
NSDate* maxDate = [[NSDate alloc]initWithString:@"2099-01-01 00:00:00 -0500"];
datePicker.minimumDate = minDate;
datePicker.maximumDate = maxDate;
|
若是兩個日期範圍屬性中任何一個未被設置,則默認行爲將會容許用戶選擇過去或將來的任意日期。這在某些狀況下頗有用處,好比,當選擇生日時,能夠是過去的任意日期,但終止與當前日期。若是你但願設置默認顯示的日期,可使用date屬性:
1
|
datePicker.date = minDate;
|
你還能夠用 setDate 方法。若是選擇了使用動畫,則錶盤會滾動到你指定的日期:
1
|
[ datePicker setDate:maxDate animated:YES];
|
1. 初始化UIDatePicker
UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 200, 320, 216)];
注:高度和寬度能夠設定爲0,好比:
UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 200, 0, 0)];
2. 設置時區
[datePicker setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
3. 設置當前顯示時間
[datePicker setDate:tempDate animated:YES];
4. 設置顯示最大時間(此處爲當前時間)
[datePicker setMaximumDate:[NSDate date]];
或
datePicker.maximumDate = [NSDate date];
設置最小時間
NSDate* minDate = [[NSDate alloc]initWithString:@"1900-01-01 00:00:00 -0500"];
datePicker.minimumDate = minDate;
[minDate release];
5. 設置UIDatePicker的顯示模式
[datePicker setDatePickerMode:UIDatePickerModeDate];
參數 UIDatePickerMode 有四種:
UIDatePickerModeTime, // Displays hour, minute, and optionally AM/PM designation depending on the locale setting (e.g. 6 | 53 | PM)
UIDatePickerModeDate, // Displays month, day, and year depending on the locale setting (e.g. November | 15 | 2007)
UIDatePickerModeDateAndTime, // Displays date, hour, minute, and optionally AM/PM designation depending on the locale setting (e.g. Wed Nov 15 | 6 | 53 | PM)
UIDatePickerModeCountDownTimer // Displays hour and minute (e.g. 1 | 53)
6. 當值發生改變的時候調用的方法
[datePicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
7. 加入到視圖
[self.view addSubview:datePicker];
甚至還能夠加入到 UIActionSheet 中
[actionSheet addSubview: datePicker];
8. 釋放對象
[datePicker release];
9. 得到當前UIPickerDate所在的時間
NSDate *date = [datePicker date];
10.設置本地化語言
NSLocale * locale = [[NSLocalealloc] initWithLocaleIdentifier:@"Chinese"];//設置本地化語言,本地化語言能夠經過在xib文件中添加一個日曆選取器,而後查看其屬性來找到須要的值
[datePicker setLocale:locale];
好比能夠在 datePickerValueChanged 回調方法中
- (void)datePickerValueChanged:(id)sender {
UIDatePicker *datePicker = sender;
NSDate *date = [datePicker date];
// TODO:
|
能夠在toolBar上添加任何View。其實它的原理是把你要添加的View先加到UIBarButtonItem裏面,最後再把UIBarButtonItem數組一次性放到toolbar的items裏面。
1.首先,咱們看一下UIBbarButtonItem有哪些初始化方法,這也能夠看出,它能夠被定義爲何東東,而後加到UIToolBar上面去。
根據SDK的文檔,咱們能夠發現UIBarButtonItem有以下幾種初始化的方法:
-initWithTitle(添加button用這個)
-initWithImage
-initWithBarButtonSystemItem(添加系統自定義的button,形狀跟大小都已經固定了)下面連接裏面有按鈕圖片樣式
https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIBarButtonItem_Class/Reference/Reference.html
-initWithCustomView(添加除了button之外的View)
第4種方法就是咱們添加各類做料的接口,因此今天的主角其它也是它。
2.在UIToolBar上面添加Title
view plaincopy to clipboardprint?
UIToolbar *myToolBar = [[UIToolbar alloc] initWithFrame:
CGRectMake(0.0f, 0.0f, 320.0f, 44.0f)];
NSMutableArray *myToolBarItems = [NSMutableArray array];
[myToolBarItems addObject:[[[UIBarButtonItem alloc]
initWithTitle:@"myTile"
style:UIBarButtonItemStylePlain
target:self
action:@selector(action)] autorelease]];
[myToolBar setItems:myToolBarItems animated:YES];
[myToolBar release];
[myToolBarItems];
setItems傳入值或者說items是一個對象數組。
3.在UIToolBar上面添加image
view plaincopy to clipboardprint?
[myToolBarItems addObject:[[[UIBarButtonItem alloc]
initWithImage:[UIImage imageNamed:@"myImage.png"]
style:UIBarButtonItemStylePlain
target:self
action:@selector(action)]];
4.在UIToolBar上面添加SystemItem
[myToolBarItems addObject:[[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemPlay
target:self
action:@selector(action)] autorelease]];
Note:
initWithBarButtonSystemItem初始化:
- (id)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(id)target action:(SEL)action
Defines system defaults for commonly used items.
typedef enum {
UIBarButtonSystemItemDone,
UIBarButtonSystemItemCancel,
UIBarButtonSystemItemEdit,
UIBarButtonSystemItemSave,
UIBarButtonSystemItemAdd,
UIBarButtonSystemItemFlexibleSpace,
UIBarButtonSystemItemFixedSpace,
UIBarButtonSystemItemCompose,
UIBarButtonSystemItemReply,
UIBarButtonSystemItemAction,
UIBarButtonSystemItemOrganize,
UIBarButtonSystemItemBookmarks,
UIBarButtonSystemItemSearch,
UIBarButtonSystemItemRefresh,
UIBarButtonSystemItemStop,
UIBarButtonSystemItemCamera,
UIBarButtonSystemItemTrash,
UIBarButtonSystemItemPlay,
UIBarButtonSystemItemPause,
UIBarButtonSystemItemRewind,
UIBarButtonSystemItemFastForward,
UIBarButtonSystemItemUndo, // iPhoneOS 3.0
UIBarButtonSystemItemRedo, // iPhoneOS 3.0
} UIBarButtonSystemItem;
5.在UIToolBar上面添加其它各類控件,最自由意義,最有意思的,我把它放在最後來說。咱們使用initWithCustomView來完成,
這裏須要看一下initWithCustomView的定義:
- (id)initWithCustomView:(UIView *)customView
能夠看出,它的參數是一個VIEW,因此咱們給它的配料要正確哦才行哦,不然,你就等着時間DIDADIDA的流失吧.
A>加一個開關switch:
[myToolBarItems addObject:[[[UIBarButtonItem alloc]
initWithCustomView:[[[UISwitch alloc] init] autorelease]]
autorelease]];
B>加一個按鈕UIBarButtonItem
UIBarButtonItem *myButton = [[[UIBarButtonItem alloc]
initWithTitle:@"myButton"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(action)]autorelease];
get1Button.width = 50;
[myToolBarItems addObject:myButton];
C>加一個文本Label
view plaincopy to clipboardprint?
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(40.0f, 20.0f, 45.0f, 10.0f)];
myLabel.font=[UIFont systemFontOfSize:10];
//myLabel.backgroundColor = [UIColor clearColor];
//myLabel.textAlignment=UITextAlignmentCenter;
UIBarButtonItem *myButtonItem = [[UIBarButtonItem alloc]initWithCustomView:myLabel];
[myToolBarItems addObject: myButtonItem];
[mylabel release];
[myButtonItem release];
D>加一個進度條UIProgressView
UIProgressView *myProgress = [[UIProgressView alloc] initWithFrame:CGRectMake(65.0f, 20.0f, 90.0f, 10.0f)];
UIBarButtonItem *myButtonItem = [[UIBarButtonItem alloc]initWithCustomView:myProgress];
[myToolBarItems addObject: myButtonItem];
[myProgress release];
[myButtonItem release];
能夠加使用initWithCustomView製做各類button,這裏就不在這裏一個一個在加了。我想你應該也已經掌握瞭如何添加各類buttonItem的方法了。
UIProgressView顧名思義用來顯示進度的,如音樂,視頻的播放進度,和文件的上傳下載進度等。
下面以一個簡單的實例來介紹UIprogressView的使用。
@interface ActivityViewController : UIViewController
{
UIProgressView *proView;
double proValue;
NSTimer *timer;
}
@property(nonatomic, retain) UIProgressView *proView;
-(IBAction)btnStartClick;
@implementation ActivityViewController
@synthesize proView;
#pragma mark - View lifecycle
-(IBAction)btnStartClick
{
proValue=0;
timer = [NSTimerscheduledTimerWithTimeInterval:1target:selfselector:@selector(changeProgress) userInfo:nilrepeats:YES]; //利用計時器,每隔1秒調用一次(changeProgress)
}
-(void)changeProgress
{
proValue += 1.0; //改變proValue的值
if(proValue > 5)
{
//停用計時器
[timer invalidate];
}
else
{
[proViewsetProgress:(proValue / 5)];//重置進度條
}
}
- (void)viewDidLoad
{
proView = [[UIProgressViewalloc] initWithFrame:CGRectMake(100, 100, 150, 20)];
[proViewsetProgressViewStyle:UIProgressViewStyleDefault]; //設置進度條類型
[self.viewaddSubview:proView];
[superviewDidLoad];
}
(三)3.UISlider 滑塊
UIslider是一個方便的控件,讓用戶可以以可視化的方式設置指定範圍內的值。和按鈕同樣,滑塊也能響應事件,還可像文本框同樣被讀取。若是但願用戶對滑塊的調整馬上影響應用程序,則須要讓他觸發操做。
UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(0, 0, 200, 20)]; //初始化 slider.minimumValue = 0;//指定可變最小值 slider.maximumValue = 100;//指定可變最大值 slider.value = 50;//指定初始值 [slider addTarget:self action:@selector(updateValue:) forControlEvents:UIControlEventValueChanged];//設置響應事件 [self.view addSubview:slider];
-(IBAction)updateValue:(id)sender{
//添加響應事件
float f = slider.value; //讀取滑塊的值
}
改變UISlider的樣式:
須要資源以下
(max.png)
(min.png) 相似圖片就可。
slider.backgroundColor = [UIColorclearColor];
[slider setMinimumTrackImage:[UIImageimageNamed:@"max.png"] forState:UIControlStateNormal];
[slider setMaximumTrackImage:[UIImageimageNamed:@"min.png"] forState:UIControlStateNormal];
注意:UISlider的長和寬,要和圖片匹配。
(三)4.UISegmentControl 選項卡
-(void) viewDidLoad{
/*************分段控件UISegmentdControl*************/ UISegmentedControl *segmentedControl = [[UISegmentedControlalloc] initWithItems:nil]; segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar; //控件風格小按鈕,適合導航欄: segmentedControl.segmentedControlStyle = UISegmentedControlStyleBezeled; //控件風格 segmentedControl.segmentedControlStyle = UISegmentedControlStyleBordered; //控件風格黑邊的大白按鈕,適合表格單元 segmentedControl.segmentedControlStyle = UISegmentedControlStylePlain; //控件風格灰邊大白按鈕,適合偏好設置單元 segmentedControl.tintColor = [UIColor blueColor]; //渲染色彩 //添加片斷,從0單元開始 ,可加入標題或圖片兩種狀況 [segmentedControl insertSegmentWithTitle:@"First"atIndex:0animated:NO]; [segmentedControl insertSegmentWithTitle:@"Second"atIndex:1animated:NO]; UIImage *myImage = [UIImage imageNamed:@"1.png"]; [segmentedControl insertSegmentWithImage:myImage atIndex:2animated:NO]; //刪除片斷 [segmentedControl removeSegmentAtIndex:1 animated:YES]; //刪除單個 [segmentedControl removeAllSegments]; //刪除全部 //片斷標題 [segmentedControl setTitle:@"Third" forSegmentAtIndex:2];//設置標題 NSString *myTitle = [segmentedControl titleForSegmentAtIndex:0];//讀取標題 //圖像 [segmentedControl setImage:[UIImageimageNamed:@"2.png"] forSegmentAtIndex:0];//設置圖像 UIImage *myImage = [segmentedControl imageForSegmentAtIndex:3]; //讀取圖片 //設置片斷寬度 [segmentedControl setWidth:64.0 forSegmentAtIndex:0]; //瞬時單擊 segmentedControl.momentary = YES; //按鈕被按下後很快恢復,默認爲選中狀態就一直保持 //初始化默認片斷 segmentedControl.selectedSegmentIndex = 0; //初始指定第0個選中 //顯示控件 [parentView addSubview:segmentedControl]; //添加到父視圖 self.navigationItem.titleView = segmentedControl; //添加到導航欄(經過視圖控制器) //讀取控件 int selectIndex = segmentedControl.selectedSegmentIndex; //對應當前被選總的片斷號碼 [segmentedControl addTarget:selfaction:@selector(controlPressed:) forControlEvents:UIControlEventValueChanged];
}
//SegmentedControl觸發的動做
-(void)controlPressed:(id)sender{
UISegmentedControl *control = (UISegmentedControl *)sender;
if (control == mySegmentedControl) {
int x = control.selectedSegmentIndex;
/*添加代碼,對片斷變化作出響應*/
}
}
(三)5.UIPickerView 選擇器
1.UIPickerView的初始化
1
2
3
|
pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0f, 200.0f, 320.0f, 216.0f)];
pickerView.delegate =
self
;
//指定Delegate
pickerView.showsSelectionIndicator =
YES
;
//顯示選中框
|
2.實現UIPickerViewDelegate和UIPickerViewDataSource
1
2
3
4
5
6
7
|
- (
NSInteger
)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
//返回列數
- (
NSInteger
)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(
NSInteger
)component;
//返回每列的最大行數
- (
NSString
*)pickerView:(UIPickerView *)pickerView titleForRow:(
NSInteger
)row forComponent:(
NSInteger
)component;
//每一列中每一行的具體內容
- (
void
)pickerView:(UIPickerView *)pickerView didSelectRow:(
NSInteger
)row inComponent:(
NSInteger
)component
//選中哪一列哪一行
|