文章目录
- 前言
- 核心思想
- 具体的实现步骤
- I 、使用方法
- II、实现细节
- 2.1 使用宏进行block属性的声明
- 2.2 代码
- see also
前言
block 的妙用:结合block和方法的优点实现iOS的链式编程
-【 完整pod 仓库源码GitHub】
主要针对段落样式NSMutableParagraphStyle
和富文本NSMutableAttributedString
进行封装
- 代码效果
xx.kn_addString(@"封装富文本API").kn_fontColor(UIColor.redColor).kn_addString(@"采用block实现链式编程").kn_fontColor(UIColor.blueColor).kn_addString(@"!");
核心思想
- 实现步骤:方法的返回值是block,block必须有返回值(本身对象),block参数(需要操作的值)
- 链式编程特点:
将多个操作(多行代码)通过点号(.)链接在一起成为一句代码,使代码可读性好a(1).b(2).c(3)。
具体的实现步骤
- 声明block属性
k_PropertyStatement(strong, NSMutableAttributedString, NSString*, kn_addString)// 好处是Xcode的提示比较友好 //- (NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_addString// 不推荐直接声明getter方法,推荐上面的声明的block属性
- 实现getter方法
- (NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_addString{ return ^id(NSString *str){ NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc]initWithString:str]; self.leftStr = str; [self appendAttributedString:attStr]; return self; }; } 1
I 、使用方法
- Installation
pod 'ChainAttributedString'
- 声明
//#import <ChainAttributedString/ChainAttributedString-umbrella.h> #import <ChainAttributedString/NSMutableAttributedString+Chain.h>
- demo
UILabel *x = [UILabel new]; x.textAlignment = NSTextAlignmentCenter; [self.view addSubview:x]; x.frame = self.view.frame; x.numberOfLines = 0; NSMutableAttributedString *xx = [[NSMutableAttributedString alloc]init]; xx.kn_addString(@"封装富文本API").kn_fontColor(UIColor.redColor).kn_addString(@"采用block实现链式编程").kn_fontColor(UIColor.blueColor).kn_addString(@"!"); x.attributedText =xx;
II、实现细节
2.1 使用宏进行block属性的声明
#define k_PropertyStatement(propertyModifier,className, propertyPointerType, propertyName) \ @property (nonatomic, propertyModifier) className *(^propertyName)(propertyPointerType); - (NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_addString; 直接声明方法也行 #define k_methodStatement(returnClassName,paramPointerType, methodName) \ - (returnClassName * _Nonnull (^)(paramPointerType * _Nonnull))methodName;
2.2 代码
- NSMutableAttributedString+Chain.h
// block 的妙用:结合block和方法的优点实现iOS的链式编程 //其他更多链式编程的例子:https://github.com/zhangkn/DKUsingblockImplementChainProgramming /** 核心思想 */ //核心的实现步骤:方法的返回值是block,block必须有返回值(本身对象),block参数(需要操作的值) //链式编程特点:将多个操作(多行代码)通过点号(.)链接在一起成为一句代码,使代码可读性好a(1).b(2).c(3)。 //##------ 实现链式编程的两种形式:本质都是一样的,就是执行(getter)方法之后,得到一个block,block必须有返回值(本身对象),block参数(需要操作的值) //1、声明方法: 缺点就是 Xcode提示不太友好。不推荐 声明方法的返回值是block,block必须有返回值(本身对象),block参数(需要操作的值) //p.run() <=> [p run]();//执行方法的同时之后,立即执行方法返回的block //2、声明属性: 本质就是利用他的getter方法 //声明属性,属性的类型是block,block必须有返回值(本身对象),block参数(需要操作的值) //---------## #import "kConst.h" #import <Foundation/Foundation.h> /** 用于动态新增属性 */ #import <objc/runtime.h> NS_ASSUME_NONNULL_BEGIN /* // NSUnderlineStyleNone 不设置下划线/删除线 // NSUnderlineStyleSingle 设置下划线/删除线为细的单线 // NSUnderlineStyleThick 设置下划线/删除线为粗的单线 // NSUnderlineStyleDouble 设置下划线/删除线为细的双线 // NSUnderlinePatternSolid 设置下划线/删除线样式为连续的实线 // NSUnderlinePatternDot 设置下划线/删除线样式为点,也就是虚线,比如这样:------ // NSUnderlinePatterDash 设置下划线/删除线样式为破折号,比如这样:—— —— —— // NSUnderlinePatternDashDot 设置下划线/删除线样式为连续的破折号和点,比如这样:——-——-——- // NSUnderlinePatternDashDotDot 设置下划线/删除线样式为连续的破折号、点、点,比如:——--——--——-- // NSUnderlineByWord 在有空格的地方不设置下划线/删除线 */ static const char leftMutableAttributedStringKey; @interface NSMutableAttributedString (Chain) /** 记录最近一次新添加的富文本对应的字符串,以便进行后续的其他操作 */ @property (strong, nonatomic) NSString *leftStr; //每次kn_addString就是一句新的富文本 //kn_addString方法的返回值是block,block必须有返回值(本身对象),block参数(需要操作的值) //富文本的block属性,发返回值就是自己,block的参数类型propertyPointerType //k_PropertyStatement(strong, NSMutableAttributedString, NSString*, kn_addString) k_PropertyStatement(strong, NSMutableAttributedString, NSString*, kn_addString) //- (NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_addString; 直接声明方法也行 // 字体颜色 k_PropertyStatement(strong, NSMutableAttributedString, UIColor*, kn_fontColor) // 字体大小 k_PropertyStatement(strong, NSMutableAttributedString, UIFont*, kn_fontSize); // 字体背景颜色 k_PropertyStatement(strong, NSMutableAttributedString, UIColor*, kn_fontBgColor); // 字体间距 k_PropertyStatement(assign, NSMutableAttributedString, NSInteger, kn_fontSpacing); // 删除线 k_PropertyStatement(assign, NSMutableAttributedString, NSUnderlineStyle, kn_strikethrough); // 删除线颜色 k_PropertyStatement(strong, NSMutableAttributedString, UIColor*, kn_strikethroughColor); // 下划线 k_PropertyStatement(assign, NSMutableAttributedString, NSUnderlineStyle, kn_underline); // 下划线颜色 k_PropertyStatement(strong, NSMutableAttributedString, UIColor*, kn_underlineColor); // 笔画宽度 正值中空 负值填充 k_PropertyStatement(assign, NSMutableAttributedString, NSInteger, kn_strokeWidth); // 笔画颜色 k_PropertyStatement(strong, NSMutableAttributedString, UIColor*, kn_strokeColor); // 倾斜 正值右倾,负值左倾 k_PropertyStatement(assign, NSMutableAttributedString, CGFloat, kn_obliqueness); // 书写方向 //@(NSWritingDirectionRightToLeft|NSWritingDirectionOverride)倒着写 k_PropertyStatement(strong, NSMutableAttributedString, NSArray*, kn_direction); // 跳转URL k_PropertyStatement(strong, NSMutableAttributedString, NSString*, kn_link); // 图文混排等 k_PropertyStatement(strong, NSMutableAttributedString, NSTextAttachment*, kn_attachment); // 段落属性 k_PropertyStatement(strong, NSMutableAttributedString, NSMutableParagraphStyle*, kn_paragraph); @end NS_ASSUME_NONNULL_END 1 2
- NSMutableAttributedString+Chain.m
// // NSMutableAttributedString+Chain.m // ChainAttributedString // // Created by mac on 2020/8/6. // #import "NSMutableAttributedString+Chain.h" @implementation NSMutableAttributedString (Chain) - (void)setLeftStr:(NSString *)leftStr{ objc_setAssociatedObject(self, &leftMutableAttributedStringKey, leftStr, OBJC_ASSOCIATION_COPY); } - (NSString *)leftStr{ return objc_getAssociatedObject(self, &leftMutableAttributedStringKey); } - (void)setKn_addString:(NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_addString{ } - (NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_addString{ return ^id(NSString *str){ NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc]initWithString:str]; self.leftStr = str; [self appendAttributedString:attStr]; return self; }; } - (void)setKn_fontColor:(NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_fontColor{} - (NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_fontColor{ return ^id(UIColor *color){ if ([self.leftStr isEqualToString:@""]) { [self addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(0, self.length)]; }else{ [self addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)]; } return self; }; } - (void)setKn_fontSize:(NSMutableAttributedString * _Nonnull (^)(UIFont * _Nonnull))kn_fontSize{}; - (NSMutableAttributedString * _Nonnull (^)(UIFont * _Nonnull))kn_fontSize{ return ^id(UIFont *size) { if ([self.leftStr isEqualToString:@""]) { [self addAttribute:NSFontAttributeName value:size range:NSMakeRange(0, self.length)]; }else{ [self addAttribute:NSFontAttributeName value:size range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)]; } return self; }; } - (void)setKn_fontBgColor:(NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_fontBgColor{}; - (NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_fontBgColor{ return ^id(UIColor *bgColor){ if ([self.leftStr isEqualToString:@""]) { [self addAttribute:NSBackgroundColorAttributeName value:bgColor range:NSMakeRange(0, self.length)]; }else{ [self addAttribute:NSBackgroundColorAttributeName value:bgColor range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)]; } return self; }; } - (void)setKn_fontSpacing:(NSMutableAttributedString * _Nonnull (^)(NSInteger))kn_fontSpacing{}; - (NSMutableAttributedString * _Nonnull (^)(NSInteger))kn_fontSpacing{ return ^id(NSInteger spacing){ if ([self.leftStr isEqualToString:@""]) { [self addAttribute:NSKernAttributeName value:@(spacing) range:NSMakeRange(0, self.length)]; }else{ [self addAttribute:NSKernAttributeName value:@(spacing) range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)]; } return self; }; } - (void)setKn_strikethrough:(NSMutableAttributedString * _Nonnull (^)(NSUnderlineStyle))kn_strikethrough{}; - (NSMutableAttributedString * _Nonnull (^)(NSUnderlineStyle))kn_strikethrough{ return ^id(NSUnderlineStyle style){ if ([self.leftStr isEqualToString:@""]) { [self addAttribute:NSStrikethroughStyleAttributeName value:@(style) range:NSMakeRange(0, self.length)]; }else{ [self addAttribute:NSStrikethroughStyleAttributeName value:@(style) range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)]; } return self; }; } - (void)setKn_strikethroughColor:(NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_strikethroughColor{}; - (NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_strikethroughColor{ return ^id(UIColor *color){ if ([self.leftStr isEqualToString:@""]) { [self addAttribute:NSStrikethroughColorAttributeName value:color range:NSMakeRange(0, self.length)]; }else{ [self addAttribute:NSStrikethroughColorAttributeName value:color range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)]; } return self; }; } - (void)setKn_underline:(NSMutableAttributedString * _Nonnull (^)(NSUnderlineStyle))kn_underline{}; - (NSMutableAttributedString * _Nonnull (^)(NSUnderlineStyle))kn_underline{ return ^id(NSUnderlineStyle style){ if ([self.leftStr isEqualToString:@""]) { [self addAttribute:NSUnderlineStyleAttributeName value:@(style) range:NSMakeRange(0, self.length)]; }else{ [self addAttribute:NSUnderlineStyleAttributeName value:@(style) range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)]; } return self; }; } - (void)setKn_underlineColor:(NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_underlineColor{}; - (NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_underlineColor{ return ^id(UIColor *color){ if ([self.leftStr isEqualToString:@""]) { [self addAttribute:NSUnderlineColorAttributeName value:color range:NSMakeRange(0, self.length)]; }else{ [self addAttribute:NSUnderlineColorAttributeName value:color range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)]; } return self; }; } - (void)setKn_strokeWidth:(NSMutableAttributedString * _Nonnull (^)(NSInteger))kn_strokeWidth{}; - (NSMutableAttributedString * _Nonnull (^)(NSInteger))kn_strokeWidth{ return ^id(NSInteger width){ if ([self.leftStr isEqualToString:@""]) { [self addAttribute:NSStrokeWidthAttributeName value:@(width) range:NSMakeRange(0, self.length)]; }else{ [self addAttribute:NSStrokeWidthAttributeName value:@(width) range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)]; } return self; }; } - (void)setKn_strokeColor:(NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_strokeColor{}; - (NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_strokeColor{ return ^id(UIColor *color){ if ([self.leftStr isEqualToString:@""]) { [self addAttribute:NSStrokeColorAttributeName value:color range:NSMakeRange(0, self.length)]; }else{ [self addAttribute:NSStrokeColorAttributeName value:color range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)]; } return self; }; } - (void)setKn_obliqueness:(NSMutableAttributedString * _Nonnull (^)(CGFloat))kn_obliqueness{}; - (NSMutableAttributedString * _Nonnull (^)(CGFloat))kn_obliqueness{ return ^id(CGFloat obliqueness){ if ([self.leftStr isEqualToString:@""]) { [self addAttribute:NSObliquenessAttributeName value:@(obliqueness) range:NSMakeRange(0, self.length)]; }else{ [self addAttribute:NSObliquenessAttributeName value:@(obliqueness) range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)]; } return self; }; } - (void)setKn_direction:(NSMutableAttributedString * _Nonnull (^)(NSArray * _Nonnull))kn_direction{}; - (NSMutableAttributedString * _Nonnull (^)(NSArray * _Nonnull))kn_direction{ return ^id(NSArray *direction){ if ([self.leftStr isEqualToString:@""]) { [self addAttribute:NSWritingDirectionAttributeName value:direction range:NSMakeRange(0, self.length)]; }else{ [self addAttribute:NSWritingDirectionAttributeName value:direction range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)]; } return self; }; } - (void)setKn_link:(NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_link{}; - (NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_link{ return ^id(NSString *link){ if ([self.leftStr isEqualToString:@""]) { [self addAttribute:NSLinkAttributeName value:[NSURL URLWithString:link] range:NSMakeRange(0, self.length)]; }else{ [self addAttribute:NSLinkAttributeName value:[NSURL URLWithString:link] range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)]; } return self; }; } - (void)setKn_attachment:(NSMutableAttributedString * _Nonnull (^)(NSTextAttachment * _Nonnull))kn_attachment{} - (NSMutableAttributedString * _Nonnull (^)(NSTextAttachment * _Nonnull))kn_attachment{ return ^id(NSTextAttachment *attachment){ NSAttributedString * imageStr = [NSAttributedString attributedStringWithAttachment:attachment]; [self appendAttributedString:imageStr]; return self; }; } - (void)setKn_paragraph:(NSMutableAttributedString * _Nonnull (^)(NSMutableParagraphStyle * _Nonnull))kn_paragraph{}; - (NSMutableAttributedString * _Nonnull (^)(NSMutableParagraphStyle * _Nonnull))kn_paragraph{ return ^id(NSMutableParagraphStyle *paragraph){ if ([self.leftStr isEqualToString:@""]) { [self addAttribute:NSParagraphStyleAttributeName value:paragraph range:NSMakeRange(0, self.length)]; }else{ [self addAttribute:NSParagraphStyleAttributeName value:paragraph range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)]; } return self; }; } @end 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16