创建时间:2021-04-22
本文旨在将编码过程变为模块化、对象化的过程
一、基本控件的初始化
UILabel
- (UILabel *)remindLabel {
if (!_remindLabel) {
_remindLabel = [[UILabel alloc] init];
_remindLabel.frame = CGRectMake(0, kStatusBarHeight+90, kScreenWidth, 20);
_remindLabel.textColor = [UIColor colorWithHexString:@"#60b4e6"];
_remindLabel.font = kRegularFont(14);
_remindLabel.textAlignment = NSTextAlignmentCenter;
_remindLabel.backgroundColor = [UIColor clearColor];
[self.view addSubview:_remindLabel];
}
return _remindLabel;
}
UIImageView
- (UIImageView *)imgView {
if (!_imgView) {
_imgView = [[UIImageView alloc] init];
_imgView.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame));
_imgView.backgroundColor = [UIColor clearColor];
_imgView.contentMode = UIViewContentModeScaleAspectFill;
[self addSubview:_imgView];
}
return _imgView;
}
UIButton
- (UIButton *)publishBtn {
if (!_publishBtn) {
_publishBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_publishBtn.frame = CGRectMake(kScreenWidth-67, kStatusBarHeight+3, 62, 32);
[_publishBtn setTitle:@"发布" forState:UIControlStateNormal];
_publishBtn.titleLabel.font = kMediumFont(16);
[_publishBtn setTitleColor:[UIColor colorWithHexString:@"#0A1F44"] forState:UIControlStateNormal];
[_publishBtn setBackgroundColor:[UIColor clearColor]];
[_publishBtn addTarget:self action:@selector(requestOfPublishDynamic) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_publishBtn];
}
return _publishBtn;
}
UITextView
- (UITextView *)textView {
if (!_textView) {
_textView = [[UITextView alloc] init];
_textView.font = kRegularFont(14);
_textView.showsHorizontalScrollIndicator = false;
_textView.backgroundColor = KRGB(0xF7F7F7);
_textView.showsVerticalScrollIndicator = false;
_textView.returnKeyType = UIReturnKeySend;
_textView.delegate = self;
_textView.text = @"请输入消息...";
_textView.textColor = KRGB(0xC1C0C9);
[_textContainerView addSubview:_textView];
}
return _textView;
}
UIScrollView
- (UIScrollView *)scrollView {
if (!_scrollView) {
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 40, kScreenWidth, WhiteBgViewHeight-40)];
_scrollView.delegate = self;
_scrollView.backgroundColor = [UIColor whiteColor];
_scrollView.pagingEnabled = YES;
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.showsHorizontalScrollIndicator = NO;
[self addSubview:_scrollView];
_scrollView.contentSize = CGSizeMake(2*kScreenWidth, 0);
}
return _scrollView;
}
UITableView
//UITableView懒加载
- (UITableView *)tableView {
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, kTopHeight, KScreenWidth, KScreenHeight-kTopHeight) style:UITableViewStyleGrouped];
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.backgroundColor = kSystemBgColor;
[_tableView setSeparatorColor:kSystemBgColor];
[_tableView registerClass:[LWYMyCollectionCell class] forCellReuseIdentifier:@"cellID"];
_tableView.separatorStyle = UITableViewCellEditingStyleNone; //让tableview不显示分割线
[self.view addSubview:_tableView];
kWeakSelf(self);
// 下拉刷新,上拉加载更多
_tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
[weakself requestOfMyCollectionData:YES];
}];
_tableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingBlock:^{
// 上拉加载更多
[weakself requestOfMyCollectionData:NO];
}];
// 为tableView添加长按手势
UILongPressGestureRecognizer *longPressGr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction:)];
longPressGr.minimumPressDuration = 0.5f;
longPressGr.numberOfTouchesRequired = 1;
[_tableView addGestureRecognizer:longPressGr];
_tableView.userInteractionEnabled = YES;
}
return _tableView;
}
//长按Cell的动作
- (void)longPressAction:(UILongPressGestureRecognizer *)longRecognizer {
if (longRecognizer.state == UIGestureRecognizerStateBegan) {
CGPoint point = [longRecognizer locationInView:_tableView];
NSIndexPath *indexPath = [_tableView indexPathForRowAtPoint:point]; // 可以获取我们在哪个cell上长按
if (indexPath != nil) {
}
}
}
UICollectionView
- (UICollectionView *)collectionview {
if (!_collectionview) {
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
_collectionview = [[UICollectionView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.searchbarView.frame) + 10, kScreenWidth, kScreenHeight*2.0/3.0 - 100) collectionViewLayout:flowLayout];
_collectionview.delegate = self;
_collectionview.dataSource = self;
_collectionview.backgroundColor = [UIColor clearColor];
_collectionview.showsVerticalScrollIndicator = NO;
[_collectionview registerClass:[LWYPersonalTagCell class] forCellWithReuseIdentifier:@"cellID"];
[self addSubview:_collectionview];
}
return _collectionview;
}
二、TableView相关
UITableView刷新单独的section或row
// 刷新section
NSIndexSet * indexSet = [[NSIndexSet alloc]initWithIndex:1];
[tableview reloadSections: indexSet withRowAnimation:UITableViewRowAnimationAutomatic];
// 刷新row
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:2 inSection:1];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation:UITableViewRowAnimationNone];
UITableView滚动到最后一行有数据的cell
类似于微信进入聊天详情后,最新的一条消息在最底部,但是如果消息条数过少,又不会cell硬塞到最底部
/// 滑动到最底部
- (void)scrollToBottom {
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01/*延迟执行时间*/ * NSEC_PER_SEC));
dispatch_after(delayTime, dispatch_get_main_queue(), ^{
if (self.dataSource.count > 0) {
if ([self.tableView numberOfRowsInSection:0] > 0) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:([self.tableView numberOfRowsInSection:0]-1) inSection:0];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];
}
}
});
}
判断UIScrollView/UITableView是向上还是向下滑动
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGPoint point = [scrollView.panGestureRecognizer translationInView:scrollView];
CGFloat offsetY = point.y;
if (offsetY < 0) {
// 下滑
} else {
// 上滑
}
}
获取TableView或CollectionView可视范围(自身frame)的Cell
self.tableView.visibleCells
self.collectionView.visibleCells
去除tableView底部多余行和分割线
tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
tableView.tableFooterView = nil;
隐藏所有分割线
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
设置分割线的颜色
tableView.separatorColor = [UIColor redColor];
三、协议和代理/委托
Delegate声明步骤A类
Aclass.h
//1.声明协议
@protocol AclassDelegate <NSObject>
@required //成为A类的代理/委托的类中必须实现的方法
- (void)mustDoSomething;
@optional //成为A类的代理/委托的类中可选择是否实现的方法
- (void)optionalDoSomething;
@end
//2.声明属性
@interface Aclass : NSObject
@property (nonatomic, weak) id <AclassDelegate>delegate;
@end
Aclass.m
//6.委托方通知代理人执行相应方法
if ([self.delegate respondsToSelector:@selector(mustDoSomething)])
[self.delegate mustDoSomething];
}
B类
Bclass.m
//3.代理人签订协议
@interface Bclass () <AclassDelegate>
@property (nonatomic, strong) Aclass *a;
@end
//4.委托方指定代理人
a.delegate = self;
//5.代理人实现协议方法
- (void *)mustDoSomething {}
四、NSURLSession
1. NSURLSessionDataTask发送get请求
// 1.创建request相关数据
NSString *str = @"http:/localhost:80/api/hello.json";
NSURL *url = [NSURL URLWithString:str];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 2.使用NSURLSession创建task任务
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data) {
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
if (result) {
dispatch_async(dispatch_get_main_queue(), ^{
});
}
}
}];
// 3.执行task任务
[task resume];
2. NSURLSessionDataTask发送post请求
// 1.创建request相关数据(post请求需要设置请求头和请求体,使用NSMutableURLRequest)
NSString *str = @"http:/localhost:80/api/hello.json";
NSURL *url = [NSURL URLWithString:str];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = [@"username=520&pwd=520&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
// 2.使用NSURLSession创建task任务
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data) {
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
if (result) {
dispatch_async(dispatch_get_main_queue(), ^{
});
}
}
}];
// 3.执行task任务
[task resume];
3. NSURLSessionDataTask设置代理发送请求
- (void)requestWithDelegate {
// 1.创建request相关数据
NSString *str = @"http:/localhost:80/api/hello.json";
NSURL *url = [NSURL URLWithString:str];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = [@"username=520&pwd=520&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
// 2.配置NSURLSession并设置其代理(queue是设置队列,若设置为nil,则默认在子线程中执行)
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
// 3.使用NSURLSession创建task任务
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
// 4.执行task任务
[dataTask resume];
}
#pragma mark - NSURLSessionDelegate
- (void)URLSession:(NSURLSession *)session dataTask:(nonnull NSURLSessionDataTask *)dataTask didReceiveResponse:(nonnull NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler {
//子线程中执行
NSLog(@"接收到服务器响应的时候调用 -- %@", [NSThread currentThread]);
self.resultData = [NSMutableData data];
//默认情况下不接收数据
//必须告诉系统是否接收服务器返回的数据
completionHandler(NSURLSessionResponseAllow);
}
- (void)URLSession:(NSURLSession *)session dataTask:(nonnull NSURLSessionDataTask *)dataTask didReceiveData:(nonnull NSData *)data {
NSLog(@"接受到服务器返回数据的时候调用,可能被调用多次");
//拼接服务器返回的数据
[self.resultData appendData:data];
}
- (void)URLSession:(NSURLSession *)session task:(nonnull NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error {
NSLog(@"请求完成或者是失败的时候调用");
//解析服务器返回数据
NSLog(@"%@", [[NSString alloc] initWithData:self.resultData encoding:NSUTF8StringEncoding]);
}
#pragma mark - 设置代理后解决强引用问题
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.session invalidateAndCancel]; //方法直接取消请求然后释放代理对象
[self.session finishTasksAndInvalidate]; //方法等请求完成之后释放代理对象
}
4. NSURLSessionDataTask 简单下载
// 1.创建request下载地址相关数据
NSString *str = @"http:/localhost:80/resource/IMG_1604.JPG";
NSURL *url = [NSURL URLWithString:str];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 2.使用 NSURLSession 对象创建一个 NSURLSessionDataTask 请求
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data) {
UIImage *img = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 100, 100)];
imgView.image = img;
[self.view addSubview:imgView];
});
}
}];
// 3.执行task任务
[task resume];
5. NSURLSessionDownloadTask 简单下载
// 1.创建request下载地址相关数据
NSString *str = @"http:/localhost:80/resource/IMG_1604.JPG";
NSURL *url = [NSURL URLWithString:str];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 2.使用 NSURLSession 对象创建一个 NSURLSessionDownloadTask 请求
NSURLSessionDownloadTask *downloadTask = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//默认存储到临时文件夹 tmp 中
NSLog(@"%@", location);//目标位置
//需要剪切文件到 cache
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]
stringByAppendingPathComponent:response.suggestedFilename];
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
}];
// 3.执行task任务
[downloadTask resume];
五、block代码块
1.block的声明
typedef void (^CompleteBlock)(void);
2.block作为属性(修饰符要使用copy)
//使用定义过的代码块
@property (nonatomic, copy) CompleteBlock block;
//直接在属性中定义
@property (nonatomic, copy) void (^completeBlock)(void);
3.block作为方法的参数
//使用定义过的代码块
- (void)doSomethingMethod:(CompleteBlock)block {
//做完了所需的操作后,执行block回调
block();
}
//直接在方法中定义
+ (void)doSomethingMethod:(void (^)(BOOL result, NSString *errorStr))block {
//做完了所需的操作后,执行block回调
if (1) {
block(YES, @"");
} else {
block(NO, @"这里是错误的原因");
}
}
4.block实现两个类之间的方法回调(同协议代理Delegate)
上面的delegate协议总共有6步,如果用block的话可以缩减为3步:
bolck实现回调流程
A类
//1.定义一个名为completeBlock的代码块属性
@property (nonatomic, copy) void (^completeBlock)(void);
//2.在需要的时候执行block
if (self. completeBlock) {
self. completeBlock();
}
B类
//3.初始化A类的对象a时
- (Aclass *)a {
if (!_a) {
_a = [[Aclass alloc] init];
[_a setCompleteBlock:^{
//次数为B执行的方法
}];
}
return _a;
}
3.利用block来实现一个异步方法执行完成的回调
/// 从服务器异步下载文件,并保存到本地生成地址
/// @param serverUrl 文件在服务器的url
/// @param completedBlock 完成回调
- (void)downloadFileFromUrl:(NSString *)serverUrl completed:(void (^)(BOOL successed, NSString *filePath))completedBlock {
//开启异步子线程下载文件
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *filePath = @"此处为设置的文件地址";
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:serverUrl]];
if ([data writeToFile:filePath atomically:YES]) {
completedBlock(YES, filePath);
} else {
completedBlock(NO, @"");
}
});
}
判断文件夹下是否存在指定文件(根据文件路径和文件名)
//1.获取文件的路径
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [NSString stringWithFormat:@"%@/%@", docPath,此处为目标文件的文件名];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
//文件存在
} else {
//文件不存在
}
在使用 fileExistsAtPath 判断的时候,如果不管本地是否存在的情况下一直返回NO,有可能是使用了绝对路径,如NSHomeDirectory(),此时应使用NSSearchPathForDirectoriesInDomains()来获取相对路径,而此方法只能获取Documents和Cache文件夹,不能获取Tmp文件夹。
UIImage加载本地图片
[UIImage imageWithContentsOfFile:imgPath];
使用NSData对象将文件写入本地指定路径
if ([fileData writeToFile:filePath atomically:YES]) {
//写入成功
} else {
//写入失败
}
加载本地的gif图片
#import "UIImage+GIF.h"
NSData *data = [NSData dataWithContentsOfFile:imgPath];
UIImage *gifImage = [UIImage sd_imageWithGIFData:data];
AES加密解密
.h
/// AES加密
/// @param key 加密的密钥
- (NSData *)aes256_encrypt:(NSString *)key;
/// AES解密
/// @param key 解密的密钥
- (NSData *)aes256_decrypt:(NSString *)key;
.m
// AES加密
- (NSData *)aes256_encrypt:(NSString *)key {
char keyPtr[kCCKeySizeAES256 + 1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode, keyPtr, kCCBlockSizeAES128, NULL, [self bytes], dataLength, buffer, bufferSize, &numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
// AES解密
- (NSData *)aes256_decrypt:(NSString *)key {
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
从服务器上获取AES加密过的文件,并将其解密后保存到本地(异步)
在AES的解密过程中,如果需要解密多个文件的话,需要使用异步的方式,以免阻塞主线程。此方法模仿SD_WebImage的实现,在方法的回调中返回了保存过后的文件地址,供如加载图片等各个方法的使用:
/// 从服务器下载加密后的文件,并解密后保存到本地生成地址(异步)
/// @param serverUrl 文件在服务器的url
/// @param key 解密的key
/// @param completedBlock 完成回调
+ (void)downloadFileFromUrl:(NSString *)serverUrl aes256decrypt:(NSString *)key completed:(void (^)(BOOL successed, NSString *filenamePath))completedBlock {
//1.提取文件名
NSString *nameStr = [serverUrl componentsSeparatedByString:@"/"].lastObject;
//2.获取沙盒Document地址
NSString *documentsDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
//3.在沙盒地址下新建文件夹,并生成文件地址(带文件名)
NSString *folderPath = [documentsDir stringByAppendingPathComponent:@"AESCryptFiles"];
BOOL isDir = NO;
BOOL existed = [[NSFileManager defaultManager] fileExistsAtPath:folderPath isDirectory:&isDir];
if ( !(isDir == YES && existed == YES) ) {
[[NSFileManager defaultManager] createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:nil];
}
NSString *filePath = [NSString stringWithFormat:@"%@/%@",folderPath, nameStr];
//4.判断文件是否已存在,如果已存在那么直接返回地址,如果不存在,那么下载后解压保存
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
//文件已存在,直接返回
completedBlock(YES, filePath);
return;
}
//文件不存在,解密后返回(异步)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:serverUrl]];
NSData *fileData = [data aes256_decrypt:key];
if ([fileData writeToFile:filePath atomically:YES]) {
completedBlock(YES, filePath);
} else {
completedBlock(NO, @"");
}
});
}
利用MJExtension讲json字典转化为模型时,对id这类关键字的处理
+ (NSDictionary *)mj_replacedKeyFromPropertyName {
return @{@"tagId": @"id"};
}
AppDelegate中设置指定控制器为根控制器
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
GQTimerViewController *vc = [[GQTimerViewController alloc] initWithNibName:@"GQTimerViewController" bundle:nil];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
判断文件夹下是否存在指定文件
NSString *fileName = @"04.jpg";
NSArray *DocumentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filepath = [[NSString alloc] initWithString:[NSString stringWithFormat:@"%@/%@",DocumentPath[0],fileName]];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:filepath]) {
NSLog(@"file is exists");
} else{
NSLog(@"file is not exists");
};
加载本地Gif图片
NSString *path = [[NSBundle mainBundle] pathForResource:@"ai_animation" ofType:@"gif"];
NSData *data = [NSData dataWithContentsOfFile:path];
UIImage *image = [UIImage sd_imageWithGIFData:data];
boundingRectWithSize计算文字高度不准问题
//使用ceilf函数
CGSize size = [extraModel.txtContent boundingRectWithSize:CGSizeMake(kScreenWidth-140, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17]} context:nil].size;
extraModel.txtLabelH = ceilf(size.height);
将指定View的显示内容截取成图片
/// 截取指定View的图片
/// @param currentView 需要被截取的View
- (UIImage *)captureScreenForView:(UIView *)currentView {
UIGraphicsBeginImageContextWithOptions(currentView.frame.size, NO, [UIScreen mainScreen].scale);
[currentView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshotImage;
}
UIButton实现左边文字,右边图片
[btn setTitleEdgeInsets:UIEdgeInsetsMake(0, -btn.imageView.image.size.width, 0, btn.imageView.image.size.width)];
[btn setImageEdgeInsets:UIEdgeInsetsMake(0, btn.titleLabel.bounds.size.width, 0, -btn.titleLabel.bounds.size.width)];
网友评论