iOS SDK:創建一個自定義文本輸入框



創建一個好的應用不是一件簡單的事,一般來說,最難做的是創建一個內容豐富,吸引人的界面。這個教程教你如何創建一個自定義的文本輸入框。 啓動Xcode,創建一個Single View Application 1.創建

本文由會員代號101投稿分享。

 

目前,我們正在舉辦徵稿活動,每月都會評選出最優秀文章,本月徵稿活動一等獎獎勵iPad Mini一個,如果您有好的文章,歡迎參加活動,查看徵稿活動詳情,如有任何疑問,可聯繫QQ:2408167315

 

創建一個好的應用不是一件簡單的事,一般來說,最難做的是創建一個內容豐富,吸引人的界面。這個教程教你如何創建一個自定義的文本輸入框。 

 

啓動Xcode,創建一個Single View Application 

 

1.創建項目 

 

啓動Xcode,創建一個Single View Application 

給項目命名,我的命名是CustomViewsDemo。 勾選Use Automatic Reference Counting。 

 最後,選擇一個文件夾來保存這個項目,然後點擊創建: 

 

 2.配置界面 

 

步驟1 

 

點擊 ViewController.xib,打開Interface Builder。 首先反選Autolayout(這麼做的原因是讓這個demo可以在iOS 6之前的系統運行,Autolayout是iOS 6的功能): 

 

--如果Utilities面板看不到的話,找到Xcode工具欄,點擊Utilities 按鈕 。 

 

--點擊File Inspector. 

 

--下拉框,找到Use Autolayout選項,反選。 

 

 步驟2

 

點擊Attributes Inspector ,在Simulated Metrics標籤下設置Size爲None,這麼做可以讓項目可以在3.5寸的顯示屏上運行。 

 步驟3 

 

添加一個UIToolbar到視圖,將其放置在底部。 

 

 

--添加一個Flexible Space Bar Button item到默認的Bar Button Item左側,讓它留在工具欄左側。 

 

--設置bar button item的名字。 

 

--設置button的顏色爲:(R:51,G:51,B:51)。 

 

--設置工具欄toolbar的顏色爲:(R:0,G:0,B:51)。 

 

步驟4 

 

下一步,添加一個 UITableView,放到剩下的空間裏。設置Style樣式爲Grouped,設置Separator爲Single Line。 

 

同時選擇背景顏色爲:(R: 51, G: 51, B: 51)。現在你的界面看上去會是這個樣子: 

 

 3.IBOutlet 屬性以及 IBAction 用法 

 

到下一步之前,我們要先把UITableView鏈接到一個IBOutlet屬性裏,然後給工具欄的bar button item(即Add item按鈕)創建一個IBaction方法。可以這麼做,在Interface Builder 

 

中,點擊Xcode工具欄上的編輯控件的中間的按鈕來隱藏Assistant Editor。 

 

 

步驟1, 

 

按住Ctrl鍵右擊Table View,然後點擊New Referencing Outlet,把它拖拽到Assistant Editor裏,這樣做就插入了一個新的IBOutlet屬性。 

 

下一步給這個新屬性命名,我給它命名爲table。 

 

 步驟2 

 

按住Ctrl鍵右擊 Bar Button item,點擊Sent Action的Selector,把它拖拽到Assistant Editor,這麼做就創建了一個IBAction。 

 

 

 給這個方法命名。我給他命名爲addItem。 

 

 

 4. UItableView用法 

 

 步驟1 

 

爲了使我們的table正確的工作,這一步我們需要調用一個minimum required table view方法。在這麼做之前,首先我們需要設置table view 

 

點擊 ViewController.h 文件,定義 @interface頭文件 

 

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> 

 

進入了ViewController.m文件,在viewDidLoad下加入以下代碼: 

 

// Set the tableview's delegate and datasource. 

 

[_table setDelegate:self];

 

[_table setDataSource:self]; 

 

步驟2 

 

一個NSMutableArray序列會成爲我們列表項目的來源(表的內容)。首先,我們需要聲明和初始化這個序列。進入 ViewController.m文件,找到最開始的部分,在 @interface 部分加上以下代碼:

 

@interface ViewController () 

 @property (nonatomic, strong) NSMutableArray *sampleDataArray; 

 @end 

 

同時在viewDidload加上:

 

// Initialize the sample data array. 

 _sampleDataArray = [[NSMutableArray alloc] init]; 

 

步驟3: 

 

接入table view的methods。首先加上sections的編號

 

-(int)numberOfSectionsInTableView:(UITableView *)tableView{ 

 // Set the number of sections inside the tableview. We need only one section. 

 return 1; 

 }

然後設置序列的總數。總數和_sampleDataArray序列中的全部對象數相同

 

-(int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 

 // The number of rows is equal to the number of the sample data in our tableview. 

 return [_sampleDataArray count]; 

 

然後設置每列的高度:

 

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 

 // Set the row height. 

 return 45.0; 

 

 

現在,設置我們的view。在代碼裏面你可以找到所有view的定製信息。有詳細註釋。也可以根據你的想法進行定製:

 

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 

 static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) { 

        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 

        // Let's set some custom cell options. 

        // Set the cell's background. 

        [cell setBackgroundColor:[UIColor colorWithRed:0.8 green:0.8 blue:0.8 alpha:1.0]]; 

        // Set the selection style. 

        [cell setSelectionStyle:UITableViewCellSelectionStyleGray]; 

        // Set the accessory type. 

        [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; 

        // Set a font for the cell's textlabel. 

        [[cell textLabel] setFont:[UIFont fontWithName:@"Georgia" size:15.0]]; 

    } 

    [[cell textLabel] setText:[_sampleDataArray objectAtIndex:[indexPath row]]]; 

    return cell; 

 

這部分暫時這樣,過會兒再來。 

 

總結一下,至今我們現在已經創建了項目, 使用Interface Builder創建了界面。連接了必須的IBOutlet屬性以及IBAction方法,接入了可以讓我們的table基本順利工作的方法。現在讓我們去創建一個自定義的文本輸入框。待會兒再繼續使用ViewController 

 

5.Custom Text Input View Controller 

 

在開發的時候,保持所有代碼整潔有序是非常好的習慣。所以,我們要爲 text input view controller創建一個新的group。

 

步驟1

 

找到在Xcode左側的Project Navigation面板,按住Ctrl鍵右擊CustomViewsDemo group ,然後從彈出的目錄中選擇New Group 項。

 

 

 給這個New Group 命名爲:Custom Text Input View 

 

 

 步驟2 

 

現在我們準備添加新的view controller。按住Ctrl鍵右擊CustomViewsDemo group ,選擇New File,

 

 

這個新文件的模板選擇Objective-C class,點擊Next下一步。

 

 

在Class框中輸入CustomTextInputViewController ,選擇 Subclass of框中的UIviewController,勾選With XIB for user interface選項 。 

 

 

最後,點擊Create按鈕。確保選中了Custom Text Input View ,如下圖所示:

 

6. Text Input View's Interface文本輸入框界面 

 

步驟1 

 

點擊 CustomTextInputViewController.xib 文件隱藏Interface Builder,創建界面。

 

--和先前做的一樣,反選Autolayout 選項(Utilities面板>File Inspector>點擊Use Autolayout checkbox 

 

--點擊Attributes Inspector ,在Simulated Metrics下把Size選爲None。 

 

步驟2

 

現在可以添加我們想要的subviews到我們的view裏了。根據以下辦法來增加subviews,同時選擇他們的屬性 

 

1. UILabel 

 

o Frame: X: 0.0, Y: 145.0, Width: 320.0, Height: 30 

 

o Font:: Georgia, 17.0 

 

o Color:: Black 

 

o Alignment:: Center 

 

o Background Color: (R: 204, G: 204, B: 204) 

 

2. UITextField 

 

o Frame: X: 0.0, Y: 180.0, Width: 320.0, Height: 30.0 

 

o Font: Georgia, 15.0 

 

o Color: Black 

 

o Border Style: Bezel 

 

o Clear button: Appears while editing 

 

o Capitalization:Sentences 

 

o Return Key: Done 

 

o Background Color: White 

 

大部分設置都會出現在下面的圖像中。

 

 

3. UIToolBar 

 

o Frame: X: 0.0, Y: 225.0, Width: 320.0, Height: 44.0 

 

o Tint Color: (R: 204, G: 204, B: 204) 

 

注意Y座標現在並不重要,因爲根據每個subview的不同,他會自動調整。 

 

步驟3 

 

添加以下的UIBarButton項 到toolbar,緊鄰默認的bar button按鈕項 

 

" A flexible space bar button item 

 " Another bar button item 

 

同時選擇這兩個bar button items(不選flexible space item),設置他們的顏色爲: (R: 51, G: 51, B: 51)。左邊的bar button按鈕命名爲Okay。右邊的bar button按鈕命名爲Cancel 

 

最後,選擇所有的三個subviews(UILable,UITextField,以及UIToolBar),設置Autosizing的值如下所示( Flexible Width, Flexible Right Margin, Flexible Left Margin, and Flexible Bottom Margin

 

7. IBOutlets & IBActions

 

之前我向大家展示瞭如何創建IBOutlet屬性以及IBAction方法,以及如何把他們和subviews鏈接起來。重複之前的步驟,創建並且分別連接屬性到UILabel UITextField,, UIToolbar。 

 

@property (weak, nonatomic) IBOutlet UILabel *lblTitle; 

 @property (weak, nonatomic) IBOutlet UITextField *txtText; 

 @property (weak, nonatomic) IBOutlet UIToolbar *toolbarIAV;

 

然後聲明並鏈接下一個IBAction到Okay和Cancel按鈕。

 

- (IBAction)acceptTextChanges:(id)sender; 

 - (IBAction)cancelTextChanges:(id)sender; 

 

至此Interface Builder的工作就結束了。現在可以編碼我們文本框的屬性了。 

 

 

8. 編碼 

 

步驟1 

 

首先我們要設置view controller爲文本框的delegate。點擊CustomTextInputViewController.h文件,修改 @interface頭文件爲: 

 

@interface CustomTextInputViewController : UIViewController 

 

然後, 到CustomTextInputViewController.m文件,在viewDidLoad中設置delegate。 

 

// Set the textfield delegate. 

[_txtText setDelegate:self]; 

 

同時到 viewDidLoad 設置UIToolbar作爲文本框的 Input Accessory View 。 

 

// Set the textfield delegate.

[_txtText setDelegate:self];

// Set the input accessory view of the textfield.

[_txtText setInputAccessoryView:_toolbarIAV];

 

到目前爲止,非常好。在本教程的開頭,我提到了view controller的view會作爲一個防護性的東西,目的是防止用戶在我們的view之外輸入內容。同時我們也要讓view變成半透明的,這樣看上去會比較好看。所以添加下面的代碼來修飾我們的view。 

 

// Set the background color of the view to a semi-transparent gray. 

[self.view setBackgroundColor:[UIColor colorWithRed:0.66 

                                                  green:0.66 

                                                  blue:0.66 

                                                  alpha:0.75]]; 

 

現在來思考一下。之前說的,我們需要文本框在input accessory view(toolbar)正上方顯現,同時標題標籤出現在文本框上方。要做到這樣,我們需要知道鍵盤框和input accessory view的起點,這樣我們可以依次調整文本框和標籤。但是我們怎麼知道什麼時候出現鍵盤,怎麼得到它的大小以及起點呢? 

 

答案很簡單,每次鍵盤快要出現的時候,iOS會發送一個通知,叫做UIKeyboardWillShowNotification(實際上,iOS會發送很多通知,但現在我們沒必要管它們)。我們可以添加view controller來接收這個通知,當通知發送過來的時候會call一個預先定義的方法(這個我們來添加)。添加下面的代碼,進入viewDidLoad方法。 

 

// Add self as observer to the NSNotificationCenter so we know when the keyboard is about to be shown up. 

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShowWithNotification:) name:UIKeyboardWillShowNotification object:nil]; 

 

注意 keyboardWillShowWithNotification,這個我們待會兒要接入的。 

 

我們還要考慮一下status bar。我們的subviews的顯現位置取決於status bar和它的高度。因此,如果我們有一個status bar(以它的高度)創造出來的偏移距離變量會非常好。 

 

到文件的頭部,在@interface的private part聲明一個CGFloat變量,這個變量會代表status bar的偏移距離。 

 

同時聲明 keyboardWillShowWithNotification: 

 

@interface CustomTextInputViewController (){ 

    CGFloat statusBarOffset; 


-(void)keyboardWillShowWithNotification:(NSNotification *)notification; 

@end 

 

過會兒再來管status bar。 

 

步驟2 

 

現在我們要開始到接入階段了。這樣我們可以創建一個必須的public methods,這個方法可以被其他classes接入。 

 

每個方法要做什麼必須很清楚。 

 

-(void)showCustomTextInputViewInView:(UIView *)targetView 

                            withText:(NSString *)text 

                            andWithTitle:(NSString *)title; 

-(void)closeTextInputView; 

-(NSString *)getText; 

 

首先是showCustomTextInputViewInView:withText:andWithTitle  method。開始編碼之前,有幾點必須提一下。首先,我們要檢查status bar是否可見,設好statusBarOffset的value。我們可以輕易看出它是否可見,然後得到它的size。然而,如果status bar是可見的話,這兒有個小陷阱,我們需要處理portrait 和landscape方向。在portrait模式下,status bar的尺寸是寬*高的,而landscape模式下尺寸大小是高*寬的。對我們來說,最簡單的確定status bar的高度是檢查寬和高的最小值。使用這個方法我們一定可以得出正確的值來。把這個加到接下來的代碼裏。 

 

你可能還記得我們把Autolayout功能給關閉了,所以我們必須確保我們view的方向是正確的。 這就意味着我們每次調用這個方法的時候都必須檢查一下方向,並且以此設定view的框架 

 

必須注意到在landscape模式下屏幕的寬度是view的高度,而屏幕的高度則是view的的高度。同時由於status bar是可見的,在landscape模式下,在view的左邊會有一塊邊距,這個邊距是需要消除的。 

 

這就是爲什麼之前我們需要聲明 statusBarOffset。 

 

最後,我們希望的是最開始的時候view是不顯現的,伴隨着動畫,它慢慢出現在屏幕上。 

 

現在來演示一下。打開CustomTextInputViewController.m,接入以下method; 

 

-(void)showCustomTextInputViewInView:(UIView *)targetView withText:(NSString *)text andWithTitle:(NSString *)title{ 

if (![[UIApplication sharedApplication] isStatusBarHidden]) { 

        CGSize statusBarSize = [[UIApplication sharedApplication] statusBarFrame].size; 

        if (statusBarSize.width < statusBarSize.height) { 

            // If the width is smaller than the height then this is the value we need. 

            statusBarOffset = statusBarSize.width; 

        } 

        else{ 

            // Otherwise the height is the desired value we want to keep. 

            statusBarOffset = statusBarSize.height; 

        } 

    } 

    else{ 

        // Otherwise set it to 0.0. 

        statusBarOffset = 0.0; 

    } 

    // Before showing the self.view on-screen, we need to calculate the following 

    // values, depending always on the orientation. 

    CGFloat x, width, height; 

    if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || 

        [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight){ 

        // Landscape orientation. 

        // Set the x point for the view. If we don't substract the statusBarOffset value then a 

        // padding is going to exist at the left of the view when it will appear. 

        x = targetView.frame.origin.x - statusBarOffset; 

        // In landscape orientation, the width of the view equals to the height of the target view. 

        width = targetView.frame.size.height; 

        // The same with the height. 

        height = targetView.frame.size.width; 

    } 

    else{ 

        // In portrait orientation everything is normal. 

        x = targetView.frame.origin.x; 

        width = targetView.frame.size.width; 

        height = targetView.frame.size.height; 

    } 

    // Initially set the self.view off screen. That's why the y point equals to -height. 

    [self.view setFrame:CGRectMake(x, 

                                   -height, 

                                   width, 

                                   height)]; 

    // Add the view to the target view. 

    [targetView addSubview:self.view]; 

    // Begin animating the appearance of the view. 

    [UIView beginAnimations:@"" context:nil]; 

    [UIView setAnimationDuration:0.25]; 

    [UIView setAnimationCurve:UIViewAnimationCurveLinear]; 

    // We simply want the y point of the origin to become 0.0. 

    [self.view setFrame:CGRectMake(self.view.frame.origin.x, 

                                   0.0, 

                                   self.view.frame.size.width, 

                                   self.view.frame.size.height)]; 

    [UIView commitAnimations]; 

    // Set the textfield as the first responder to make the keyboard appear. 

    [_txtText becomeFirstResponder]; 

    // Set the text to edit (if exists) to the textfield. 

    [_txtText setText:text]; 

    // Set the label's text (the title above the textfield). 

    [_lblTitle setText:title]; 

 

代碼的註釋已經解釋的很清楚了。注意在內部我們調用了 _txtText文本框的becomeFirstResponder 方法,這樣做輸入鍵盤也會顯現。不久我們就可以看到這個調用有多麼的重要,這是我們view在正確的位置出現的關鍵點。 

 

現在,讓我們來接入下一個方法。view的關閉和他的顯現方式是正好相反的。 

 

-(void)closeTextInputView{ 

    // Resign the textfield from first responder to make the keyboard go away. 

    [_txtText resignFirstResponder]; 

    // Animate the view closing. It's just the opposite from the showing animation. 

    [UIView beginAnimations:@"" context:nil]; 

    [UIView setAnimationDuration:0.25]; 

    [UIView setAnimationCurve:UIViewAnimationCurveLinear]; 

    [self.view setFrame:CGRectMake(self.view.frame.origin.x, 

                                   -self.view.frame.size.height, 

                                   self.view.frame.size.width, 

                                   self.view.frame.size.height)]; 

    [UIView commitAnimations]; 

    // Also remove the view from the superview after a while (we must let the animation finish first). 

    [self.view performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:0.25]; 

 

請注意,我們不是立刻把view從superview上移除的,而是等到動畫結束以後。 

 

最後,是第三個方法。 

 

-(NSString *)getText{ 

// Return the textfield's text. 

    return [_txtText text]; 

 

步驟3 

 

這一步會向您展示如何處理輸入鍵盤。在界面的private部分我們申明瞭下面這個方法: 

 

-(void)showCustomTextInputViewInView:(UIView *)targetView withText:(NSString *)text andWithTitle:(NSString *)title; 

 

 

每次輸入鍵盤將要出現的時候這個method會被調用,同時UIKeyboardWillShowNotification會發送通知。通知參數包含了一個NSDictionary,這裏麪包含了關於輸入鍵盤的信息。裏面有鍵盤的大小以及出現的座標。我們這兒需要的是座標點,因爲如果我們知道鍵盤出現的Y座標,我們就可以合理的分配輸入框和label。同樣的,在landscape模式下鍵盤的x座標和y座標是正好相反的。 

 

以下是需要用到的代碼: 

 

-(void)keyboardWillShowWithNotification:(NSNotification *)notification{ 

    // Get the userInfo dictionary from the notification object. 

    NSDictionary *info = [notification userInfo]; 

    // Get the keyboard origin. 

    CGPoint keyboardOrigin = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].origin; 

    CGFloat keyboardOriginY; 

    if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || 

        [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight){ 

        // In landscape orientation the x point represents the vertical axis. 

        keyboardOriginY = keyboardOrigin.x; 

    } 

    else{ 

        keyboardOriginY = keyboardOrigin.y; 

    } 

    // Set the appropriate frame for the textfield. That is just right above the input accessory view. 

    [_txtText setFrame:CGRectMake(_txtText.frame.origin.x, 

                                  keyboardOriginY - _txtText.frame.size.height - statusBarOffset, 

                                  _txtText.frame.size.width, 

                                  _txtText.frame.size.height)]; 

    // Set the label's frame in turn. 

    [_lblTitle setFrame:CGRectMake(0.0, 

                                   _txtText.frame.origin.y - _lblTitle.frame.size.height, 

                                   _lblTitle.frame.size.width, 

                                   _lblTitle.frame.size.height)]; 

 

我相信你肯定注意到了statusBarOffset的subtraction。如果我們不這樣做的話,文本框會被input accessory view給遮擋住。 

 

步驟4 

 

我們現在需要定義協議了。到這一步, view controller現在基本準備完畢,但是還差最後一點工作。現在缺的是定義協議,這個協議可以讓使用的delegate class(在我們的例子裏是viewcontroller)接入可以處理Okay和Cancel按鈕的必要方法。 

 

找到CustomTextInputViewController.h文件,然後定義一個協議,附上下面的delegate方法: 

 

@protocol CustomTextInputViewControllerDelegate

-(void)shouldAcceptTextChanges;

-(void)shouldDismissTextChanges;

@end

 

同時,在@interface頭文件後,加上下面的代碼: 

 

@interface CustomTextInputViewController : UIViewController

@property (nonatomic, strong) id delegate;

...

...

 

這麼做了以後,delegate class就應該和shouldAcceptTextChanges method鏈接好了,可以處理觸碰okay按鈕,shouldDismissTextChanges method也鏈接好了,可以處理觸碰Cancel按鈕。 

 

但是,這個class裏的IBAction 方法有什麼作用呢?現在這一片是沒有用上的。讓我們輸入以下代碼: 

 

- (IBAction)acceptTextChanges:(id)sender { 

[self.delegate shouldAcceptTextChanges]; 


- (IBAction)cancelTextChanges:(id)sender { 

    [self.delegate shouldDismissTextChanges]; 

 

觸碰okay按鈕的時候shouldAcceptTextChanges的delegate method會被調用,觸碰cancel按鈕的時候shouldDismissTextChanges的delegate方法會被調用。 

 

但是爲了完全正確,還有一步要做:要讓鍵盤的Done 按鈕可以使用。這麼做,我們必須接入 -(BOOL)textFieldShouldReturn的delegate method。 

 

-(BOOL)textFieldShouldReturn:(UITextField *)textField{ 

// The tap on the Done button of the keyboard equals to the Okay button. 

    [self.delegate shouldAcceptTextChanges]; 

    return YES; 

 

現在我們新的自定義view就準備好了。 

 

9.文本輸入框投入使用 

 

步驟1 

 

在我們見證新的自定義文本輸入框工作之前,還有幾步工作需要做。首先,我們必須聲明ViewController class作爲它的 delegate委託類。打開ViewController.h文件,導入 CustomTextInputViewController.h 文件,讓我們的class的delegate在interface頭文件調用。 

 

#import <UIKit/UIKit.h> 

#import "CustomTextInputViewController.h" 

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, CustomTextInputViewControllerDelegate> 

@property (weak, nonatomic) IBOutlet UITableView *table; 

... 

... 

 

現在找到ViewController.m文件,在@interface的private part聲明一個CustomTextInputViewController對象。我把它命名爲 textInput。 

 

@interface ViewController () 

@property (nonatomic, strong) NSMutableArray *sampleDataArray; 

@property (nonatomic, strong) CustomTextInputViewController *textInput; 

@end 

 

初始化viewDidLoad方法: 

 

// Initialize the custom text input object. 

_textInput = [[CustomTextInputViewController alloc] init]; 

[_textInput setDelegate:self]; 

 

步驟2 

 

調用addItem IBAction method讓我們的文本輸入框顯現: 

 

- (IBAction)addItem:(id)sender { 

[_textInput showCustomTextInputViewInView:self.view 

                                    withText:@"" 

                                    andWithTitle:@"Add new item"]; 


很簡單,不是嗎? 

 

如果我們現在運行應用,你就會看到文本輸入框已經可以使用了,但是okay和cancel按鈕還不行,這是因爲我們還沒有接入delegate方法。加上以下代碼: 

 

-(void)shouldAcceptTextChanges{ 

    // Add the new item to the sampleDataArray. 

    [_sampleDataArray addObject:[_textInput getText]]; 

    // Reload the table using animation. 

    [_table reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic]; 

    // Close the text input. 

    [_textInput closeTextInputView]; 


-(void)shouldDismissTextChanges{ 

    [_textInput closeTextInputView]; 

 

運行,現在這兩個按鈕就可以工作了。你可以任意輸入文字,但是還沒有完成,我們還不能編輯任何items。 

 

步驟3 

 

現在我們需要訪問table view的delegate方法了, -(void)tableView:didSelectRowAtIndexPath。我們想要我們輸入的文字都能進行編輯。於是我們還需要知道用戶什麼時候增加或者編輯文字。所以我們必須使用一個flag來判斷表明我們的用戶是否要編輯文字。 

 

找到@interface的private part,加入以下變量: 

 

@interface ViewController (){

BOOL isEditingItem;

}

@property (nonatomic, strong) NSMutableArray *sampleDataArray;

@property (nonatomic, strong) CustomTextInputViewController *textInput;

@end

 

  

不要忘記加上大括號。進入 viewDidLoad設置value值爲NO。 

 

// Set the initial value of the isEditingItem flag. 

isEditingItem = NO; 


現在到table的 delegate method: 

 

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 

    [_textInput showCustomTextInputViewInView:self.view 

                                    withText:[_sampleDataArray objectAtIndex:[indexPath row]] 

                                    andWithTitle:@"Edit item"]; 

    // Set the isEditingItem flag value to YES, indicating that 

    // we are editing an item. 

    isEditingItem = YES; 

 

到了這個階段,當你觸碰在文本框中的文字時,文本輸入框就會出現,可以對文字進行編輯了。但是無論你怎麼努力,你編輯的都無法保存替代掉舊的文本,而會以新的文本形式存儲起來。這就說明我們還需要做一些小調整,修改 -(void)shouldAcceptTextChanges 的delegate method如下; 

 

-(void)shouldAcceptTextChanges{

    // If the isEditingItem flag is set to NO, then a new item has been

    // added to the list. Otherwise an existing item has been edited.

    if (!isEditingItem) {

        // Add the new item to the sampleDataArray.

        [_sampleDataArray addObject:[_textInput getText]];

    }

    else{

        // Replace the selected item into the array with the updated value.

        NSUInteger index = [[_table indexPathForSelectedRow] row];

        [_sampleDataArray replaceObjectAtIndex:index withObject:[_textInput getText]];

        // Set the isEditingItem flag to NO.

        isEditingItem = NO;

    }

    // Reload the table using animation.

    [_table reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];

    // Close the text input.

    [_textInput closeTextInputView];

}

 

記得當修改文本內容的時候,在相同的數據序列中的同等對象會被替換。同時,還要注意isEditingItem,它取得是NO值。 

 

現在,所有問題都解決了。運行然後在portrait模式和landscape模式下都測試下吧。 

 

 

 查看原帖:http://www.cocoachina.com/bbs/read.php?tid=140617&page=1&toread=1#tpc

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章