针对系统原生的菊花视图(NSProgressIndicator
类实例),封装一个较为完善的加载视图!
为工程创建一个新的视图——GYHLoadProgress
类!
对应的“.h”文件:
#import
NS_ASSUME_NONNULL_BEGIN
@interface GYHLoadProgress : NSView
@property (nonatomic, strong) NSView * totalProgressV;//整个‘加载中’视图
@property (nonatomic, strong) NSProgressIndicator * progIndicator;//’加载中‘视图(菊花)
@property (nonatomic, strong) NSTextField * showNoticeLabel;
//属性——backGroundColor(背景色)、textFont(字体大小)、 //可根据自己需求来进行添加,比如:textColor(字体色)、等
@property (nonatomic, strong) NSColor * backGroundColor;
@property (nonatomic, assign) CGFloat textFont;
//方法——显示、隐藏
-(void)startTheProgressWithStr:(NSString *)str; //显示——开启 旋转
-(void)stopTheProgressAnimation; //隐藏——停止 旋转
@end
NS_ASSUME_NONNULL_END
对应的“.m”文件:
#import "GYHLoadProgress.h"
@implementation GYHLoadProgress
-(instancetype)initWithFrame:(NSRect)frameRect {
if (self = [super initWithFrame:frameRect]) {
CGFloat progressV_W = frameRect.size.width;
_totalProgressV = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, progressV_W, progressV_W)];//整个‘加载中’视图
[self addSubview:_totalProgressV];
//为_totalProgressV添加约束
_totalProgressV.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint * total_progressV_CenterX = [_totalProgressV.centerXAnchor constraintEqualToAnchor:self.centerXAnchor constant:0.f];
NSLayoutConstraint * total_progressV_CenterY = [_totalProgressV.centerYAnchor constraintEqualToAnchor:self.centerYAnchor constant:0.f];
NSLayoutConstraint * total_progressV_Width = [_totalProgressV.widthAnchor constraintEqualToConstant:progressV_W];
NSLayoutConstraint * total_progressV_Height = [_totalProgressV.heightAnchor constraintEqualToConstant:progressV_W];
[self addConstraints:@[total_progressV_CenterX,total_progressV_CenterY,total_progressV_Width,total_progressV_Height]];
_totalProgressV.wantsLayer = YES;
_totalProgressV.layer.backgroundColor = [NSColor whiteColor].CGColor;//背景色:白色
_totalProgressV.layer.masksToBounds = YES;
_totalProgressV.layer.cornerRadius = 5.f;//切圆角
_totalProgressV.hidden = YES;//(默认)隐藏
CGFloat totalProgressV_W = (1.f/2.f)*progressV_W;
CGFloat progress_Offset_Y = -8.0f;
_progIndicator = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(0, 0, totalProgressV_W, totalProgressV_W)]; //’加载中‘视图(菊花)
[_totalProgressV addSubview:_progIndicator];
//为_progIndicator添加约束
_progIndicator.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint * progressV_CenterX = [_progIndicator.centerXAnchor constraintEqualToAnchor:_totalProgressV.centerXAnchor constant:0.f];
NSLayoutConstraint * progressV_CenterY = [_progIndicator.centerYAnchor constraintEqualToAnchor:_totalProgressV.centerYAnchor constant:progress_Offset_Y];
NSLayoutConstraint * progressV_Width = [_progIndicator.widthAnchor constraintEqualToConstant:totalProgressV_W];
NSLayoutConstraint * progressV_Height = [_progIndicator.heightAnchor constraintEqualToConstant:totalProgressV_W];
[self addConstraints:@[progressV_CenterX,progressV_CenterY,progressV_Width,progressV_Height]];
_progIndicator.style = NSProgressIndicatorStyleSpinning; //条形样式,菊花样式
_progIndicator.controlSize = NSControlSizeRegular; //大小,可选 regular small mini
[_progIndicator sizeToFit]; //size适配菊花大小,多余的舍弃
_progIndicator.minValue = 0;
_progIndicator.maxValue = 100; //最大值默认为100, 不是1,和progress不同
//[_progIndicator setIndeterminate:NO]; // YES:不显示当前进度 NO:精准显示当前进度
CGFloat showLB_W = progressV_W; CGFloat showLB_H = (1.f/5.f)*progressV_W;
CGFloat showLB_X = 0.f; CGFloat showLB_Y = 0.f;
_showNoticeLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(showLB_X, showLB_Y, showLB_W, showLB_H)];//文字提示Label
[_totalProgressV addSubview:_showNoticeLabel];
_showNoticeLabel.bordered = NO;
_showNoticeLabel.editable = NO; _showNoticeLabel.enabled = NO;//不可操作,当作Label!
_showNoticeLabel.alignment = NSTextAlignmentCenter; //字体 居中
_showNoticeLabel.lineBreakMode = NSLineBreakByCharWrapping;//换行模式:字符边界
_showNoticeLabel.backgroundColor = [NSColor clearColor];
_showNoticeLabel.textColor = [NSColor blackColor]; //textColor(字体色)
self.textFont = 10.0; //textFont(字体大小)
_showNoticeLabel.font = [NSFont labelFontOfSize:self.textFont];
}
return self;
}
//属性——backGroundColor(背景色)、textFont(字体大小)、
-(void)setBackGroundColor:(NSColor *)backGroundColor {
_backGroundColor = backGroundColor;
_totalProgressV.layer.backgroundColor = backGroundColor.CGColor;
}
-(void)setTextFont:(CGFloat)textFont {
_textFont = textFont;
self.showNoticeLabel.font = [NSFont systemFontOfSize:textFont];
}
//方法——显示、隐藏
-(void)startTheProgressWithStr:(NSString *)str {
dispatch_async(dispatch_get_main_queue(), ^{
self.totalProgressV.hidden = NO; //整个‘加载中’视图
[self.progIndicator startAnimation:nil]; //开始动画
self.showNoticeLabel.stringValue = str;
});
}
-(void)stopTheProgressAnimation {
dispatch_async(dispatch_get_main_queue(), ^{
self.totalProgressV.hidden = YES;
[self.progIndicator stopAnimation:nil]; //结束动画
self.showNoticeLabel.stringValue = @"";
});
}
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
// Drawing code here.
}
@end
使用:在ViewController中
CGFloat progressV_W = 100.f;
GYHLoadProgress * gyhProgress = [[GYHLoadProgress alloc] initWithFrame:NSMakeRect(0, 0, progressV_W, progressV_W)];//整个‘加载中’视图
[self.view addSubview:gyhProgress];
//添加约束,始终居于viewController对应视图的中央!
gyhProgress.translatesAutoresizingMaskIntoConstraints = NO;//必须书写
NSLayoutConstraint * total_progressV_CenterX = [gyhProgress.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor constant:0.f];
NSLayoutConstraint * total_progressV_CenterY = [gyhProgress.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor constant:0.f];
NSLayoutConstraint * total_progressV_Width = [gyhProgress.widthAnchor constraintEqualToConstant:progressV_W];
NSLayoutConstraint * total_progressV_Height = [gyhProgress.heightAnchor constraintEqualToConstant:progressV_W];
[self.view addConstraints:@[total_progressV_CenterX,total_progressV_CenterY,total_progressV_Width,total_progressV_Height]];
//开始动画 显示——开启 旋转
[gyhProgress startTheProgressWithStr:@"加载中..."];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{//延时3s
[gyhProgress setBackGroundColor:[NSColor redColor]];//改为红色
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{//延时5s
//停止动画 隐藏——停止 旋转
[gyhProgress stopTheProgressAnimation];
});
效果:
a.由于对GYHLoadProgress
实例添加了约束,所以会一直居中!
b.延时3.0s时改变颜色为红色,延时5.0s时隐藏!
Tips:对于
NSTextField
字体过长的处理!修改代码
[gyhProgress startTheProgressWithStr:@"加载中..."];
为[gyhProgress startTheProgressWithStr:@"Loading...加载中。。。"];
后,NSTextField会显示不全!思路:目前思路有 1.增加行数、2.计算该使用的准确字体大小(
font
)!采取的解决方案:2.计算该使用的准确字体大小(
font
)——Label宽度固定,行数为1
参 《iOS\Mac OS 根据字体大小、控件宽度,计算字符串展示时尺寸!》中的“- (NSSize)sizeForLblContent:(NSString *)strContent fixMaxWidth:(CGFloat)w andFondSize:(int)fontSize;
”方法!
在-(void)startTheProgressWithStr:(NSString *)str
方法中:使用递归方法“-(void)adjustTheLabelFontWithStr:(NSString *)str
”来设置字体大小!-(void)startTheProgressWithStr:(NSString *)str { dispatch_async(dispatch_get_main_queue(), ^{ //主线程 self.totalProgressV.hidden = NO; //整个‘加载中’视图 [self.progIndicator startAnimation:nil]; //开始动画 self.showNoticeLabel.stringValue = str; [self adjustTheLabelFontWithStr:str]; }); }
递归方法:
-(void)adjustTheLabelFontWithStr:(NSString *)str
-(void)adjustTheLabelFontWithStr:(NSString *)str {//使用递归方法,设置好对应字体大小(NSFont) CGFloat maxWidth = (self.showNoticeLabel.frame.size.width - 5); NSSize size = [self sizeForLblContent:str fixMaxWidth:maxWidth andFondSize:self.textFont]; NSLog(@"%lf %lf",size.height,self.showNoticeLabel.frame.size.height); if (size.height < self.showNoticeLabel.frame.size.height) { //计算得到的高度在控件范围 } else { //计算得到的高度超过控件范围,重新设置NSTextField的font属性! CGFloat newFontNum = self.textFont - 1.0; NSLog(@"newFontNum:%lf",newFontNum); self.textFont = newFontNum; self.showNoticeLabel.font = [NSFont systemFontOfSize:newFontNum]; [self adjustTheLabelFontWithStr:str]; } }
效果:文字展示完整!
XCode打印:字体变为8号!
goyohol's essay