IOS 簡潔輸入框的實現
要的功能有 有一個placeholder的文字作為提示,點擊輸入文字後消失,當刪除後文字為空白的時候,重新出現。文字框下面有一條藍色線表示輸入的框範圍,類似我們裡面的那個綠色的輸入框文字框需要跟隨鍵盤上下浮動,再輸入文字後能自動調整大小和位置右邊的發送按鈕,在沒有文字的時候是灰色的,提示無法發送,當輸入文字框不為空白的時候,可以發送,用藍色來表示,而且需要根據左邊的輸入框高度變化而變化頂部有一條和底部視圖分界的線在輸入完成後,點擊鍵盤的完成或者點擊發送按鈕能輸出文字通過功能區分我們可以大致將該視圖分成三個部分,第一個是分割線,寬度為1的UIView,第二個是類似html中的具有placeHolder功能的輸入框,最後是按鈕button。 輸入文字框的實現輸入框是由UILabel+UITextView+UIImageView(藍色線)實現的,UITextView的內容長度變化可以通過監聽UITextViewTextDidChangeNotification來判斷當前輸入框的輸入字數。先建一個類繼承UITextView添加placeText和placeColor到標頭檔由於外部改變placetext內容,現在添加UILable -(void)PlaceTextLabel{ if (self.placeText.length>0) { if (!_placeTextLab) { CGRect frame=CGRectMake(8,8, self.bounds.size.width-16, 0); _placeTextLab=[[UILabel alloc]initWithFrame:frame]; _placeTextLab.font=self.font; _placeTextLab.backgroundColor=[UIColor clearColor]; _placeTextLab.textColor=self.placeColor; _placeTextLab.tag=999; _placeTextLab.alpha=0; _placeTextLab.lineBreakMode=NSLineBreakByWordWrapping; _placeTextLab.numberOfLines=0; [self addSubview:_placeTextLab]; } _placeTextLab.text=self.placeText; [_placeTextLab sizeToFit]; [_placeTextLab setFrame:CGRectMake(8, 8, CGRectGetWidth(self.bounds)-16, CGRectGetHeight(_placeTextLab.frame))]; } if (self.text.length==0 && self.placeText.length>0) { [[self viewWithTag:999]setAlpha:1.0]; }}用Photoshop做一個單行像素的類似藍線的圖片,儲存為png格式,必須設定圖片的UIImageView的圖片顯示模式 -(void)addLineView{ [_subLine removeFromSuperview]; _subLine=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"subline.png"]]; [_subLine setContentMode:UIViewContentModeScaleToFill]; [self addSubline:_subLine]; }UITextView的設定會相對麻煩一些,重寫初始化代碼 -(instancetype)initWithFrame:(CGRect)frame PlaceText:(NSString *)placeText PlaceColor:(UIColor *)placeColor{ self=[super initWithFrame:frame]; if (self) { self.scrollEnabled=NO; _placeText=placeText; _placeColor=placeColor; _Textnil=YES; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(TextChange:) name:UITextViewTextDidChangeNotification object:nil]; } return self;}由於輸入框會隨著輸入的文字而不斷增高,我們需要把這個值傳遞給父視圖,讓父視圖也能根據內容而增大,可以通過委託來,但是委託又有點重量級,這裡我們可以用更簡單的block 這裡首先我想到的是通過監聽UITextViewTextDidChangeNotification來即時監測輸入,輸入即時變化引起高度的即時變化。但是不幸的是我掉坑裡了,我發現當我們輸入一行到頭以後再輸入一個字元換行後,這個時候高度居然沒有變。再輸入這一行的第二個字元時候,高度值才發生變化。我想應該是高度變化之前,已經發送了通知所以導致我們的高度變化其實不是即時的,如果這樣就不能用這種方式了,所幸的我們還可以使用UITextView的一個簡單函數 CGSize size= [self sizeThatFits:CGSizeMake(self.contentSize.width, 1000.0)];這樣size就是我們要的大小了。 -(void)TextChange:(NSNotification *)notification{ if (self.text.length==0) { _Textnil=YES; }else{ _Textnil=NO; } [self addLineView]; if (self.placeText.length==0) { return; } [UIView animateWithDuration:0.5 animations:^{ if (_Textnil) { [[self viewWithTag:999]setAlpha:1.0]; }else{ [[self viewWithTag:999] setAlpha:0]; } }]; }-(void)addSubline:(UIView *)view{ CGSize size= [self sizeThatFits:CGSizeMake(self.contentSize.width, 1000.0)]; if (view) { CGRect frame=CGRectMake(2, size.height-3, self.bounds.size.width-4, 3.0); view.frame=frame; } [self addSubview:view]; self.viewSize(size);//先判斷一下更好。。。}這裡使用block傳遞size,我們先聲明一個block的私人變數,再寫一個方法用來賦值,block的實現也是由調用該對象的類建立的。然後像委託一樣調用就可以,AFNetwork中我們可以到處看到block而不像他的前輩ASIhttprequest到處是委託。 組裝主要的輸入框完工後,就能組裝了,先建立一個UIview子類。UIView需要和鍵盤高度保持一致。需要監聽鍵盤滑出滑入的通知UIKeyboardWillChangeFrameNotification,即時改變輸入框的高度 -(void)keyboardWillShow:(NSNotification *)notification{ NSDictionary *userInfo=[notification userInfo]; NSTimeInterval boardAnimationDuration=[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; CGRect frame=[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey]CGRectValue]; [UIView animateWithDuration:boardAnimationDuration delay:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{ CGFloat keyBoardY=frame.origin.y; CGFloat keyBoardHeigh=frame.size.height; maxy=[UIScreen mainScreen].bounds.size.height-keyBoardHeigh; CGRect frame=self.frame; frame.origin.y=keyBoardY-CGRectGetHeight(self.frame); self.frame=frame; } completion:^(BOOL finished) { nil; }];}這裡的maxY是指輸入框的y方向的標準位置。在沒有鍵盤的情況下是[UIScreen mainScreen].bounds.size.height,在有鍵盤的情況是鍵盤的y值,在輸入框字元變化的時候即時改變他的高度 如下面圖所示 -(void)TextViewDidChange:(CGSize)size{ self.frame=CGRectMake(0, self.frame.origin.y, self.frame.size.width,size.height+6*2); self.frame=CGRectMake(0,maxy-self.frame.size.height, self.frame.size.width, self.frame.size.height); _Inputview.frame=CGRectMake(10, 6, self.frame.size.width-K_right_padding, size.height); }以上是比較重要的UIView高度自適應變化的問題 這裡button與外部類的調用關係也採用的是block的方式 @property (nonatomic,copy)void(^sendText)(NSString *);-(void)sendMessage:(void (^)(NSString * text))inputText{ if (inputText) { self.sendText=inputText; }}-(void)buttonClick{ [self sendInputText];}-(void)sendInputText{ if (_Inputview.Textnil) { return; }else{if(self.sendText){ self.sendText(_Inputview.text); _Inputview.text=@"";} }}