前言
好久沒有在簡書上面發表文章了,至今文集中都還有好幾個未完成的文章,今天決定先發表一篇簡單好寫的文章,也許我這看似簡單的文章就能省去你幾個小時的時間,來寫更多的代碼。哈哈,我相信基本上有需要這方面的功能,但是在網上搜索來實現的時候肯定遇到過坑,所以這篇文章你不會白看的。
靜態的textView行間距
當我們不需要在textView中輸入,直接顯示文字時,設置textView的行間距非常簡單,網上也有現成的代碼,非常簡單也不會有什么bug。
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(20, 100, 100, 200)];
textView.delegate = self;
textView.text = @"哈哈哈哈哈哈大家好大家好大家好大家好";
[self.view addSubview:textView];
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.lineSpacing = 20;// 字體的行間距
NSDictionary *attributes = @{
NSFontAttributeName:[UIFont systemFontOfSize:17],
NSParagraphStyleAttributeName:paragraphStyle
};
textView.attributedText = [[NSAttributedString alloc] initWithString:textView.text attributes:attributes];
用到NSMutableParagraphStyle這個類,這是設置段落風格的類,有很多屬性,請自行查看API
動態設置textView行間距
大多數情況下,我們的textView是需要輸入的,我們想要在輸入的時候改變行間距,上面的方法就行不通了。我們一貫的解決方法就是去網上查代碼,基本上解決方案都是一樣的,動態實現的話需要在textView的代理方法中實現。貼上bug代碼。
- (void)textViewDidChange:(UITextView *)textView {
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 20;// 字體的行間距
NSDictionary *attributes = @{
NSFontAttributeName:[UIFont systemFontOfSize:15],
NSParagraphStyleAttributeName:paragraphStyle
};
textView.attributedText = [[NSAttributedString alloc] initWithString:textView.text attributes:attributes];
}
這樣,輸入的時候間距出來了,但是內容就不準確了,輸入的字符會直接顯示到textView上,再次輸入時前一次輸入的還會顯示上去,輸入一個漢字會帶上很多字符。如果是用模擬器運行就不會有這種bug。關于attributedText的具體實現沒有深入去研究,如果我們換成另外一個屬性就會顯示正常了。
最終的方案
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(20, 100, 100, 200)];
textView.delegate = self;
[self.view addSubview:textView];
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.lineSpacing = 20;// 字體的行間距
NSDictionary *attributes = @{
NSFontAttributeName:[UIFont systemFontOfSize:17],
NSParagraphStyleAttributeName:paragraphStyle
};
textView.typingAttributes = attributes;
主要的一個屬性 typingAttributes,官方文檔中介紹是,該字典中包含屬性鍵去應用于新輸入的文本,當選擇變化時字典的內容被自動清除,如果文本框不是在編輯模式中,這個屬性為nil。同時你也不能賦值這個屬性,除非文本字段目前處于編輯模式。所以這個屬性不會出現使用attributedText的問題。
后續遇到的問題
以上的方案能夠動態的改變UITextView的行間距,但是后來發現一個問題,當UITextView的行間距改變之后,光標的高度也跟著變化了,這樣的用戶體驗不好。
后來查閱UITextView的API,沒有發現相關的屬性來設置光標的顯示, 使用系統的UITextView暫時解決不了上述問題(如果有使用UITextView的解決方案,還請告知,謝謝!)。
但是,UITextView遵循了UITextInput協議,其中有返回光標frame的方法 *- (CGRect)caretRectForPosition:(UITextPosition )position,所以我們可以使用自定義的TextView,重寫返回光標frame的方法來解決這個問題。
- (CGRect)caretRectForPosition:(UITextPosition *)position {
CGRect originalRect = [super caretRectForPosition:position];
originalRect.size.height = self.font.lineHeight + 2;
originalRect.size.width = 3;
return originalRect;
}
END
希望我這篇文章能幫助到閱讀的你!