步驟:發微博01-導航欄內容 -> 發微博02-自定義TextView -> 發微博03-完善TextView和發送微博按鈕 -> 發微博04-顯示工具條 -> 發微博05-封裝工具條和相冊 -> 發微博06-發送微博
發微博01-導航欄內容
APP的演示操作:
從APP的演示操作中可知,當點擊tabBar的“+”按鈕時APP會以modal的方式跳轉到發微博的控制器。實現代碼如下:
在HMComposeViewController類的viewDidLoad方法中,設置導航欄內容,并添加輸入控件(用于輸入微博正文),如下:
HMComposeViewController類的初始化方法如下:
發微博02-自定義TextView
APP的演示操作:
前文中,已經初步添加了輸入控件UITextView,但是輸入控件UITextView并不能完全滿足我們的要求,即無法實現占位文字。
所以,新建了一個繼承自UITextView的HMTextView類,將占位文字的實現以及輸入控件的具體邏輯都封裝到HMTextView類中,只將占位文字和占位文字顏色兩個屬性提供給外界(HMComposeViewController類)使用。如下:
在HMTextView類中,占位文字的實現有多種方式:第一種是添加UILabel,第二種是重寫drawRect:方法。在這里,我們采用的是第二種方式。重寫drawRect:方法,如下:
觀察APP的演示操作,一開始進入發微博界面時,輸入控件上顯示的是“分享新鮮事”,當我們輸入文字后,“分享新鮮事”就會“消失”。這里的實現原理是通知。具體代碼如下:
注意:這里不適合使用代理,用通知即可。發出通知后,會觸發textDidChange事件,然后重新調用drawRect方法進行重繪。
發微博03-完善TextView和發送微博按鈕
APP的演示操作:
在前文的基礎上繼續完善輸入控件,并且當有輸入文字后,導航欄的右邊發送按鈕可以響應(發送微博)。
參考前面,HMComposerViewController監聽輸入文字同樣是采用通知的方式。如下:
其中,textDidChange方法的具體代碼如下:
在HMComposerViewController中,監聽方法send是用于發送微博,具體代碼如下:
說明:
1.完善前文中設置導航欄內容的代碼,要考慮是否有微博名,如下:
2.HMTextView類聲明了兩個屬性placedholder和placedholderColor,由于這兩個屬性不是系統屬性,所以在優先級上會較低,我們有時候需要重寫它們的setter方法,如下:
3.每一次使用通知,都要注意調用dealloc方法,移除觀察者。如下:
發微博04-顯示工具條
APP的演示操作:
仔細觀察APP的演示操作,工具條一開始是顯示在屏幕底部,當鍵盤彈出時工具條才移動到鍵盤的頂部。
在HMComposeViewController的viewDidLoad方法添加工具條,如下:
其中,setupToolBar方法如下:
問題:對于工具條的類HMComposerToolbar暫時不要考慮,先弄明白為什么當鍵盤一出現工具條就會移動鍵盤的頂部?實現原理是什么?
思路:
1.鍵盤會在進入發微博頁面后就彈出是因為調用了viewDidAppear:方法,如下:
2.彈出鍵盤后移動工具條,這是因為當鍵盤的frame發生改變時就會發出通知UIKeyboardWillChangeFrameNotification,觸發keyboardWillChangeFrame:事件, 執行動畫移動工具條,如下:
其中,keyboardWillChangeFrame:方法,如下:
在HMComposerToolbar類(繼承自UIView)中,設置工具條上的按鈕。具體代碼如下:
@implementation HMComposeToolbar
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"compose_toolbar_background"]];
//初始化按鈕
[self setupBtn:@"compose_camerabutton_background" highImage:@"compose_camerabutton_background_highlighted"];
[self setupBtn:@"compose_toolbar_picture" highImage:@"compose_toolbar_picture_highlighted"];
[self setupBtn:@"compose_mentionbutton_background" highImage:@"compose_mentionbutton_background_highlighted"];
[self setupBtn:@"compose_trendbutton_background" highImage:@"compose_trendbutton_background_highlighted"];
[self setupBtn:@"compose_emoticonbutton_background" highImage:@"compose_emoticonbutton_background_highlighted"];
}
return self;
}
/**
* 創建一個按鈕
*/
- (void)setupBtn:(NSString *)image highImage:(NSString *)highImage
{
UIButton *btn = [[UIButton alloc] init];
[btn setImage:[UIImage imageNamed:image] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted];
[self addSubview:btn];
}
/**
* 設置按鈕的尺寸
*/
- (void)layoutSubviews
{
[super layoutSubviews];
//設置按鈕的frame
NSUInteger btnCount = self.subviews.count;
CGFloat btnW = self.size.width / 5;
CGFloat btnH = self.size.height;
for (int i = 0; i< btnCount; i++) {
UIButton *btn = self.subviews[i];
btn.x = i * btnW;
btn.y = 0;
btn.width = btnW;
btn.height = btnH;
}
}
@end
發微博05-封裝工具條和相冊
APP的演示操作:
仔細觀察APP的演示操作,在輸入文字下面添加了相冊,用于顯示發微博的圖片。而工具條上的按鈕也可以響應某些事件。其實現過程相當復雜。
在HMComposeViewController的viewDidLoad方法添加相冊,如下:
其中,setupPhotosView方法如下:
在HMComposePhotosView(繼承自UIView)中,添加圖片到發微博的相冊中,設置圖片的frame。關鍵代碼如下:
其中,要將方法addPhoto提供外界,用于從外界添加圖片。
在HMComposeToolbar類,完善之前的代碼,使得工具條上的按鈕可以響應。不同于之前所用到的通知,這里要通過代理來實現按鈕的點擊事件。
過程:
1.聲明代理協議和代理屬性,具體代碼如下:
2.通知代理對象,具體代碼如下:
說明:由于使用到btn.tag,所以要對之前的代碼進行完善,如下:
在HMComposeViewController中,遵守HMComposeToolbarDeleagate代理協議,實現代理方法,如下:
其中,openCamera和openAlbum方法分別對應工具條上的“拍照”和“相冊”按鈕。具體代碼如下:
openImagePickerController:設置代理,遵守
UINavigationControllerDelegate和UIImagePickerControllerDelegate代理協議,實現代理方法imagePickerController:didFinishPickingMediaWithInfo:方法,如下:
在imagePickerController:didFinishPickingMediaWithInfo:方法中,取出系統相冊里的圖片后,調用HMComposePhotosView類的addPhoto方法,將圖片添加到發微博的相冊photosView中。
發微博06-發送微博
APP的演示操作:
仔細觀察APP的演示操作,此時發微博除了發送文字,還可以發送圖片。截圖如下:
實際上,在前文的send方法中的api接口是沒辦法發送圖片的,需要另外一個接口。這就需要我們考慮兩種情況(有圖片和沒圖片)。
完善send方法,具體代碼如下:
其中,sendWithImage方法如下:
sendWithoutImage方法如下:
說明:
1.發送帶有圖片的微博,需要將圖片上傳到新浪的服務器。
這就涉及HMComposePhotosView類,需要HMComposePhotosView類提供photos屬性給外界用來獲取圖片資源。
由于外界沒必要對圖片資源進行修改,只需要獲取即可。所以對photos屬性進行特殊聲明(readonly)。如下:
并且要完善下addPhoto方法的代碼,如下:
總結:主要掌握好工具條的設置和如何移動,并且進一步加深對readonly屬性的認識。