前言
過年了,老家卻沒有網(wǎng)鳄哭,用的朋友家的wifi要糊,信號很不穩(wěn)定,相當(dāng)不爽妆丘。正好最近也有點郁悶锄俄,作為一個搬磚的人,倒是可以靜下來寫點兒東西解解乏飘痛。如果不了解UIBezierPath看本文前可以先看看片尾的參考文章珊膜。
需求
像這樣的圖形可以用圖片作backgroundView,但是理智告訴你肯定是不能那么干的是不能這么偷懶的宣脉。雖然也很容易適配车柠,但是你得盡最大的努力縮小app的size。(注:上下左右都是π/2弧度1px的圓凰懿)
我的紅包_MarkMan.png
實現(xiàn)思路
- 將每一條直線和一個圓弧當(dāng)做一個步驟竹祷,一共分為六部分。
- 要非常小心的注意圓弧的位置和弧度方向羊苟,一般而言原點是在左下方而ios是左上方塑陵,所以ios的弧度方向是順時針逐漸增大。(但是addArcWithCenter方法里的clockwise可以設(shè)置弧度方向)
- 虛線其實就是由實線構(gòu)成蜡励,每畫一條移動畫筆就是令花。
外圈實現(xiàn)
- (void)drawRect:(CGRect)rect {
// Drawing code
//set line color
[[ATAppTheme colorLightGray] set];
CGFloat padding = 0.3;
CGFloat totalHeight = [ATAppTheme paddingWithSize:236] - padding * 2;
CGFloat totalWidth = kScreenWidth - [ATAppTheme paddingWithSize:28] * 2 - padding * 2;
CGFloat radius = [ATAppTheme paddingWithSize:12];
CGFloat upHeight = [ATAppTheme paddingWithSize:162] - padding;
CGFloat smallRadius = [ATAppTheme paddingWithSize:4];
UIBezierPath* aPath = [UIBezierPath bezierPath];
aPath.lineWidth = 0.5;
aPath.lineCapStyle = kCGLineCapRound;
aPath.lineJoinStyle = kCGLineCapRound;
[aPath moveToPoint:CGPointMake(padding, smallRadius + padding)];
[aPath addLineToPoint:CGPointMake(padding, upHeight - radius)];
//1
[aPath addArcWithCenter:CGPointMake(padding, upHeight)
radius:radius
startAngle:transformRadian(-90.0)
endAngle:(transformRadian(90.0))
clockwise:YES];
[aPath addLineToPoint:CGPointMake(padding, totalHeight - smallRadius + padding)];
//2
[aPath addArcWithCenter:CGPointMake(smallRadius + padding, totalHeight - smallRadius + padding)
radius:smallRadius startAngle:transformRadian(180)
endAngle:transformRadian(90)
clockwise:NO];
[aPath addLineToPoint:CGPointMake(totalWidth - smallRadius + padding, totalHeight + padding)];
//3
[aPath addArcWithCenter:CGPointMake(totalWidth - smallRadius + padding, totalHeight - smallRadius + padding)
radius:smallRadius startAngle:transformRadian(90)
endAngle:transformRadian(0)
clockwise:NO];
[aPath addLineToPoint:CGPointMake(totalWidth + padding, upHeight + radius)];
// 4
[aPath addArcWithCenter:CGPointMake(totalWidth + padding, upHeight)
radius:radius
startAngle:(transformRadian(90))
endAngle:transformRadian(-90)
clockwise:YES];
[aPath addLineToPoint:CGPointMake(totalWidth + padding, smallRadius + padding)];
// 5
[aPath addArcWithCenter:CGPointMake(totalWidth - smallRadius + padding, smallRadius + padding)
radius:smallRadius startAngle:transformRadian(0)
endAngle:transformRadian(-90)
clockwise:NO];
[aPath addLineToPoint:CGPointMake(smallRadius + padding, padding)];
// 6
[aPath addArcWithCenter:CGPointMake(smallRadius + padding, smallRadius + padding)
radius:smallRadius startAngle:transformRadian(-90)
endAngle:transformRadian(-180)
clockwise:NO];
[aPath moveToPoint:CGPointMake([ATAppTheme paddingWithSize:36] + padding, upHeight)];
[self addDottedLineToPoint:CGPointMake(totalWidth + padding - [ATAppTheme paddingWithSize:36], upHeight) withPath:aPath scaleOfDottedLineToLine:2];
[aPath closePath];
// set background color
[[UIColor whiteColor] setFill];
[aPath fill];
UIBezierPath* bPath = [UIBezierPath bezierPath];
[[ATAppTheme colorLightGray] set];
bPath.lineWidth = 0.5f;
[bPath moveToPoint:CGPointMake([ATAppTheme paddingWithSize:36] + padding, upHeight)];
[self addDottedLineToPoint:CGPointMake(totalWidth + padding - [ATAppTheme paddingWithSize:36], upHeight) withPath:bPath scaleOfDottedLineToLine:2];
[aPath appendPath:bPath];
[aPath stroke];
}
虛線實現(xiàn)
這是一個水平的虛線所以幾乎不用考慮取整的問題,但是最后一根線確實有可能和其他的有丁點兒的差別凉倚。UIBezierPath其實是做了一層封裝的兼都,應(yīng)該是有直接畫虛線的方法,今天網(wǎng)不好就沒查稽寒,下次待更新扮碧。不過我自己在話斜虛線做了一點兒處理,請看官們指點一下杏糙。
- (void)addDottedLineToPoint:(CGPoint)point withPath:(UIBezierPath*)path scaleOfDottedLineToLine:(CGFloat)scale{
path.lineWidth = 0.25;
CGPoint currentPoint = path.currentPoint;
CGFloat width = [self lineOfPointToPoint:currentPoint endPoint:point];
CGFloat dattedWidth = 2;
CGFloat lineWidth = dattedWidth * scale;
NSInteger number = floorf((width - lineWidth) / (dattedWidth + lineWidth));
for (NSInteger i = 0; i <= number ; i++) {
[path addLineToPoint:CGPointMake(currentPoint.x + lineWidth, currentPoint.y)];
[path moveToPoint:CGPointMake(currentPoint.x + lineWidth + dattedWidth, currentPoint.y)];
currentPoint = path.currentPoint;
[path stroke];
}
}
- (CGFloat)lineOfPointToPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint {
return sqrt((pow(endPoint.x - startPoint.x, 2) + pow(endPoint.y - startPoint.y, 2)));
}
小彩蛋
重寫drawRect方法是在7plus ios10.2的版本上View視圖最上面會出現(xiàn)莫名其妙的黑線慎王,在其他的ios10.2的模擬器上倒是沒有出現(xiàn)這個問題,個人懷疑是apple官方的問題宏侍,不知道ios10.2.1修復(fù)了沒有赖淤,只有待下次檢查了。若是我的問題谅河,懇請大神指正咱旱。在photoshop里放大到單個像素級別的就能發(fā)現(xiàn)一個像素的區(qū)別嗜愈,雖說只有一個像素的區(qū)別,而且在真機(jī)上肉眼很難發(fā)現(xiàn)區(qū)別莽龟,但是一個優(yōu)秀的app在這方面還是得要考慮周全一些。(待更新锨天。毯盈。。)
本文代碼