在筆者的上篇文章《自己動(dòng)手寫iPhone wap瀏覽器之BSD Socket引擎篇》中已經(jīng)成功解析出來了wml頁面中的tag,如果讀者仔細(xì)的話可能會(huì)看到里面中文的tag顯示為亂碼,這是因?yàn)樵趇Phone上默認(rèn)的中文編碼格式是UTF-8,而通過BSD Socket請(qǐng)求過來的是ASCII碼,所以需要通過轉(zhuǎn)換為UTF-8格式,如下:
?。郏跱SString alloc] initWithBytes:aChild-》Value() length:strlen(aChild-》Value()) encoding:NSUTF8StringEncoding]
經(jīng)過轉(zhuǎn)換編碼之后,在屏幕上顯示的打印內(nèi)容如下:
parse xml succeed
aChild value = STATUS OK
aChild value = card
TiXmlNode::ELEMENT name = title, attr value = 百度一下,你就知道
aChild value = p
aChild value = img
TiXmlNode::ELEMENT name = src, attr value = /r/wise/wapsearchindex/logoindexsmall.gif
TiXmlNode::ELEMENT name = alt, attr value = 百度首頁
aChild value = br
aChild value = input
TiXmlNode::ELEMENT name = name, attr value = word
TiXmlNode::ELEMENT name = emptyok, attr value = true
aChild value = br
aChild value = anchor
aChild value = 搜網(wǎng)頁
TiXmlNode::TEXT Value = 搜網(wǎng)頁
接下來的任務(wù)就是渲染這些解析出來的tag并顯示在界面上了,本篇里筆者重點(diǎn)講述如果搭建一個(gè)可擴(kuò)展的、健壯的界面架構(gòu)。
在所有平臺(tái)的界面架構(gòu)中,筆者一直推崇MVC,MVC的著重點(diǎn)在于把界面顯示和數(shù)據(jù)處理分離開來以提供可擴(kuò)展的界面架構(gòu)平臺(tái)?;谶@個(gè)思想,筆者建立了如下的架構(gòu)圖:
圖1.Tag界面架構(gòu)圖
在筆者的上篇文章《自己動(dòng)手寫iPhone wap瀏覽器之BSD Socket引擎篇》中已經(jīng)成功解析出來了wml頁面中的tag,如果讀者仔細(xì)的話可能會(huì)看到里面中文的tag顯示為亂碼,這是因?yàn)樵趇Phone上默認(rèn)的中文編碼格式是UTF-8,而通過BSD Socket請(qǐng)求過來的是ASCII碼,所以需要通過轉(zhuǎn)換為UTF-8格式,如下:
?。郏跱SString alloc] initWithBytes:aChild-》Value() length:strlen(aChild-》Value()) encoding:NSUTF8StringEncoding]
經(jīng)過轉(zhuǎn)換編碼之后,在屏幕上顯示的打印內(nèi)容如下:
parse xml succeed
aChild value = STATUS OK
aChild value = card
TiXmlNode::ELEMENT name = title, attr value = 百度一下,你就知道
aChild value = p
aChild value = img
TiXmlNode::ELEMENT name = src, attr value = /r/wise/wapsearchindex/logoindexsmall.gif
TiXmlNode::ELEMENT name = alt, attr value = 百度首頁
aChild value = br
aChild value = input
TiXmlNode::ELEMENT name = name, attr value = word
TiXmlNode::ELEMENT name = emptyok, attr value = true
aChild value = br
aChild value = anchor
aChild value = 搜網(wǎng)頁
TiXmlNode::TEXT Value = 搜網(wǎng)頁
接下來的任務(wù)就是渲染這些解析出來的tag并顯示在界面上了,本篇里筆者重點(diǎn)講述如果搭建一個(gè)可擴(kuò)展的、健壯的界面架構(gòu)。
在所有平臺(tái)的界面架構(gòu)中,筆者一直推崇MVC,MVC的著重點(diǎn)在于把界面顯示和數(shù)據(jù)處理分離開來以提供可擴(kuò)展的界面架構(gòu)平臺(tái)?;谶@個(gè)思想,筆者建立了如下的架構(gòu)圖:
圖1.Tag界面架構(gòu)圖
在Xml模塊處理完xml數(shù)據(jù)并提取出tag后,交給CXmlControl進(jìn)行處理,CXmlControl在這里充當(dāng)Control的角色,它負(fù)責(zé)在處理完tag(標(biāo)簽)后生成相應(yīng)的消息以顯示在界面上。
其中CXmlControl繼承自UIView類,它負(fù)責(zé)顯示界面并響應(yīng)用戶的按鍵消息,而具體的邏輯處理則是在CXmlControlImpl類中進(jìn)行的,CXmlControlImpl這個(gè)類負(fù)責(zé)管理生成的tag(標(biāo)簽)以及tag(標(biāo)簽)的界面Layout(布局),如下:
@class CXmlControlImpl;
@interface CXmlControl : UIView {
@public
CXmlControlImpl* iImpl;
}
-(void) addElements:(CXmlElementImpl*)iElemntAdded;
-(CXmlElement*) InsertContent:(CXmlElement*)aTarget aPosition:(NSInteger)aPosition aSource:(const NSString*)aSource aFlags:(NSInteger)aFlags;
-(CXmlElement*) AppendContent:(const NSString*)aSource aFlags:(NSInteger)aFlags;
-(void) Refresh;
-(void) RefreshAndDraw;
-(void) ClearContent;
-(void) RemoveElement:(CXmlElement*)aElement;
-(CXmlElement*) Element:(const NSString*)aId aIndex:(NSInteger)aIndex;
-(CXmlElement*) ElementByTag:(const NSString*)aTagName aIndex:(NSInteger)aIndex;
-(CXmlElement*) FocusedElement;
-(void) SetFocusTo:(CXmlElement*)aElement;
-(void) ScrollToView:(CXmlElement*)aElement;
-(CXmlElement*) Body;
-(void) SetEventObserver:(id《MXmlCtlEventObserver》)aObserver;
-(CXmlElementImpl*) Impl;
-(CGContextRef) SystemGc;
-(void) Draw:(const CGRect)aRect;
-(CWritableBitmap*) OffScreenBitmap;
-(void) SetOffScreenBitmap:(CWritableBitmap*)aBitmap;
-(void) DrawOffscreen;
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
@end
Tag(標(biāo)簽)類的基類為CXmlElement,它抽象了標(biāo)簽的基本屬性和操作,在每一個(gè)派生自此基類的tag(標(biāo)簽)類如CXmlTextElement、CXmlImgElement中都維護(hù)一個(gè)全局的布局類CHcMeasureStatus,每一個(gè)tag(標(biāo)簽)類都負(fù)責(zé)自己的布局和自己的繪制操作,完成布局操作和繪制操作后為改變CHcMearuseStatus的狀態(tài)和屬性并傳遞給CXmlControl類。