目的
製作一個帶陰影的Button
替換NSButton
背景色以及繪製圓角和陰影。
設置圖片的話就還要考慮陰影問題,顏色還要考慮是否和圖片的一致,複用性也不高。
起初想使用drawRect:
直接繪製,但是會遮罩文本和無法顯示圓角,使用其layer
層的現有接口似乎更簡單快捷,所以着手修改其layer
層來實現了。
CustomButton
NSView
都有一個wantsUpdateLayer
,默認返回NO
時視圖會默認調用drawRect
方法,當返回爲YES
時,會調用- (void)updateLayer
方法
- (BOOL)wantsUpdateLayer {
return YES;
}
- (void)updateLayer {
//changed to the width or height of a single source pixel centered at the specified location.
self.layer.contentsCenter = CGRectMake(0.5, 0.5, 0, 0);
//setImage
self.layer.backgroundColor = _backgroundColor.CGColor;
self.layer.cornerRadius = _cornerRadius;
self.layer.shadowColor = _backgroundColor.CGColor;
if (!CGSizeEqualToSize(CGSizeZero, _shadowOffset)) {
self.layer.masksToBounds = NO;
self.layer.shadowOffset = CGSizeMake(1, 2);
self.layer.shadowRadius = 6.f;
self.layer.shadowOpacity = 1;
}
}
代碼
CustomButton.h
//
// CustomButton.h
// Training
//
// Created by gensee on 2020/1/3.
// Copyright © 2020年 Gensee Inc. All rights reserved.
//
#import <Cocoa/Cocoa.h>
//用於藍色底色或者自定義底色的button按鈕
NS_ASSUME_NONNULL_BEGIN
@interface CustomButton : NSButton
/**
背景色 - 默認是APP的藍色按鈕
*/
@property (strong) NSColor *backgroundColor;
/**
陰影偏移量 - 如果不需要陰影請不要設置
*/
@property (assign) CGSize shadowOffset;
/**
圓角的半徑 - 默認爲4
*/
@property (assign) CGFloat cornerRadius;
/**
設置標題 - 這只是一個快捷方法,你可以根據富文本內容設置更多自定標題
@param title 內容
@param textColor 顏色
*/
- (void)setTitle:(NSString *)title color:(NSColor *)textColor font:(CGFloat)fontsize;
@end
NS_ASSUME_NONNULL_END
CustomButton.m
//
// CustomButton.m
// Training
//
// Created by gensee on 2020/1/3.
// Copyright © 2020年 Gensee Inc. All rights reserved.
//
#import "CustomButton.h"
@implementation CustomButton
- (instancetype)initWithFrame:(NSRect)frameRect {
if (self = [super initWithFrame:frameRect]) {
[self setup];
}
return self;
}
- (instancetype)init {
if (self = [super init]) {
[self setup];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder {
if (self = [super initWithCoder:coder]) {
[self setup];
}
return self;
}
- (void)setup {
_backgroundColor = [NSColor colorWithRed:62/255.f green:175/255.f blue:14/255.f alpha:1];
_shadowOffset = CGSizeZero;
_cornerRadius = 4.f;
}
- (void)setTitle:(NSString *)title color:(NSColor *)textColor font:(CGFloat)fontsize;{
NSMutableAttributedString *attrTitle = [[NSMutableAttributedString alloc] initWithString:title];
NSUInteger len = [attrTitle length];
NSRange range = NSMakeRange(0, len);
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.alignment = NSTextAlignmentCenter;
[attrTitle addAttribute:NSForegroundColorAttributeName value:textColor
range:range];
[attrTitle addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:fontsize]
range:range];
[attrTitle addAttribute:NSParagraphStyleAttributeName value:paragraphStyle
range:range];
[attrTitle fixAttributesInRange:range];
[self setAttributedTitle:attrTitle];
attrTitle = nil;
[self setNeedsDisplay:YES];
}
/**
繪製方法由updateLayer替換
*/
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
}
- (BOOL)wantsUpdateLayer {
return YES;
}
- (void)updateLayer {
//changed to the width or height of a single source pixel centered at the specified location.
self.layer.contentsCenter = CGRectMake(0.5, 0.5, 0, 0);
//setImage
self.layer.backgroundColor = _backgroundColor.CGColor;
self.layer.cornerRadius = _cornerRadius;
self.layer.shadowColor = _backgroundColor.CGColor;
if (!CGSizeEqualToSize(CGSizeZero, _shadowOffset)) {
self.layer.masksToBounds = NO;
self.layer.shadowOffset = CGSizeMake(1, 2);
self.layer.shadowRadius = 6.f;
self.layer.shadowOpacity = 1;
}
}
@end
使用方法
- (void)showStartBtn {
if (!self.startButton) {
CGSize loadsize = CGSizeMake(180, 60);
self.startButton = [[CustomButton alloc] initWithFrame:CGRectMake((self.view.bounds.size.width - loadsize.width)/2, (self.view.bounds.size.height - loadsize.height)/2, loadsize.width, loadsize.height)];
self.startButton.shadowOffset = CGSizeMake(1, 2);
[self.startButton setTitle:@"開始上課" color:[NSColor whiteColor] font:18];
self.startButton.target = self;
self.startButton.action = @selector(beginToLive);
}
[self.view addSubview:self.startButton];
}
效果如下:
都很簡單,只是爲了方便使用,打卡記錄