實現(xiàn)這個我真的花了很長的時間憋肖,效果和簡書的代碼框差不多寿酌,因為簡書也是采用了 Markdown 的代碼框胰苏,就像下面這樣。
特別喜歡孫燕姿的這張專輯醇疼。
克卜勒是以天文學家Johannes Kepler命名的一顆超新星。
是四百年來第一次在白天可以用肉眼看到的星星秧荆。
我不太懂那些宇宙的事埃仪,因為自己的不夠聰明卵蛉,反而對這個世界格外放心傻丝。
太陽每天都會升起來葡缰,潮水每天都會退去,“藏在眾多孤星之中滤愕,還是找得到你”间影。
—— [來自網(wǎng)易云評論] (http://music.163.com/#/song?id=28196001)
要實現(xiàn)這個效果魂贬,相當于要解決下面這幾個問題随橘。
一、UILabel 添加邊框和背景色
這個是最簡單的蒲祈,沒什么好說萝嘁,直接貼代碼,顏色都幫你取好了酸钦。
UILabel *label = [[UILabel alloc] init];
label.layer.borderWidth= 1.0f;
label.layer.cornerRadius=5.0f;
label.layer.borderColor = [[UIColor colorWithRed:204/255.0 green:204/255.0 blue:204/255.0 alpha:1] CGColor];
二咱枉、UILabel 設置文本的行高
NSString *text = @"藏在眾多孤星之中\(zhòng)n還是找得到你";
NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithString:text];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:lineSpacing];
[attrString addAttribute:NSParagraphStyleAttributeName
value:style
range:NSMakeRange(0, text.length)];
label.attributedText = attrString;
三蚕断、UILabel 支持多行文本和動態(tài)高度
這里需要設置 label 的相關屬性和加上自動布局的水平限制亿乳。
[self.view addSubview:label];
label.numberOfLines = 0;
label.translatesAutoresizingMaskIntoConstraints = NO;
NSArray *labelConstraints = nil;
NSDictionary *views = @{
@"label": label,
};
labelConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[label]-10-|" options:0 metrics:nil views:views];
[self.view addConstraints:labelConstraints];
注:上面都是偽代碼葛假,只提供一個大概思路聊训。
四魔眨、UILabel 設置 Padding
這個是最難的地方遏暴,我在 Stackoverflow 找到下面兩個解決方案朋凉。
- subclass UILabel 并重寫 drawTextInRect 和 intrinsicContentSize 方法
- 如果只是添加左右 Padding,可以使用 NSAttributedString
很顯然我們是需要添加4個方向的 Padding墓毒,但當我采用第一種方法時吓揪,發(fā)現(xiàn)如果文本太長所计,出現(xiàn)換行的情況下柠辞,高度的計算會有問題主胧,部分文本顯示不出來叭首。第一種方法只適用于添加上下兩個方向的 Padding踪栋,不能用于添加左右方向的 Padding焙格。
所以這里必須結(jié)合兩種方案,才能順利實現(xiàn)4個方向的 Padding 添加夷都。最后我就直接貼實現(xiàn)的代碼好了。
// CodeBlockLabel.h
#import <UIKit/UIKit.h>
@interface CodeBlockLabel : UILabel
- (void)setBlockText:(NSString*)text;
- (void)setBlockText:(NSString*)text fontSize:(NSInteger)fontSize lineSpacing:(NSInteger)lineSpacing;
@end
// CodeBlockLabel.m
#import "CodeBlockLabel.h"
@implementation CodeBlockLabel
float topInset, leftInset, bottomInset, rightInset;
- (instancetype)init {
if (self = [super init]) {
[self setContentEdgeInsets:UIEdgeInsetsMake(20, 0, 20, 0)];
self.numberOfLines = 0;
self.backgroundColor = [UIColor colorWithRed:247/255.0 green:247/255.0 blue:247/255.0 alpha:1];
self.translatesAutoresizingMaskIntoConstraints = NO;
self.layer.cornerRadius=5.0f;
self.layer.borderColor = [[UIColor colorWithRed:204/255.0 green:204/255.0 blue:204/255.0 alpha:1] CGColor];
self.layer.borderWidth= 1.0f;
}
return self;
}
- (void)drawTextInRect:(CGRect)uiLabelRect {
[super drawTextInRect:UIEdgeInsetsInsetRect(uiLabelRect, UIEdgeInsetsMake(topInset,leftInset,bottomInset,rightInset))];
}
- (CGSize)intrinsicContentSize {
CGSize intrinsicSuperViewContentSize = [super intrinsicContentSize] ;
intrinsicSuperViewContentSize.height += topInset + bottomInset;
intrinsicSuperViewContentSize.width += leftInset + rightInset;
return intrinsicSuperViewContentSize;
}
- (void)setContentEdgeInsets:(UIEdgeInsets)edgeInsets {
topInset = edgeInsets.top;
leftInset = edgeInsets.left;
rightInset = edgeInsets.right;
bottomInset = edgeInsets.bottom;
[self invalidateIntrinsicContentSize] ;
}
- (void)setBlockText:(NSString*)text {
NSInteger lineSpacing;
NSString *trimmedString = [text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// 處理一行的情況
if ([trimmedString rangeOfString:@"\n"].location == NSNotFound) {
lineSpacing = 0;
} else {
lineSpacing = 7;
}
[self setBlockText:trimmedString fontSize:15 lineSpacing:lineSpacing];
}
- (void)setBlockText:(NSString*)text fontSize:(NSInteger)fontSize lineSpacing:(NSInteger)lineSpacing {
[self setFont:[UIFont systemFontOfSize:fontSize]];
NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithString:text];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:lineSpacing];
// 是的寫死了,不要在意哈哈哈
style.firstLineHeadIndent = 20.0;
style.headIndent = 20.0;
style.tailIndent = -20.0;
[attrString addAttribute:NSParagraphStyleAttributeName
value:style
range:NSMakeRange(0, text.length)];
self.attributedText = attrString;
}
@end
// ViewController.m
#import "ViewController.h"
#import "CodeBlockLabel.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 添加 UIScrollView
UIScrollView *scrollView = [[UIScrollView alloc] init];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:scrollView];
// 這里添加更多的文本,就能看到滾動條了
NSString *text = @"藏在眾多孤星之中\(zhòng)n還是找得到你";
CodeBlockLabel *codeBlock = [[CodeBlockLabel alloc] init];
[codeBlock setBlockText:text];
// 這個 spongeBob 去掉會有 bug
UILabel *spongeBob = [[UILabel alloc] init];
spongeBob.numberOfLines = 0;
spongeBob.translatesAutoresizingMaskIntoConstraints = NO;
[scrollView addSubview:spongeBob];
[scrollView addSubview:codeBlock];
NSDictionary *views = @{
@"scrollView": scrollView,
@"codeBlock": codeBlock,
@"spongeBob": spongeBob,
};
// 添加約束
NSArray *constraints = nil;
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[codeBlock]-10-|" options:0 metrics:nil views:views];
[scrollView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[spongeBob(scrollView)]|" options:0 metrics:nil views:views];
[scrollView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-15-[codeBlock]-15-[spongeBob]-5-|" options:0 metrics:nil views:views];
[scrollView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics:nil views:views];
[self.view addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-30-[scrollView]-44-|" options:0 metrics:nil views:views];
[self.view addConstraints:constraints];
}
@end
這就是全部了嚷掠,上面還添加了一個 UIScrollView贯城,這樣就算文本太長,你也能滑到下面去看了霹娄,你的更好的辦法嗎能犯?有的話一定要告訴我!