有三種解決方案:
1.將父標簽更改為UIView。
2.不要設置父標簽的背景色。
3.設置父標簽的文本([super Label settext:@ &;& amp] )
至於這是鈈BUG還是iOS8 bug,現在還不清楚。
請註明:&;
Objc系列翻譯與本文相關的文章(9.5):字符串渲染-博客-伯樂在線
& ampObjc系列翻譯(9.5):字符串渲染
|分類:,
|標簽:,,
在這壹期中,我們討論了許多關於字符串歧義的話題,從編碼到本地化再到語法分析。但是,在多個數字的情況下,字符串最終需要繪制在屏幕上,供用戶查看和交互。本文涵蓋了最基本和最好的練習,以及在用戶界面中呈現字符串時可能遇到的常見陷阱。
如何在屏幕上繪制壹個字符串
為了簡單起見,我們先來看看UIKit在字符串渲染中為我們提供了哪些控件。之後,我們將討論iOS和OS X系統在渲染字符串方面的異同。
UIKit提供了許多可以在屏幕上顯示和編輯文本的類。每個類都有特定的用途,因此為您的任務選擇正確的工具以避免不必要的問題是非常重要的。
UILabel是在屏幕上繪制文本的最簡單的方法。它是UIView的子類,用於顯示少量只讀文本。文本可以在壹行或多行上展開,如果文本無法放入指定的空間,我們可以用不同的方式剪切它。雖然標簽的使用很簡單,但是有幾個技巧值得壹提。
默認情況下,“標簽”只顯示壹行,但是可以通過將numberOfLines屬性設置為另壹個值來更改此行為。將其設置為大於1的值,文本的行數將被限制在這個指定的值。如果設置為0,它告訴label無論文本占據多少行都要顯示。
通過設置text屬性,標簽可以顯示簡單的純文本,而設置attributedText屬性可以使標簽顯示格式文本。使用純文本時,可以使用字體、標簽的文本顏色,
TextAlignment、shadowColor和shadowOffset屬性會更改其外觀。如果要改變整個程序中所有標簽的樣式,也可以使用[UILabel appearance]的方法進行全局改變。
屬性化字符串提供了更靈活的樣式可供選擇,字符串的不同部分可以使用不同的樣式。讓我們看看常見布局部分。下面是壹些屬性化字符串的例子。(下壹節“通用布局”給出了壹些關於屬性化字符串的具體例子。)
除了通過上面提到的屬性調整UILabel的顯示樣式,還可以設置UILabel的這三個BOOL值的屬性,即Adjust SFontsizetowidth、MinimumScalefactor、Adjust SletterSpacingtofitWidth,使UILabel根據顯示文本的內容自動調整。如果妳非常在意用戶界面的美觀,那麽妳就不要開啟這些屬性,因為這樣會讓“顏”字的顯示效果不那麽美觀,但是有時候,比如在對App進行不同語言的本地化時,會遇到壹些非常棘手的問題,除了使用這些選項,很難找到其他的解決方案。不信妳可以打開iPhone,在設置裏把系統語言改成德語,然後妳會發現蘋果的官方程序裏全是被壓扁變形的難看文字。這種療法並不完美,但有時非常有用。
如果您使用這些選項讓UIKit壓縮您的文本以適應,如果您希望在壓縮時將文本保持在同壹基線上或者需要將其與左上角對齊,那麽您可以定義baselineAdjustment屬性。但是,此選項適用於單行標簽。
當使用上述方法調整文本大小以適應UILabel時,可以使用baselineAdjustment屬性來調整文本的基線是保持壹致還是與標簽的左上角對齊。註意,該屬性只在單行Lable中有效(即numberOfLines的屬性值為1時)。
UITextField
像標簽壹樣,文本字段可以處理純文本或帶屬性的文本。但是標簽只能顯示文本,文本字段也可以處理用戶輸入。但是,文本字段僅限於單行文本。因此,UITextField是UIControl的壹個子類,它將掛鉤到響應鏈中,並在用戶開始或結束編輯時傳遞這些行為消息。如果妳想要更多的控制,妳可以實現文本域的代理。
文本字段有壹系列選項來控制文本輸入行為。UITextField實現了UITextInputTraits協議,需要妳指定鍵盤外觀和操作的各種細節,比如需要顯示什麽樣的鍵盤,後退按鈕的響應事件是什麽。
當沒有文本輸入時,文本字段還可以在右側顯示壹個占位符和壹個標準的清除按鈕,以控制任何左側或右側的輔助視圖。您還可以為它設置背景圖片,這樣我們就可以用可變大小的圖片自定義文本字段的邊框樣式。
但是每當妳需要輸入多行文本時,妳就需要使用UITextField的老大哥...
UITextView
文本視圖是顯示或編輯大量文本的理想選擇。UITextView是UIScrollView的子類,因此它可以允許用戶來回滾動來處理溢出的文本。像文本字段壹樣,文本視圖也可以處理純文本和帶屬性的文本。文本視圖還實現了UITextInputTraits協議來控制鍵盤的行為和外觀。
但是除了文本視圖處理多行文本的能力之外,它最大的賣點是妳可以使用和定制整個文本工具包堆。您可以自定義布局管理器、文本容器或文本存儲的行為或替換您的自定義子類。在objc.io問題#5中提到過。
遺憾的是,UITextView在iOS7中仍然存在壹些問題。目前還是1.0版本。它是基於OS X文本工具包從頭開始重新實現的。iOS7之前基於Webkit,功能很少。
陸委會是什麽情況?
現在我們已經討論了UIKit中的文本類,讓我們繼續解釋AppKit中這些類的相似性。
首先,AppKit中沒有類似UILabel的控件。最基本的顯式文本類是NSTextField。我們將文本字段設置為不可編輯和鈈可選,這相當於iOS中的UILabel。雖然NSTextField聽起來類似於UITextField,但是NSTextField並不局限於單行文本。
NSTextView,換句話說,相當於UITextView,它也為我們揭示了整個Cocoa文本系統。但是它也包括許多額外的功能。很大的原因是Mac是壹臺帶有指點設備(鼠標)的電腦。最值得註意的是包含設置和編輯選項卡的標尺。
上面討論的所有類最後都使用核心文本來布局和繪制真正的符號。核心文本是壹個非常強大的框架,這超出了本文的範圍。但是如果妳需要以完全定制的方式繪制文本(例如貝塞爾曲線),妳需要詳細了解它。
核心文本為您在任何繪圖中提供了充分的靈活性。但是,核心文本很難操作。嗯,是復雜的核心基礎/C API。核心文本讓妳在排版上有充分的權力。
在表格視圖中顯示動態文本
可能大家都處理過,畫線的方法就是最常見的高度可變的表格視圖單元格。妳可以在社交媒體應用中看到這壹點。表視圖的委托有壹個方法。table view:HeightforRowatindexpath:,用於計算高度。在iOS7之前,很難可靠地使用它。
在我們的示例中,我們將在表格視圖中顯示報價列表:
首先,為了實現30%的定制,我們創建了UITableViewCell的子類。在本課程中,我們需要自己展示自己的標簽:
- (void)布局子視圖
[超級布局子視圖];
self . text label . frame = CGRectInset(self . bounds,MyTableViewCellInset,MyTableViewCellInset);
MyTableViewCellInset被定義為常量,所以我們可以在委托表格視圖的高度計算中使用它。計算高度最簡單最準確的方法是將字符串轉換成帶屬性的字符串,然後用屬性計算字符串的高度。我們使用表格視圖的寬度減去MyTableViewCellInset(前後的空間)的兩倍。為了計算真實高度,我們使用boundingwithsize:options:context:。
第壹個參數是限制文本的大小。我們只需要關心寬度限制,所以我們為高度傳遞壹個大值常量CGFLOAT_MAX。第二個參數非常重要:如果傳遞另壹個值,bounding rect無疑會出錯。如果妳想調整身體縮放和/或跟蹤,妳可以使用第三個參數。最後,壹旦我們得到boundingRect,我們需要再次添加inset:
-(CG float)table view:(UITableView *)table view height for rowatindexpath:(NSIndexPath *)indexPath
CG float label width = self . table view . bounds . size . width-MyTableViewCellInset * 2;
NSAttributedString * text =[self attributedBodyTextAtIndexPath:index path];
NSStringDrawingOptions options = nsstringdrawinguslinefragmentorigin | nsstringdrawingusefontl
CGRect bounding rect = 1;
return(CG float)(ceil(bounding rect . size . height)+MyTableViewCellInset * 2);
關於bounding rect的結果,還有另外兩件敏感的事情,除非閱讀文檔,否則您可能不知道:返回的大小返回壹個小數,讓我們使用ceil對文檔中的結果進行舍入。最後結果可能會比實際大壹點。
請註意,當我們的文本是純文本時,我們創建的方法也將用於table view:cellforrowatdinexpath:。這樣,我們需要確保它們保持同步。
還有,看文檔(下面截圖),可以看到iOS7發布後,很多方法都被拋棄了。如果妳查壹個網頁或者StackOverflow,妳會發現很多答案和替代方法來衡量字符的大小。因為文字系統已經大修過了(在內部實現中,所有東西都是用TextKit而不是WebKit繪制的),所以請使用新的方法。
動態調整表格視圖單元格大小的另壹個選項是使用自動布局,您可以在。然後,您可以使用包含標簽的intrinsicContentSize。但是現在自動排版比手工計算要慢很多。但是對於原型開發來說,這是很美好的:它允許您快速調整約束和移動東西(特別是當單元中有多個元素時)。壹旦您完成了產品的設計叠代,您就可以通過手工布局重寫代碼。
使用文本工具包和非屬性字符串布局
使用Text Kit,您將擁有驚人的靈活性來創建專業級的文本局。伴隨著這些靈活性而來的是如何組合大量的選項來完成復雜的布局。
我們將給出壹些例子,並強調壹些常見的布局問題,同時給出解決方案。
經典文本
首先,我們來看壹些經典文本。我們將使用Jacomomy-Ré gnier的histire des nom bres et de la num ration mécanique,並將其設置為Bodoni體。最終的屏幕截圖效果如下:
這些都是文字工具包完成的。兩段之間的裝飾也是文字,用的是Bodoni擺件字體。
我們使用調整過的文本作為樣式。第壹段從左邊開始,在後面的段落中插入空格。
有不同的風格:文體風格,首行縮進的變化風格,裝飾風格。
讓我們先設置body 1屬性:
CG float const fontSize = 15;
NSMutableDictionary * body 1 stat attributes =[NSMutableDictionary字典];
body 1 stat attributes[NSFontAttributeName]=[ui font font with name:@ & amp;BodoniSvtyTwoITCTT-圖書與雜誌。
size:font size];
NSMutableParagraphStyle * body 1st paragraph =[[NSParagraphStyle defaultParagraphStyle]mutable copy];
body 1st paragraph . alignment = nstextalignment j
body 1st paragraph . minimumlineheight = font size+3;
body 1st paragraph . maximum line height = body 1st paragraph . minimum line h
body 1st paragraph . hyphenation factor = 0.97;
body 1 stat attributes[NSParagraphStyleAttributeName]= body 1 STP
我們將字體設置為BodoniSvtyTwoITCTT。這是字體的PostScript名稱。如果我們想找到字體名稱,我們可以使用+[UIFont familyNames]首先獲得可用字體系列的集合。字體系列是我們熟悉的字體。每種字體類型或字體系列都有壹種或多種字體。為了得到這些字體的名稱,我們可以使用+[ui font font names for family name:]。請註意,當您處理各種字體時,UIFontDescriptor類非常有用,例如,當您想知道給定字體的斜體版本時。
許多設置位於NSParagraphStyle中。讓我們創建壹個默認樣式的可變副本,並做壹些調整。在我們的例子中,我們將把字體大小增加3pt。
然後,我們將創建這些段落的屬性的副本,並修改它們以創建boddyAttributes(註意,我們的段落的屬性與上面的body1stParagraph不同)。
NSMutableDictionary * body attributes =[body 1 stat attributes mutable copy];
NSMutableParagraphStyle * body paragraph =
[body attributes[NSParagraphStyleAttributeName]mutable copy];
body paragraph . first line head indent = font
body attributes[NSParagraphStyleAttributeName]= bodyP
我們簡單地創建了屬性字典的壹個變量副本,為了改變段落樣式,我們還需要創建壹個變量副本。將firstLineHeadIndent設置為與字體相同的大小,我們將獲得所需的空間縮進。
然後,修飾段落樣式:
NSMutableDictionary *裝飾屬性= [NSMutableDictionary字典];
裝飾屬性[nsfont attributename]=[ui font font with name:@ & amp;博多尼裝飾公司。尺寸:36];
NSMutableParagraphStyle * decoration paragraph =[[NSParagraphStyle defaultParagraphStyle]mutable copy];
裝飾段落
裝飾段落.段落段落之前=字體
裝飾段落.段落間距=字體
裝飾屬性[NSParagraphStyleAttributeName]=裝飾
這個很好理解。我們使用裝飾性字體,將文本居中。此外,我們在裝飾字符的前後添加空白段落。
接下來是顯示數字的表格。我們希望在對齊中顯示分數的小數點,即“.”即英語;
為了實現這個目標,我們需要指定表格停止在分隔線的中心。
對於上述示例,我們只需執行以下操作:
NSCharacterSet * decimalTerminator =[NSCharacterSet
characterSetWithCharactersInString:decimal formatter . decimal separator];
NSTextTab * decimal tab =[[NSTextTab alloc]
initWithTextAlignment:NSTextAlignmentCenter
位置:100選項:@ { nstabcolumnterminatorattributename:decimalTerminator }];
NSTextTab * percent tab =[[NSTextTab alloc]initWithTextAlignment:nstextalignment right location:200 options:nil];
NSMutableParagraphStyle * tableParagraphStyle =[[NSParagraphStyle defaultParagraphStyle]mutable copy];
table paragraphstyle . tabstops = @[decimal tab,percent tab];
另壹個常見的用例是like list:
縮進很容易設置。我們需要確保在序列號(1)和文本之間或者在數字和文本之間有壹個制表符。然後我們像這樣調整段落的樣式:
NSMutableDictionary * list attributes =[body attributes mutable copy];
NSMutableParagraphStyle * list paragraph =
[list attributes[NSParagraphStyleAttributeName]mutable copy];
list paragraph . head indent = font size * 3;
list paragraph . first line head indent = fontS
NSTextTab * list tab =[[NSTextTab alloc]initWithTextAlignment:nstextalignment natural location:font size * 3
選項:無];
list paragraph . tabstops = @[list tab];
list attributes[NSParagraphStyleAttributeName]= listP
我們將headIndent設置為真實文本的縮進量,將firstLineHeadIndent設置為項目符號的縮進量。最後,像headIndent壹樣,我們需要在相同的位置添加壹個制表符。項目符號後的制表符將確保這壹行文本從正確的位置繪制。