前言
好久沒有在簡書上面發(fā)表文章了,至今文集中都還有好幾個未完成的文章,今天決定先發(fā)表一篇簡單好寫的文章,也許我這看似簡單的文章就能省去你幾個小時的時間,來寫更多的代碼。哈哈,我相信基本上有需要這方面的功能,但是在網(wǎng)上搜索來實現(xiàn)的時候肯定遇到過坑,所以這篇文章你不會白看的。
靜態(tài)的textView行間距
當(dāng)我們不需要在textView中輸入,直接顯示文字時,設(shè)置textView的行間距非常簡單,網(wǎng)上也有現(xiàn)成的代碼,非常簡單也不會有什么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這個類,這是設(shè)置段落風(fēng)格的類,有很多屬性,請自行查看API
動態(tài)設(shè)置textView行間距
大多數(shù)情況下,我們的textView是需要輸入的,我們想要在輸入的時候改變行間距,上面的方法就行不通了。我們一貫的解決方法就是去網(wǎng)上查代碼,基本上解決方案都是一樣的,動態(tài)實現(xiàn)的話需要在textView的代理方法中實現(xiàn)。貼上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];
}
這樣,輸入的時候間距出來了,但是內(nèi)容就不準(zhǔn)確了,輸入的字符會直接顯示到textView上,再次輸入時前一次輸入的還會顯示上去,輸入一個漢字會帶上很多字符。如果是用模擬器運行就不會有這種bug。關(guān)于attributedText的具體實現(xiàn)沒有深入去研究,如果我們換成另外一個屬性就會顯示正常了。
最終的方案
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,官方文檔中介紹是,該字典中包含屬性鍵去應(yīng)用于新輸入的文本,當(dāng)選擇變化時字典的內(nèi)容被自動清除,如果文本框不是在編輯模式中,這個屬性為nil。同時你也不能賦值這個屬性,除非文本字段目前處于編輯模式。所以這個屬性不會出現(xiàn)使用attributedText的問題。
后續(xù)遇到的問題
以上的方案能夠動態(tài)的改變UITextView的行間距,但是后來發(fā)現(xiàn)一個問題,當(dāng)UITextView的行間距改變之后,光標(biāo)的高度也跟著變化了,這樣的用戶體驗不好。

后來查閱UITextView的API,沒有發(fā)現(xiàn)相關(guān)的屬性來設(shè)置光標(biāo)的顯示, 使用系統(tǒng)的UITextView暫時解決不了上述問題(如果有使用UITextView的解決方案,還請告知,謝謝!)。
但是,UITextView遵循了UITextInput協(xié)議,其中有返回光標(biāo)frame的方法 *- (CGRect)caretRectForPosition:(UITextPosition )position,所以我們可以使用自定義的TextView,重寫返回光標(biāo)frame的方法來解決這個問題。
- (CGRect)caretRectForPosition:(UITextPosition *)position {
CGRect originalRect = [super caretRectForPosition:position];
originalRect.size.height = self.font.lineHeight + 2;
originalRect.size.width = 3;
return originalRect;
}
END
希望我這篇文章能幫助到閱讀的你!