中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

如何為你的UIView添加邊緣分割線

2018-07-20    來源:編程學(xué)習(xí)網(wǎng)

容器云強勢上線!快速搭建集群,上萬Linux鏡像隨意使用

在移動端產(chǎn)品的開發(fā)過程中,很多時候我們需要在某個View的top或者bottom的位置添加一條分割線。遇到這樣的需求你是怎么解決的呢?歡迎各位簡友們分享自己的做法。

我們通常的解決方式,就是添加一個subview,到相應(yīng)的位置;然后把該subview.backgroundColor設(shè)置成我們想要的顏色。這樣確實解決了,視覺效果上的問題。但是長期下來,我個人還是覺得有點低效...

今天分享的就是我目前所使用的為view添加分割線的方法。總體思路這樣的:

(1).首先創(chuàng)建一個繼承自UIView類的WHView類(該類名你可以自己指定),添加屬性:

@property (nonatomic, retain) UIColor *separatorColor;

(2).接著我們創(chuàng)建一個枚舉類型(標(biāo)識View的哪些位置需要繪制分割線),并為WHView添加屬性:

typedef NS_OPTIONS(NSUInteger, WHViewSeparatorMode){
    KWHViewSeparatorModeNone = 1 << 0,
    KWHViewSeparatorModeTop = 1 << 1,
    KWHViewSeparatorModeBottom = 1 << 2,
    KWHViewSeparatorModeLeft = 1 << 3,
    KWHViewSeparatorModeRight = 1 << 4,
    KWHViewSeparatorModeAll = KWHViewSeparatorModeTop |KWHViewSeparatorModeBottom |KWHViewSeparatorModeLeft |KWHViewSeparatorModeRight
};
@property (nonatomic, assign) WHViewSeparatorMode separatorMode;

(3).創(chuàng)建一個WHView的分類WHView (WHViewSeparator),利用runtime機制,替換drawRect:方法。在替換的方法中,繪制邊緣線。

完整的代碼如下:
WHView.h中代碼如下:

#import <UIKit/UIKit.h> typedef NS_OPTIONS(NSUInteger, WHViewSeparatorMode){
    KWHViewSeparatorModeNone = 1 << 0,
    KWHViewSeparatorModeTop = 1 << 1,
    KWHViewSeparatorModeBottom = 1 << 2,
    KWHViewSeparatorModeLeft = 1 << 3,
    KWHViewSeparatorModeRight = 1 << 4,
    KWHViewSeparatorModeAll = KWHViewSeparatorModeTop|KWHViewSeparatorModeBottom|KWHViewSeparatorModeLeft|KWHViewSeparatorModeRight
}; @interface WHView : UIView @property (nonatomic, retain) UIColor *separatorColor; @property (nonatomic, assign) WHViewSeparatorMode separatorMode; @end @interface WHView(WHViewSeparator) @end

WHView.m中代碼如下:

#import "WHView.h" #import <objc/runtime.h> @implementation WHView - (instancetype)initWithFrame:(CGRect)frame{ if(self = [super initWithFrame:frame]){ self.backgroundColor = [UIColor whiteColor]; self.separatorMode = KWHViewSeparatorModeNone;
    } return self;
}

- (UIColor *)separatorColor{ if(_separatorColor != nil){ return _separatorColor;
    } return [UIColor lightGrayColor];
}

- (void)setSeparatorMode:(WHViewSeparatorMode)separatorMode{
    _separatorMode = separatorMode;
    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect{ NSLog(@"______1:drawRect%@", self.class);
} @end #define KWHSeparatorWidth (1.0/[[UIScreen mainScreen] scale]) @implementation WHView(WHViewSeparator) + (void)load{
    [super load]; //在這里替換view的drawRect方法 //替換的目的在于,我們需要在替換過的__drawRect:方法中繪制分割線,繪制完畢再調(diào)回原來的drawRect:方法。 static dispatch_once_t predicate; dispatch_once(&predicate, ^{
        Method drawRect = class_getInstanceMethod(self, @selector(drawRect:));
        Method __drawRect = class_getInstanceMethod(self, @selector(__drawRect:));
        method_exchangeImplementations(drawRect, __drawRect);
    });
}

- (void)__drawRect:(CGRect)rect{ NSLog(@"______0:drawRect%@", self.class); CGContextRef contextRef = UIGraphicsGetCurrentContext(); CGContextSetLineWidth(contextRef, KWHSeparatorWidth); CGContextSetStrokeColorWithColor(contextRef, [self.separatorColor CGColor]); CGRect rc = self.frame; //根據(jù)NS_OPTIONS枚舉類型的特性,為外部設(shè)置的_separatorMode,分別繪制。 if(self.separatorMode & KWHViewSeparatorModeTop){ CGContextMoveToPoint(contextRef, 0, 0+KWHSeparatorWidth/2); CGContextAddLineToPoint(contextRef, rc.size.width, 0+KWHSeparatorWidth/2); CGContextDrawPath(contextRef, kCGPathStroke);
    } if(self.separatorMode & KWHViewSeparatorModeBottom){ CGContextMoveToPoint(contextRef, 0, rc.size.height-KWHSeparatorWidth/2); CGContextAddLineToPoint(contextRef, rc.size.width, rc.size.height-KWHSeparatorWidth/2); CGContextDrawPath(contextRef, kCGPathStroke);
    } if(self.separatorMode & KWHViewSeparatorModeLeft){ CGContextMoveToPoint(contextRef, 0+KWHSeparatorWidth/2, 0); CGContextAddLineToPoint(contextRef, 0+KWHSeparatorWidth/2, rc.size.height); CGContextDrawPath(contextRef, kCGPathStroke);
    } if(self.separatorMode & KWHViewSeparatorModeRight){ CGContextMoveToPoint(contextRef, rc.size.width-KWHSeparatorWidth/2, 0); CGContextAddLineToPoint(contextRef, rc.size.width-KWHSeparatorWidth/2, rc.size.height); CGContextDrawPath(contextRef, kCGPathStroke);
    }

    [self __drawRect:rect];
} @end

核心代碼截屏如下:


WHViewSeparator.png

至此,我們完成了WHView類的封裝。我們設(shè)置的默認(rèn)的分割線的額顏色為[UIColor lightGrayColor];寬度為一個像素,默認(rèn)類型為無分割線。在實際運用中,我們直接用WHView去初始化我們想要的view,然后設(shè)置separatorMode即可。

另外,學(xué)習(xí)了上邊的方法后,我們最好能明白以下幾個問題:
(1).為什么要用分類來實現(xiàn)繪制的機制?
(2).runtime是否是真的懂?
(3).在drawRect:方法的末尾為什么仍然調(diào)用drawRect:?(會不會循環(huán)調(diào)用?為啥不是直接調(diào)用drawRect:)


文/iOSWH__(簡書作者)

標(biāo)簽: isp 代碼

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:前后端分離了,然后呢?

下一篇:幾種開源工作流引擎的簡單比較