【封装富文本API,采用block实现链式编程】(block 的妙用:结合block和方法的优点实现iOS的链式编程)

简介: 【封装富文本API,采用block实现链式编程】(block 的妙用:结合block和方法的优点实现iOS的链式编程)

文章目录

  • 前言

  • 核心思想
  • 具体的实现步骤
  • 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(@"!");

image.png

image.png

核心思想

  • 实现步骤:方法的返回值是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
目录
相关文章
|
14天前
|
JSON 安全 API
Microsoft邮箱API发送邮件的方法和步骤
Aoksend详解如何使用Microsoft邮箱API发送邮件:1. 在Azure创建应用并获取访问权限;2. 设置API请求头,含Authorization和Content-Type;3. 构建JSON格式的邮件内容;4. 使用POST方法发送至API端点;5. 检查响应处理发送结果。遵循最佳实践,安全集成邮件功能。
|
15天前
|
缓存 前端开发 API
API接口封装系列
API(Application Programming Interface)接口封装是将系统内部的功能封装成可复用的程序接口并向外部提供,以便其他系统调用和使用这些功能,通过这种方式实现系统之间的通信和协作。下面将介绍API接口封装的一些关键步骤和注意事项。
|
17天前
|
搜索推荐 JavaScript 前端开发
Gmail邮箱API发送邮件的方法有什么
使用Gmail API发送邮件,需先获取API访问权限,包括在Google Cloud Platform上创建项目,启用Gmail API,生成API密钥或OAuth 2.0凭据。然后,用Python等编程语言设置API请求,指定邮件详情。发送简单邮件涉及创建Base64编码的消息体,而带附件的邮件需编码为multipart格式。可添加邮件头信息,并处理发送结果以确保成功。Gmail API使应用能集成自动化、个性化的邮件发送功能,提升效率和体验。
|
1月前
|
人工智能 Java API
Google Gemini API 接口调用方法
Google 最近发布的 Gemini 1.0 AI 模型通过其升级版,Gemini,标志着公司迄今为止最为强大和多功能的人工智能技术的突破。
|
1天前
|
API PHP 数据安全/隐私保护
IMAP邮箱API接收收取邮件的方法和步骤
IMAP邮箱API是用于自动接收和管理邮件的接口,允许程序无须手动登录即可操作邮件。要使用它,需先配置邮箱允许API访问,选择如Python的imaplib或PHP的imap扩展等IMAP库,然后连接到邮箱服务器,接收和处理邮件。处理完毕后断开连接。AokSend提供高效发信服务,支持SMTP/API接口。使用IMAP API能提升邮件管理效率。
|
1天前
|
API 网络安全 数据安全/隐私保护
SMTP邮件邮箱API发送邮件的方法和步骤
使用SMTP邮件邮箱API(如AokSend)发送邮件涉及6个步骤:获取SMTP服务器地址和端口,进行身份验证,构建邮件内容,连接到服务器,发送邮件及处理结果。例如,Gmail的SMTP服务器地址是smtp.gmail.com,端口587。此方法适用于程序化发送邮件,确保安全并支持大规模发信服务。
|
2天前
|
API Python
Relay邮件邮箱API发送邮件的方法和步骤
Relay邮件邮箱API是编程发送邮件的工具,允许用户通过代码实现邮件发送。发送步骤包括:获取API密钥、设置发件人和收件人信息、编写邮件内容,最后调用API发送。Python示例代码展示了如何使用API发送邮件,需替换API密钥和邮箱地址。
|
6天前
|
API 开发者 Python
SendCloud和Aoksend邮箱API发送邮件的方法
本文介绍了如何使用Aoksend和SendCloud的API发送邮件。首先注册两个平台的账号获取API密钥和地址,然后可通过SMTP或HTTP API发送邮件。示例代码分别展示了使用SMTP API(通过`smtplib`)和HTTP API(借助`requests`库)的Python实现。在实际操作中,需确保邮件内容与收件人信息的准确性。
|
6天前
|
安全 API 开发者
Zoho Mail邮箱API发送邮件的方法
Zoho Mail提供了强大的API,使开发者可以通过编程方式轻松地使用Zoho Mail发送邮件。aoksend将介绍如何使用Zoho Mail邮箱API发送邮件,以及一些常见的用法示例。
|
15天前
|
监控 安全 API
Office365邮箱API发送邮件有什么值得推荐的方法
使用Office365邮箱API发送邮件时,建议采用OAuth认证确保安全;利用RESTful API简化流程;借助官方客户端库加速集成;遵循最佳实践保障安全可靠;批量发送时使用异步方式提升效率;监控调试以解决问题;注意避免触发垃圾邮件过滤。AokSend提供高效发信服务,支持触发式接口和SMTP/API,独立IP确保高触达。