美文网首页iOS基本功
iOS编程常用技巧

iOS编程常用技巧

作者: 单线程Jack | 来源:发表于2019-07-18 17:37 被阅读0次
SDWebImage 加载大量高清图片时内存暴增
static BOOL SDImageCacheOldShouldDecompressImages = YES; 
 
static BOOL SDImagedownloderOldShouldDecompressImages = YES; 
 
- (void)viewDidLoad { 
 
  [super viewDidLoad]; 
  // 关闭SD加载高清大图时的解压缩 
  
  SDImageCache *canche = [SDImageCache sharedImageCache]; 
  
  SDImageCacheOldShouldDecompressImages = canche.shouldDecompressImages; 
  
  canche.shouldDecompressImages = NO; 
  
  SDWebImageDownloader *downloder = [SDWebImageDownloader sharedDownloader]; 
  
  SDImagedownloderOldShouldDecompressImages = downloder.shouldDecompressImages; 
 
  downloder.shouldDecompressImages = NO; 
 
 } 
 
 -(void)dealloc { 
 
 SDImageCache *canche = [SDImageCache sharedImageCache]; 
 
 canche.shouldDecompressImages = SDImageCacheOldShouldDecompressImages; 
 
 SDWebImageDownloader *downloder = [SDWebImageDownloader sharedDownloader]; 
 
 downloder.shouldDecompressImages = SDImagedownloderOldShouldDecompressImages; 
 
 }

SDWebImage本地缓存有时候会害人。如果之前缓存过一张图片,即使下次服务器换了这张图片,但是图片url没换,用SDWebimage下载下来的还是以前那张,所以遇到这种问题,不要先去怼服务器,清空下缓存再试就好了。

禁止手机睡眠
[UIApplication sharedApplication].idleTimerDisabled = YES;
隐藏某行cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 如果是你需要隐藏的那一行,返回高度为0
 
    if(indexPath.row == YouWantToHideRow){
       return 0;
    }
       return 44;
}
 
// 然后再你需要隐藏cell的时候调用
[self.tableView beginUpdates];
[self.tableView endUpdates];
禁用button高亮
button.adjustsImageWhenHighlighted = NO;
或者在创建的时候
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
动画切换window的根控制器
[UIView transitionWithView:[UIApplication sharedApplication].keyWindow duration:.5f 
options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
        BOOL oldState = [UIView areAnimationsEnabled];
        [UIView setAnimationsEnabled:NO];
        [UIApplication sharedApplication].keyWindow.rootViewController = [[RootViewController alloc]init];
        [UIView setAnimationsEnabled:oldState];
    } completion:^(BOOL finished) {
 
    }];

去除数组中重复的对象
NSArray *newArr = [oldArr valueForKeyPath:@"@distinctUnionOfObjects.self"];
iOS8系统中,tableView最好实现下-tableView: heightForRowAtIndexPath:这个代理方法,要不然在iOS8中可能就会出现显示不全或者无法响应事件的问题

iOS8中实现侧滑功能的时候这个方法必须实现,要不然在iOS8中无法侧滑

// 必须写的方法,和editActionsForRowAtIndexPath配对使用,里面什么不写也行
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
 
}
三个比较特殊的通知
NSSystemTimeZoneDidChangeNotification监听修改时间界面的两个按钮状态变化
 
UIApplicationSignificantTimeChangeNotification 监听用户改变时间 (只要点击自动设置按钮就会调用)
 
NSSystemClockDidChangeNotification 监听用户修改时间(时间不同才会调用)
获取不到UICollectionView指定cell的问题
[self.collectionView layoutIfNeeded];//添加这句话就好 
 
QTMResContinueEditeCell *cell = (QTMResContinueEditeCell *)[self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:_index inSection:0]];
跳进app权限设置
// 跳进app设置
if (UIApplicationOpenSettingsURLString != NULL) {
    UIApplication *application = [UIApplication sharedApplication];
    NSURL *URL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
    if ([application respondsToSelector:@selector(openURL:options:completionHandler:)]) {
        [application openURL:URL options:@{}
           completionHandler:nil];
    } else {
        [application openURL:URL];
    }
}

给一个view截图
- (UIImage *)cutImageWithView:(UIView *)view
{
    UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return image;
}
注意对象为nil的时候,调用此对象分类的方法不会执行
collectionView的内容小于其宽高的时候是不能滚动的,设置可以滚动:
collectionView.alwaysBounceHorizontal = YES;
 
collectionView.alwaysBounceVertical = YES;

颜色转图片
+ (UIImage *)imageWithColor:(UIColor *)color {
 
    //描述一个矩形
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    //开启图形上下文
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
 
    //获得图形上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
 
    //使用color演示填充上下文
    CGContextSetFillColorWithColor(ctx, [color CGColor]);
 
    //渲染上下文
    CGContextFillRect(ctx, rect);
 
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
 
    //关闭图形上下文
    UIGraphicsEndImageContext();
    
    return image;
    
}
view设置圆角
#define ViewBorderRadius(View, Radius, Width, Color)\
\
[View.layer setCornerRadius:(Radius)];\
[View.layer setMasksToBounds:YES];\
[View.layer setBorderWidth:(Width)];\
[View.layer setBorderColor:[Color CGColor]] // view圆角

view某个角度设置圆角
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.whiteView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(10, 10)];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = self.whiteView.bounds;
    maskLayer.path = maskPath.CGPath;
    self.whiteView.layer.mask = maskLayer;
    
  ##指定了需要成为圆角的角该参数是UIRectCorner类型的,可选的值有:
* UIRectCornerTopLeft
* UIRectCornerTopRight
* UIRectCornerBottomLeft
* UIRectCornerBottomRight
* UIRectCornerAllCorners
由角度转换弧度
#define DegreesToRadian(x) (M_PI * (x) / 180.0)
由弧度转换角度
#define RadianToDegrees(radian) (radian*180.0)/(M_PI)
获取图片资源
//建议使用前两种宏定义,性能高于后者
 
#define LOADIMAGE(file,ext) [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:file ofType:ext]]
 
#define IMAGE(A) [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:A ofType:nil]]
 
#define ImageNamed(_pointer) [UIImage imageNamed:[UIUtil imageName:_pointer]]
 
#define UIImageName(name) [UIImage imageNamed:name]
文件路径
//获取temp
#define PathTemp NSTemporaryDirectory()
 
//获取Document
#define PathDocument [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]
 
//获取 Cache
#define PathCache [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]
 
GCD代码只执行一次
#define kDISPATCH_ONCE_BLOCK(onceBlock) static dispatch_once_t onceToken; 
dispatch_once(&onceToken, onceBlock);
自定义NSLog
//DEBUG  模式下打印日志,当前行
#ifdef DEBUG
#   define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#   define DLog(...)
#endif
 
 
//重写NSLog,Debug模式下打印日志和当前行数
#if DEBUG
#define NSLog(FORMAT, ...) fprintf(stderr,"\nfunction:%s line:%d content:%s\n", __FUNCTION__, __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#else
#define NSLog(FORMAT, ...) nil
#endif
 
//DEBUG  模式下打印日志,当前行 并弹出一个警告
#ifdef DEBUG
#   define ULog(fmt, ...)  { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"%s\n [Line %d] ", __PRETTY_FUNCTION__, __LINE__] message:[NSString stringWithFormat:fmt, ##__VA_ARGS__]  delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; }
#else
#   define ULog(...)
#endif
Font
#define FONTS(size) [UIFont systemFontOfSize:(size)]
#define BOLDFONTS(size) [UIFont boldSystemFontOfSize:(size)]

GCD
//主线程
#define kDISPATCH_MAIN_THREAD(mainQueueBlock) dispatch_async(dispatch_get_main_queue(), mainQueueBlock);
 
//异步线程
#define kDISPATCH_GLOBAL_QUEUE_DEFAULT(globalQueueBlock) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), globalQueueBlocl);
 
通知
#define NOTIF_ADD(n, f)     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(f) name:n object:nil]
#define NOTIF_POST(n, o)    [[NSNotificationCenter defaultCenter] postNotificationName:n object:o]
#define NOTIF_REMV()        [[NSNotificationCenter defaultCenter] removeObserver:self]
Color
// RGB颜色转换(16进制->10进制)
#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
 
// 获取RGB颜色
#define RGBA(r,g,b,a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a]
 
//清除背景色
#define CLEARCOLOR [UIColor clearColor]
 
// 随机色
#define RandomCOLOR RGBCOLOR(arc4random_uniform(256),arc4random_uniform(256),arc4random_uniform(256))
 
获取window
+(UIWindow*)getWindow {
    UIWindow* win = nil; //[UIApplication sharedApplication].keyWindow;
    for (id item in [UIApplication sharedApplication].windows) {
        if ([item class] == [UIWindow class]) {
            if (!((UIWindow*)item).hidden) {
                win = item;
                break;
            }
        }
    }
    return win;
}
修改textField的placeholder的字体颜色、大小
[textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
[textField setValue:[UIFont boldSystemFontOfSize:16] forKeyPath:@"_placeholderLabel.font"];
// 或者
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:placeholder attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:13],NSForegroundColorAttributeName : [UIColor grayColor]}];

APP缓存
/** *  存 数组数据*/
+(void)setObectOfArray:(NSArray *)array fileName:(NSString *)fileName
{
    
    //缓存文件的 根路径
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
    // 缓存 文件夹 路径
    NSString *filePath = [path stringByAppendingPathComponent:@"XXX.dataCache"];
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    if ([fileManager fileExistsAtPath:filePath] == NO)
    {
        [fileManager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
    }
    //缓存文件的路径
    NSString * cacheFilePath = [filePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist",fileName]];
    BOOL isSuccess = [array writeToFile:cacheFilePath atomically:NO];
    if (isSuccess) {
        NSLog(@"缓存数据成功:---%@",cacheFilePath);
    }else
    {
        NSLog(@"缓存数据失败:---%@",cacheFilePath);
    }
    
}
 
/***  取 数组数据*/
+(NSArray *)cacheArrayForFileName:(NSString *)fileName
{
    
    //缓存文件的 根路径
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
    // 缓存 文件夹 路径
    NSString *filePath = [path stringByAppendingPathComponent:@"XXX.dataCache"];
    //缓存文件的路径
    NSString * cacheFilePath = [filePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist",fileName]];
    //取得缓存文件
    NSArray *array  = [NSArray arrayWithContentsOfFile:cacheFilePath];
    
    return array;
}
 
/*** 清除 这个全部的缓存数据 */
+(void)clearCacheListData:(void (^)())completion
{
    // 异线程
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 清楚缓存
        //缓存文件的 根路径
        NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
        // 缓存 文件夹 路径
        NSString *filePath = [path stringByAppendingPathComponent:@"FortuneDonkey.dataCache"];
        NSFileManager *manager = [NSFileManager defaultManager];
        //移除文件夹
        [manager removeItemAtPath:filePath error:nil];
        //  创建一个新的文件夹
        [manager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
        if (completion)
        {
            //回调主线程
            dispatch_async(dispatch_get_main_queue(), ^{
                completion();
            });
        }
    });
}
 
/*** 清除SD缓存数据 */
-(void)clearSDCacheData
{
    //先清除内存中的图片缓存
    [[SDImageCache sharedImageCache] clearMemory];
    //清除磁盘的缓存
    [[SDImageCache sharedImageCache] clearDisk];
}

获取APP缓存大小
- (CGFloat)getCachSize {
 
    NSUInteger imageCacheSize = [[SDImageCache sharedImageCache] getSize];
    //获取自定义缓存大小
    //用枚举器遍历 一个文件夹的内容
    //1.获取 文件夹枚举器
    NSString *myCachePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"];
    NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtPath:myCachePath];
    __block NSUInteger count = 0;
    //2.遍历
    for (NSString *fileName in enumerator) {
        NSString *path = [myCachePath stringByAppendingPathComponent:fileName];
        NSDictionary *fileDict = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
        count += fileDict.fileSize;//自定义所有缓存大小
    }
    // 得到是字节  转化为M
    CGFloat totalSize = ((CGFloat)imageCacheSize+count)/1024/1024;
    return totalSize;
}

几个常用权限判断
 if ([CLLocationManager authorizationStatus] ==kCLAuthorizationStatusDenied) {
        NSLog(@"没有定位权限");
    }
    AVAuthorizationStatus statusVideo = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (statusVideo == AVAuthorizationStatusDenied) {
        NSLog(@"没有摄像头权限");
    }
    //是否有麦克风权限
    AVAuthorizationStatus statusAudio = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
    if (statusAudio == AVAuthorizationStatusDenied) {
        NSLog(@"没有录音权限");
    }
    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
        if (status == PHAuthorizationStatusDenied) {
            NSLog(@"没有相册权限");
        }
    }];

系统相关的一些方法

//获取系统版本
#define IOS_VERSION [[[UIDevice currentDevice] systemVersion] floatValue]
#define IS_IOS10_OR_LATER    ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0)
 
//获取当前语言
#define CurrentLanguage ([[NSLocale preferredLanguages] objectAtIndex:0])
 
//判断是否 Retina屏、设备是否%fhone 5、是否是iPad
#define isRetina ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 960), [[UIScreen mainScreen] currentMode].size) : NO)
#define iPhone5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO)
#define iPhone6 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(750, 1334), [[UIScreen mainScreen] currentMode].size) : NO)
#define isPad (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
 
//判断是真机还是模拟器
#if TARGET_OS_IPHONE
//iPhone Device
#endif
 
#if TARGET_IPHONE_SIMULATOR
//iPhone Simulator
#endif

长按复制功能

- (void)viewDidLoad
{
    [self.view addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(pasteBoard:)]];
}
- (void)pasteBoard:(UILongPressGestureRecognizer *)longPress {
    if (longPress.state == UIGestureRecognizerStateBegan) {
        UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
        pasteboard.string = @"我是文字";
    }
}

判断图片类型
//通过图片 Data 数据第一个字节 来获取图片扩展名
- (NSString *)contentTypeForImageData:(NSData *)data
{
    uint8_t c;
    [data getBytes:&c length:1];
    switch (c)
    {
        case 0xFF:
            return @"jpeg";
 
        case 0x89:
            return @"png";
 
        case 0x47:
            return @"gif";
 
        case 0x49:
        case 0x4D:
            return @"tiff";
 
        case 0x52:
        if ([data length] < 12) {
            return nil;
        }
 
        NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
        if ([testString hasPrefix:@"RIFF"]
            && [testString hasSuffix:@"WEBP"])
        {
            return @"webp";
        }
 
        return nil;
    }
 
    return nil;
}
获取手机和 APP 信息
//手机序列号
NSString* identifierNumber = [[UIDevice currentDevice] uniqueIdentifier];
 
//手机别名: 用户定义的名称
NSString* userPhoneName = [[UIDevice currentDevice] name];
 
//设备名称
NSString* deviceName = [[UIDevice currentDevice] systemName];
 
//手机系统版本
NSString* phoneVersion = [[UIDevice currentDevice] systemVersion];
 
//手机型号
NSString* phoneModel = [[UIDevice currentDevice] model];
 
//地方型号  (国际化区域名称)
NSString* localPhoneModel = [[UIDevice currentDevice] localizedModel];
 
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
// 当前应用名称
NSString *appCurName = [infoDictionary objectForKey:@"CFBundleDisplayName"];
 
// 当前应用版本  
NSString *appCurVersion = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
 
// 当前应用版本号码   int类型
NSString *appCurVersionNum = [infoDictionary objectForKey:@"CFBundleVersion"];

UIImage绘制圆角

- (UIImage *)circleImage
{
    // NO代表透明
    UIGraphicsBeginImageContextWithOptions(self.size, NO, 1);
    // 获得上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    // 添加一个圆
    CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
    // 方形变圆形
    CGContextAddEllipseInRect(ctx, rect);
    // 裁剪
    CGContextClip(ctx);
    // 将图片画上去
    [self drawInRect:rect];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

准确获取图片像素

CGFloat fixelW = CGImageGetWidth(image.CGImage);
CGFloat fixelH = CGImageGetHeight(image.CGImage);
JSON字符串转字典
+ (NSDictionary *)parseJSONStringToNSDictionary:(NSString *)JSONString {
    NSData *JSONData = [JSONString dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:JSONData options:NSJSONReadingMutableLeaves error:nil];
    return responseJSON;
}

获取当前控制器
//获取当前屏幕显示的viewcontroller
- (UIViewController *)getCurrentVC{
    UIWindow *window = [[UIApplication sharedApplication].windows firstObject];
    if (!window) {
        return nil;
    }
    UIView *tempView;
    for (UIView *subview in window.subviews) {
        if ([[subview.classForCoder description] isEqualToString:@"UILayoutContainerView"]) {
            tempView = subview;
            break;
        }
    }
    if (!tempView) {
        tempView = [window.subviews lastObject];
    }
    
    id nextResponder = [tempView nextResponder];
    while (![nextResponder isKindOfClass:[UIViewController class]] || [nextResponder isKindOfClass:[UINavigationController class]] || [nextResponder isKindOfClass:[UITabBarController class]]) {
        tempView =  [tempView.subviews firstObject];
        
        if (!tempView) {
            return nil;
        }
        nextResponder = [tempView nextResponder];
    }
    return  (UIViewController *)nextResponder;
}

KVO监听某个对象的属性
// 添加监听者
[self addObserver:self forKeyPath:property options:NSKeyValueObservingOptionNew context:nil];
 
// 当监听的属性值变化的时候会来到这个方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:@"property"]) {
       [self textViewTextChange];
       } else {
     }
}

Reachability判断网络状态
NetworkStatus status = [[Reachability reachabilityForInternetConnection] currentReachabilityStatus];
    if (status == NotReachable) {
        NSLog(@"当前设备无网络");
    }
    if (status == ReachableViaWiFi) {
        NSLog(@"当前wifi网络");
    }
    if (status == ReachableViaWWAN) {
        NSLog(@"当前蜂窝移动网络");
    }

AFNetworking监听网络状态
// 监听网络状况
    AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];
    [mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        switch (status) {
            case AFNetworkReachabilityStatusUnknown:
                break;
            case AFNetworkReachabilityStatusNotReachable: {
                NSLog(@"当前设备无网络");
            }
                break;
            case AFNetworkReachabilityStatusReachableViaWiFi:
                 NSLog(@"当前wifi网络");
                break;
            case AFNetworkReachabilityStatusReachableViaWWAN:
                NSLog(@"当前蜂窝移动网络");
                break;
            default:
                break;
        }
    }];
   [mgr startMonitoring];
父视图透明不影响子视图的做法
self.view.backgroundColor = [[UIColor whiteColor]colorWithAlphaComponent:0.7f];
取图片某一点的颜色
if (point.x < 0 || point.y < 0) return nil;
 
   CGImageRef imageRef = self.CGImage;
   NSUInteger width = CGImageGetWidth(imageRef);
   NSUInteger height = CGImageGetHeight(imageRef);
   if (point.x >= width || point.y >= height) return nil;
 
   unsigned char *rawData = malloc(height * width * 4);
   if (!rawData) return nil;
 
   CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
   NSUInteger bytesPerPixel = 4;
   NSUInteger bytesPerRow = bytesPerPixel * width;
   NSUInteger bitsPerComponent = 8;
   CGContextRef context = CGBitmapContextCreate(rawData,
                                                width,
                                                height,
                                                bitsPerComponent,
                                                bytesPerRow,
                                                colorSpace,
                                                kCGImageAlphaPremultipliedLast
                                                | kCGBitmapByteOrder32Big);
   if (!context) {
       free(rawData);
       return nil;
   }
   CGColorSpaceRelease(colorSpace);
   CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
   CGContextRelease(context);
 
   int byteIndex = (bytesPerRow * point.y) + point.x * bytesPerPixel;
   CGFloat red   = (rawData[byteIndex]     * 1.0) / 255.0;
   CGFloat green = (rawData[byteIndex + 1] * 1.0) / 255.0;
   CGFloat blue  = (rawData[byteIndex + 2] * 1.0) / 255.0;
   CGFloat alpha = (rawData[byteIndex + 3] * 1.0) / 255.0;
 
   UIColor *result = nil;
   result = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
   free(rawData);
   return result;

判断该图片是否有透明度通道
- (BOOL)hasAlphaChannel
{
    CGImageAlphaInfo alpha = CGImageGetAlphaInfo(self.CGImage);
    return (alpha == kCGImageAlphaFirst ||
            alpha == kCGImageAlphaLast ||
            alpha == kCGImageAlphaPremultipliedFirst ||
            alpha == kCGImageAlphaPremultipliedLast);
}

两张图片合成
+ (UIImage*)mergeImage:(UIImage*)firstImage withImage:(UIImage*)secondImage {
    CGImageRef firstImageRef = firstImage.CGImage;
    CGFloat firstWidth = CGImageGetWidth(firstImageRef);
    CGFloat firstHeight = CGImageGetHeight(firstImageRef);
    CGImageRef secondImageRef = secondImage.CGImage;
    CGFloat secondWidth = CGImageGetWidth(secondImageRef);
    CGFloat secondHeight = CGImageGetHeight(secondImageRef);
    CGSize mergedSize = CGSizeMake(MAX(firstWidth, secondWidth), MAX(firstHeight, secondHeight));
    UIGraphicsBeginImageContext(mergedSize);
    [firstImage drawInRect:CGRectMake(0, 0, firstWidth, firstHeight)];
    [secondImage drawInRect:CGRectMake(0, 0, secondWidth, secondHeight)];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}
制作水印

// 画水印
- (void) setImage:(UIImage *)image withWaterMark:(UIImage *)mark inRect:(CGRect)rect
{
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 4.0)
    {
        UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, 0.0);
    }
    //原图
    [image drawInRect:self.bounds];
    //水印图
    [mark drawInRect:rect];
    UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    self.image = newPic;
}

让label的文字内容显示在左上/右上/左下/右下/中心顶/中心底部
自定义UILabel
// 重写label的textRectForBounds方法
- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines {
    CGRect rect = [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];
    switch (self.textAlignmentType) {
        case WZBTextAlignmentTypeLeftTop: {
            rect.origin = bounds.origin;
        }
            break;
        case WZBTextAlignmentTypeRightTop: {
            rect.origin = CGPointMake(CGRectGetMaxX(bounds) - rect.size.width, bounds.origin.y);
        }
            break;
        case WZBTextAlignmentTypeLeftBottom: {
            rect.origin = CGPointMake(bounds.origin.x, CGRectGetMaxY(bounds) - rect.size.height);
        }
            break;
        case WZBTextAlignmentTypeRightBottom: {
            rect.origin = CGPointMake(CGRectGetMaxX(bounds) - rect.size.width, CGRectGetMaxY(bounds) - rect.size.height);
        }
            break;
        case WZBTextAlignmentTypeTopCenter: {
            rect.origin = CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(rect)) / 2, CGRectGetMaxY(bounds) - rect.origin.y);
        }
            break;
        case WZBTextAlignmentTypeBottomCenter: {
            rect.origin = CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(rect)) / 2, CGRectGetMaxY(bounds) - CGRectGetMaxY(bounds) - rect.size.height);
        }
            break;
        case WZBTextAlignmentTypeLeft: {
            rect.origin = CGPointMake(0, rect.origin.y);
        }
            break;
        case WZBTextAlignmentTypeRight: {
            rect.origin = CGPointMake(rect.origin.x, 0);
        }
            break;
        case WZBTextAlignmentTypeCenter: {
            rect.origin = CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(rect)) / 2, (CGRectGetHeight(bounds) - CGRectGetHeight(rect)) / 2);
        }
            break;
 
        default:
            break;
    }
    return rect;
}
 
- (void)drawTextInRect:(CGRect)rect {
    CGRect textRect = [self textRectForBounds:rect limitedToNumberOfLines:self.numberOfLines];
    [super drawTextInRect:textRect];
}

移除字符串中的空格和换行
+ (NSString *)removeSpaceAndNewline:(NSString *)str {
    NSString *temp = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
    temp = [temp stringByReplacingOccurrencesOfString:@"\r" withString:@""];
    temp = [temp stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    return temp;
}

判断字符串中是否有空格
+ (BOOL)isBlank:(NSString *)str {
    NSRange _range = [str rangeOfString:@" "];
    if (_range.location != NSNotFound) {
        //有空格
        return YES;
    } else {
        //没有空格
        return NO;
    }
}

获取一个视频的第一帧图片
NSURL *url = [NSURL URLWithString:filepath];
AVURLAsset *asset1 = [[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetImageGenerator *generate1 = [[AVAssetImageGenerator alloc] initWithAsset:asset1];
generate1.appliesPreferredTrackTransform = YES;
NSError *err = NULL;
CMTime time = CMTimeMake(1, 2);
CGImageRef oneRef = [generate1 copyCGImageAtTime:time actualTime:NULL error:&err];
UIImage *one = [[UIImage alloc] initWithCGImage:oneRef];
 return one;

获取视频的时长
+ (NSInteger)getVideoTimeByUrlString:(NSString *)urlString {
    NSURL *videoUrl = [NSURL URLWithString:urlString];
    AVURLAsset *avUrl = [AVURLAsset assetWithURL:videoUrl];
    CMTime time = [avUrl duration];
    int seconds = ceil(time.value/time.timescale);
    return seconds;
}

当tableView占不满一屏时,去除下边多余的单元格
self.tableView.tableHeaderView = [UIView new];
self.tableView.tableFooterView = [UIView new];

isKindOfClass和isMemberOfClass的区别
isKindOfClass可以判断某个对象是否属于某个类,或者这个类的子类。
isMemberOfClass更加精准,它只能判断这个对象类型是否为这个类(不能判断子类)

禁用系统滑动返回功能
- (void)viewDidAppear:(BOOL)animated
{
     [super viewDidAppear:animated];
     if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) 
     {self.navigationController.interactivePopGestureRecognizer.delegate = self;
    }
}
 
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) 
    {self.navigationController.interactivePopGestureRecognizer.delegate = nil;
    }
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
     return NO;
}

UILabel设置内边距
子类化UILabel,重写drawTextInRect方法
- (void)drawTextInRect:(CGRect)rect {
    // 边距,上左下右
    UIEdgeInsets insets = {0, 5, 0, 5};
    [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}
UILabel设置文字描边
子类化UILabel,重写drawTextInRect方法
- (void)drawTextInRect:(CGRect)rect
{
    CGContextRef c = UIGraphicsGetCurrentContext();
    // 设置描边宽度
    CGContextSetLineWidth(c, 1);
    CGContextSetLineJoin(c, kCGLineJoinRound);
    CGContextSetTextDrawingMode(c, kCGTextStroke);
    // 描边颜色
    self.textColor = [UIColor redColor];
    [super drawTextInRect:rect];
    // 文本颜色
    self.textColor = [UIColor yellowColor];
    CGContextSetTextDrawingMode(c, kCGTextFill);
    [super drawTextInRect:rect];
}

UIView背景颜色渐变
+ (CAGradientLayer *)setGradualChangingColor:(UIView *)view fromColor:(NSString *)fromHexColorStr toColor:(NSString *)toHexColorStr{
    //    CAGradientLayer类对其绘制渐变背景颜色、填充层的形状(包括圆角)
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = view.bounds;
    //  创建渐变色数组,需要转换为CGColor颜色
    gradientLayer.colors = @[(__bridge id)[UIColor colorWithHexString:fromHexColorStr].CGColor,(__bridge id)[UIColor colorWithHexString:toHexColorStr].CGColor];
    //  设置渐变颜色方向,左下点为(0,0), 右上点为(1,1)
    gradientLayer.startPoint = CGPointMake(0, 0.5);
    gradientLayer.endPoint = CGPointMake(1, 0.5);
    //  设置颜色变化点,取值范围 0.0~1.0
    gradientLayer.locations = @[@0,@1];
    
    return gradientLayer;
}

UIView某个角添加圆角

// 左上角和右下角添加圆角
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(20, 20)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = view.bounds;
maskLayer.path = maskPath.CGPath;
view.layer.mask = maskLayer;

UIImage和base64互转
// view分类方法
- (NSString *)encodeToBase64String:(UIImage *)image {
 return [UIImagePNGRepresentation(image) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
}
 
- (UIImage *)decodeBase64ToImage:(NSString *)strEncodeData {
  NSData *data = [[NSData alloc]initWithBase64EncodedString:strEncodeData options:NSDataBase64DecodingIgnoreUnknownCharacters];
  return [UIImage imageWithData:data];
}

UIWebView设置背景透明
[webView setBackgroundColor:[UIColor clearColor]];
[webView setOpaque:NO];

设置tableView分割线颜色以及顶到头
// 分割线颜色
[self.tableView setSeparatorColor:[UIColor myColor]];
 
// 顶到头
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    [cell setSeparatorInset:UIEdgeInsetsZero];
    [cell setLayoutMargins:UIEdgeInsetsZero];
    cell.preservesSuperviewLayoutMargins = NO;
}
 
- (void)viewDidLayoutSubviews {
    [self.tableView setSeparatorInset:UIEdgeInsetsZero];
    [self.tableView setLayoutMargins:UIEdgeInsetsZero];
}

为一个view添加虚线边框

CAShapeLayer *border = [CAShapeLayer layer];
 border.strokeColor = [UIColor colorWithRed:67/255.0f green:37/255.0f blue:83/255.0f alpha:1].CGColor;
 border.fillColor = nil;
 border.lineDashPattern = @[@4, @2];
 border.path = [UIBezierPath bezierPathWithRect:view.bounds].CGPath;
 border.frame = view.bounds;
 [view.layer addSublayer:border];

UITextView中打开或禁用复制,剪切,选择,全选等功能
// 继承UITextView重写这个方法
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
// 返回NO为禁用,YES为开启
    // 粘贴
    if (action == @selector(paste:)) return NO;
    // 剪切
    if (action == @selector(cut:)) return NO;
    // 复制
    if (action == @selector(copy:)) return NO;
    // 选择
    if (action == @selector(select:)) return NO;
    // 选中全部
    if (action == @selector(selectAll:)) return NO;
    // 删除
    if (action == @selector(delete:)) return NO;
    // 分享
    if (action == @selector(share)) return NO;
    return [super canPerformAction:action withSender:sender];
}

相关文章

  • iOS编程常用技巧

    SDWebImage 加载大量高清图片时内存暴增 SDWebImage本地缓存有时候会害人。如果之前缓存过一张图片...

  • iOS开发之Xcode常用调试技巧总结

    iOS开发之Xcode常用调试技巧总结 iOS开发之Xcode常用调试技巧总结

  • Swift 常用快捷键

    iOS开发之Xcode常用调试技巧总结 Xcode 常用快捷键 lldb技巧:

  • iOS 知识-常用小技巧大杂烩

    iOS 知识-常用小技巧大杂烩 - 简书

  • ReactiveObjC入门

    ReactiveObjC基础用法 iOS开发三种编程方式(响应式编程、函数编程、链式编程),函数编程最常用,链式编...

  • js编程常用技巧合集

    js编程常用技巧合集 最近看了一些JavaScript的编程技巧,个人觉得特别有用所以把我觉得好的分享给大家。 1...

  • 关于IOP的思考

    IOP即面向接口编程,这在java语言中老生常谈的东西,在iOS中其实并不常用,iOS其实就是面向协议编程,即@p...

  • 一些好的文章收录

    iOS保持流畅的技巧 iOS核心动画 离屏渲染 Dart中的异步编程——Future、async和await Fl...

  • UINavigationController的简单介绍

    UINavigationController是IOS编程中比较常用的一种容器view controller,也就是...

  • MY_汇总

    1. iOS开发--常用技巧 (MJRefresh详解) http://blog.csdn.net/mx_xuan...

网友评论

    本文标题:iOS编程常用技巧

    本文链接:https://www.haomeiwen.com/subject/uvtrlctx.html