iOS 开发Tips(一)

1.NSTimer

//暂停
if ([timer isValid]) {
[timer setFireDate:[NSDate distantFuture]];
}

//恢复
NSDate * date = [NSDate date];
[timer setFireDate:date];

//在离开界面或者计时器不在使用的时候一定要调用invalidate方法,不然会导致内存泄露
[timer invalidate];
2.UITabBarItem 图片设置

//如果这么设置的图片会被tabbarItem 所在的tabbar的tintColor所渲染。所以得到不原图
UITabBarItem *item = [[UITabBarItem alloc]init];
item.image = [UIImage imageNamed:@"norImg"];
item.selectedImage = [UIImage imageNamed:@"selImg"];

//解决方案
UITabBarItem *item = [[UITabBarItem alloc]init];
item.image = [[UIImage imageNamed:@"norImg"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
item.selectedImage = [[UIImage imageNamed:@"selImg"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
3.图像拉伸 - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight

//在开发过程中经常会遇到图片大小不确定,但是如果图片部分拉伸后能满足的情况。这时候可以使用系统自带图片拉伸函数。

  • (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight

leftCapWidth 可以理解为x
topCapHeight 理解为y
意思就是水平方向以x垂线为基准开始拉伸,拉伸的只是x垂线其他的不变,可以把x垂线想象成一个1像素的宽度高度和图片一样的线条,把一个线拉伸成一个很粗的线条。
垂直方向同理。
4.UIWebView Http头设置

//UIWebView Http头设置有两种方式
//1.实现UIWebViewDelegate的

  • (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    //在这里写一些代码,判断NSURLRequest的请求头是否合乎要求,不合则让webview加载修改够的NSURLRequest,并返回NO
    //例如:
    NSString *ua = request.allHTTPHeaderFields[@"User-Agent"];
    if (![ua isEqualToString:@"HHURLProtocolDome/1.0.0"]) {
    NSMutableURLRequest *mutableRequest = [request mutableCopy];
    [mutableRequest setValue:@"HHURLProtocolDome/1.0.0" forHTTPHeaderField:@"User-Agent"];
    [webView loadRequest:mutableRequest];
    return NO;
    }
    return YES;
    }

//2.继承NSURLProtocol并重写其方法
static NSString *kUserAgent = @"User-Agent";
static NSString *kPropertyKey = @"kPropertyKey";
@interface HHURLProtocol()<NSURLSessionDataDelegate,NSURLSessionTaskDelegate,NSURLSessionDelegate>
@property (nonatomic, strong) NSURLSession *session;
@property (nonatomic, strong) NSURLSessionTask *task;
@end

@implementation HHURLProtocol

  • (NSURLSession *)session{
    if (_session == nil) {
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    configuration.protocolClasses = @[[self class]];
    _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
    }
    return _session;
    }
  • (void)load{
    [NSURLProtocol registerClass:[HHURLProtocol class]];
    }

  • (BOOL)canInitWithRequest:(NSURLRequest *)request{
    return [self checkRequest:request];
    }

  • (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request{

    return [self settingHttpHeader:request];
    }

  • (void)startLoading
    {
    NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
    [NSURLProtocol setProperty:@YES forKey:kPropertyKey inRequest:mutableReqeust];
    _task = [self.session dataTaskWithRequest:mutableReqeust];
    [_task resume];
    }

  • (void)stopLoading
    {
    [_task cancel];
    }

pragma mark - NSURLSessionDataDelegate

  • (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
    didReceiveResponse:(NSURLResponse *)response
    completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler{

    [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
    completionHandler(NSURLSessionResponseAllow);

}

  • (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    [self.client URLProtocol:self didLoadData:data];
    }

pragma mark - NSURLSessionTaskDelegate

  • (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    if (!error) {
    [self.client URLProtocolDidFinishLoading:self];
    }
    else {
    [self.client URLProtocol:self didFailWithError:error];
    }
    }

pragma mark - check request

  • (BOOL)checkRequest:(NSURLRequest *)request{
    if ([NSURLProtocol propertyForKey:kPropertyKey inRequest:request]) {
    return NO;
    }
    return YES;//通过
    }

  • (NSURLRequest *)settingHttpHeader:(NSURLRequest *)request{
    NSMutableURLRequest *mutableReqeust = [request mutableCopy];
    [mutableReqeust setValue:@"HHURLProtocolDome/1.0.0" forHTTPHeaderField:kUserAgent];
    return mutableReqeust;
    }

@end
//方法2附上demo一份 https://github.com/MRCaoHH/HHURLProtocolDome
//老问题了,demo又打错......
5.虚线边框
.h

import <UIKit/UIKit.h>

typedef NS_ENUM(NSInteger,HHDottedLineDirection){
HHDottedLineDirection_Top = 1,
HHDottedLineDirection_Left = 1 << 1,
HHDottedLineDirection_Bottom = 1 << 2,
HHDottedLineDirection_Right = 1 << 3
};

@interface UIView (HHCategory)
@property (nonatomic,assign) CGPoint origin;
@property (nonatomic,assign) CGSize size;
@property (nonatomic,assign) CGFloat width;
@property (nonatomic,assign) CGFloat height;
@property (nonatomic,assign) CGFloat y;
@property (nonatomic,assign) CGFloat x;
@property (nonatomic, assign) CGFloat centerX;
@property (nonatomic, assign) CGFloat centerY;

@property (nonatomic,assign) CGFloat bottom;
@property (nonatomic,assign) CGFloat top;
@property (nonatomic,assign) CGFloat left;
@property (nonatomic,assign) CGFloat right;

/**

  • @brief 绘制虚线
  • @param direction 方向
  • @param color 颜色
  • @param lineDashPattern 虚线连续长度
  • @param lineWidth 线条粗细
    */
  • (void)drawDottedLine:(HHDottedLineDirection)direction lineColor:(UIColor *)color lineDashPattern:(NSArray <NSNumber >)lineDashPattern lineWidth:(CGFloat)lineWidth;

/**

  • @brief 绘制圆角虚线边框
  • @param lineColor 颜色
  • @param lineDashPattern 虚线连续长度
  • @param lineWidth 线条粗细
    */
  • (void)drawDottedLineCornerRadius:(UIColor *)lineColor lineDashPattern:(NSArray <NSNumber >)lineDashPattern lindWidth:(CGFloat)lineWidth ;

@end
.m

@implementation UIView (HHCategory)

pragma mark - origin 坐标点

-(CGPoint)origin
{
return self.frame.origin;
}

-(void)setOrigin:(CGPoint)origin
{
CGRect frame = self.frame;
frame.origin = origin;
self.frame = frame;
}

pragma mark - size 大小

-(CGSize)size
{
return self.frame.size;
}

-(void)setSize:(CGSize)size
{
CGRect frame = self.frame;
frame.size = size;
self.frame = frame;
}

pragma mark - width 宽度

-(CGFloat)width
{
return self.size.width;
}

-(void)setWidth:(CGFloat)width
{
CGSize size = self.size;
size.width = width;
self.size = size;
}

pragma mark - height 高度

-(CGFloat)height
{
return self.size.height;
}

-(void)setHeight:(CGFloat)height
{
CGSize size = self.size;
size.height = height;
self.size = size;
}

pragma mark - x 横坐标

-(CGFloat)x
{
return self.origin.x;
}

-(void)setX:(CGFloat)x
{
CGPoint origin = self.origin;
origin.x = x;
self.origin = origin;
}

pragma mark - y 纵坐标

-(CGFloat)y
{
return self.origin.y;
}

-(void)setY:(CGFloat)y
{
CGPoint origin = self.origin;
origin.y = y;
self.origin = origin;
}

  • (void)setCenterX:(CGFloat)centerX
    {
    CGPoint center = self.center;
    center.x = centerX;
    self.center = center;
    }

  • (CGFloat)centerX
    {
    return self.center.x;
    }

  • (CGFloat)left {
    return self.frame.origin.x;
    }

  • (void)setLeft:(CGFloat)x {
    CGRect frame = self.frame;
    frame.origin.x = x;
    self.frame = frame;
    }

  • (void)setCenterY:(CGFloat)centerY
    {
    CGPoint center = self.center;
    center.y = centerY;
    self.center = center;
    }

  • (CGFloat)centerY
    {
    return self.center.y;
    }

  • (void)setTop:(CGFloat)y {
    CGRect frame = self.frame;
    frame.origin.y = y;
    self.frame = frame;
    }

  • (CGFloat)top {
    return self.frame.origin.y;
    }

  • (void)setBottom:(CGFloat)bottom {
    CGRect frame = self.frame;
    frame.origin.y = bottom - frame.size.height;
    self.frame = frame;
    }

  • (CGFloat)bottom {
    return self.frame.origin.y + self.frame.size.height;
    }

  • (CGFloat)right {
    return self.frame.origin.x + self.frame.size.width;
    }

  • (void)setRight:(CGFloat)right {
    CGRect frame = self.frame;
    frame.origin.x = right - frame.size.width;
    self.frame = frame;
    }

  • (void)drawDottedLine:(HHDottedLineDirection)direction lineColor:(UIColor *)color lineDashPattern:(NSArray <NSNumber >)lineDashPattern lineWidth:(CGFloat)lineWidth{
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.frame = CGRectMake(0, 0, self.width, self.height);
    [shapeLayer setFillColor:[[UIColor clearColor] CGColor]];
    //设置虚线颜色
    [shapeLayer setStrokeColor:[color CGColor]];
    //设置虚线的宽度
    [shapeLayer setLineWidth:lineWidth];
    [shapeLayer setLineJoin:kCALineJoinRound];
    //设置虚线线段
    [shapeLayer setLineDashPattern:[NSArray arrayWithArray:lineDashPattern]];

    // Setup the path
    CGMutablePathRef path = CGPathCreateMutable();
    if (direction & HHDottedLineDirection_Top) {
    CGPathMoveToPoint(path, NULL, 0, 0);
    CGPathAddLineToPoint(path, NULL, self.width, 0);
    }

    if (direction & HHDottedLineDirection_Right) {
    CGPathMoveToPoint(path, NULL, self.width - lineWidth, 0);
    CGPathAddLineToPoint(path, NULL, self.width - lineWidth, self.height);
    }

    if (direction & HHDottedLineDirection_Bottom) {
    CGPathMoveToPoint(path, NULL, 0, self.height - lineWidth);
    CGPathAddLineToPoint(path, NULL, self.width , self.height - lineWidth);
    }

    if (direction & HHDottedLineDirection_Left) {
    CGPathMoveToPoint(path, NULL, 0, 0);
    CGPathAddLineToPoint(path, NULL, 0, self.height);
    }

    [shapeLayer setPath:path];
    CGPathRelease(path);
    [self.layer addSublayer:shapeLayer];
    }

  • (void)drawDottedLineCornerRadius:(UIColor *)lineColor lineDashPattern:(NSArray <NSNumber >)lineDashPattern lindWidth:(CGFloat)lineWidth{
    //圆角
    CGFloat cornerRadius = self.layer.cornerRadius;
    CGFloat borderWidth = lineWidth;

    CGRect frame = self.bounds;
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 0, frame.size.height - cornerRadius);
    CGPathAddLineToPoint(path, NULL, 0, cornerRadius);
    CGPathAddArc(path, NULL, cornerRadius, cornerRadius, cornerRadius, M_PI, -M_PI_2, NO);
    CGPathAddLineToPoint(path, NULL, frame.size.width - cornerRadius, 0);
    CGPathAddArc(path, NULL, frame.size.width - cornerRadius, cornerRadius, cornerRadius, -M_PI_2, 0, NO);
    CGPathAddLineToPoint(path, NULL, frame.size.width, frame.size.height - cornerRadius);
    CGPathAddArc(path, NULL, frame.size.width - cornerRadius, frame.size.height - cornerRadius, cornerRadius, 0, M_PI_2, NO);
    CGPathAddLineToPoint(path, NULL, cornerRadius, frame.size.height);
    CGPathAddArc(path, NULL, cornerRadius, frame.size.height - cornerRadius, cornerRadius, M_PI_2, M_PI, NO);

    //path is set as the _shapeLayer object's path
    shapeLayer.path = path;
    CGPathRelease(path);

    shapeLayer.backgroundColor = [[UIColor clearColor] CGColor];
    shapeLayer.frame = frame;
    shapeLayer.masksToBounds = NO;
    [shapeLayer setValue:[NSNumber numberWithBool:NO] forKey:@"isCircle"];
    shapeLayer.fillColor = [[UIColor clearColor] CGColor];
    shapeLayer.strokeColor = [lineColor CGColor];
    shapeLayer.lineWidth = borderWidth;
    shapeLayer.lineDashPattern = lineDashPattern;
    shapeLayer.lineCap = kCALineCapRound;

    [self.layer addSublayer:shapeLayer];
    }
    @end
    6.今天周几,本月有多少天,今年是否是闰年
    内容源自rfc3339

//rfc3339
//根据日期得到周几
int dayOfWeek(int day, int month, int year)
{
int cent;
int dayofweek[] = {
7, 1, 2, 3,
4, 5, 6
};

/* adjust months so February is the last one */
month -= 2;
if (month < 1) {
    month += 12;
    --year;
}
/* split by century */
cent = year / 100;
year %= 100;
return (dayofweek[((26 * month - 2) / 10 + day + year
                   + year / 4 + cent / 4 + 5 * cent) % 7]);

}

//根据年月得到当月的总天数
int monthDayCount(int year, int month){
//01 January 31
//02 February, normal 28
//03 March 31
//04 April 30
//05 May 31
//06 June 30
//07 July 31
//08 August 31
//09 September 30
//10 October 31
//11 November 30
//12 December 31
//02 February, leap year 29
///验证月份,在1~12之间
if (month < 1 || month > 12) {
return 0;
}
int arr[] = {31,28,31,30,31,30,31,31,30,31,30,31,29};
int index = month - 1;
if ( leapYear(year) && month == 2) {
index = 12;
}

return arr[index];

}

//是否是闰年
int leapYear(int year){
return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
}
如果你更喜欢oc或者swift可以尝试将以上代码转成你喜欢的,接下来介绍下用日历实现方法:

//当月的天数
NSCalendar *calendar = [NSCalendar currentCalendar];
NSRange range = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:[NSDate date]];
NSLog(@"%@",NSStringFromRange(range));

//当前时间周几,注意周一
NSInteger week = [calendar component:NSCalendarUnitWeekday fromDate:[NSDate date]];
NSLog(@"%zd",week);

//闰年,方法多样,可以用- (NSInteger)component:(NSCalendarUnit)unit fromDate:(NSDate *)date方法得到当年的天数做判断也可以直接用年份计算,故此略
7.TableViewCell点击的时候改变cell上控件背景颜色问题

  • (void)setSelected:(BOOL)selected animated:(BOOL)animated{
    //在这里直接设置背景颜色
    }

  • (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated{
    //在这里直接设置背景颜色
    }
    8.摄像头检测

if(![UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear]){
//前边摄像头不可用
}

if (![UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront]) {
//后边摄像头不可用的代码
}

if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
//摄像头不可用
}
9.约束动画

[containerView layoutIfNeeded];
[UIView animateWithDuration:1.0 animations:^{
// Make all constraint changes here
[containerView layoutIfNeeded];
}];
10.textFiled 占位文本颜色

//1.直接设置属性字符串
UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(0, 20, 375, 44)];
textField.backgroundColor = [UIColor whiteColor];
NSAttributedString *attString = [[NSAttributedString alloc]initWithString:@"占位符" attributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];
textField.attributedPlaceholder = attString;
[self.view addSubview:textField];

//2.利用私有字段
[textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
11.textView 占位文本实现

UITextView+HHCategory.h

import <UIKit/UIKit.h>

@interface UITextView (HHCategory)
@property (nonatomic, strong) NSString *placeholder;
@property (nonatomic, strong) UIColor *placeholderColor;
@property (nonatomic, strong) NSAttributedString *attributedPlaceholder;
@end
UITextView+HHCategory.m

import "UITextView+HHCategory.h"

import <objc/runtime.h>

@implementation NSObject (HHCategory)

  • (void)HH_SwizzleClassMethod:(Class)class originSelector:(SEL)originSelector otherSelector:(SEL)otherSelector
    {
    Method otherMehtod = class_getClassMethod(class, otherSelector);
    Method originMehtod = class_getClassMethod(class, originSelector);
    // 交换2个方法的实现
    method_exchangeImplementations(otherMehtod, originMehtod);
    }

  • (void)HH_SwizzleInstanceMethod:(Class)class originSelector:(SEL)originSelector otherSelector:(SEL)otherSelector
    {
    Method otherMehtod = class_getInstanceMethod(class, otherSelector);
    Method originMehtod = class_getInstanceMethod(class, originSelector);
    // 交换2个方法的实现
    method_exchangeImplementations(otherMehtod, originMehtod);
    }

@end

@implementation UITextView (HHCategory)
@dynamic placeholder,attributedPlaceholder,placeholderColor;

  • (UIColor *)HH_DefaultPlaceholderColor {
    static UIColor *color = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    UITextField *textField = [[UITextField alloc] init];
    textField.placeholder = @" ";
    color = [textField valueForKeyPath:@"_placeholderLabel.textColor"];
    });
    return color;
    }

  • (void)load{
    [self HH_SwizzleInstanceMethod:self originSelector:NSSelectorFromString(@"dealloc") otherSelector:@selector(HH_Dealloc)];
    }

  • (void)HH_Dealloc{
    [self HH_RemoveNotification];
    [self HH_RemoveServer];
    [self HH_Dealloc];
    }

  • (UIColor *)placeholderColor{
    UIColor *placeholderColor = objc_getAssociatedObject(self, @selector(placeholderColor));
    if (placeholderColor == nil) {
    return [UITextView HH_DefaultPlaceholderColor];
    }
    return objc_getAssociatedObject(self, @selector(placeholderColor));
    }

  • (void)setPlaceholderColor:(UIColor *)placeholderColor{
    objc_setAssociatedObject(self, @selector(placeholderColor), placeholderColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self updatePlaceholder];
    }

  • (NSString *)placeholder{
    return objc_getAssociatedObject(self, @selector(placeholder));
    }

  • (void)setPlaceholder:(NSString *)placeholder{
    objc_setAssociatedObject(self, @selector(placeholder), placeholder, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self updatePlaceholder];
    }

  • (NSAttributedString *)attributedPlaceholder{
    return objc_getAssociatedObject(self, @selector(attributedPlaceholder));
    }

  • (void)setAttributedPlaceholder:(NSAttributedString *)attributedPlaceholder{
    objc_setAssociatedObject(self, @selector(attributedPlaceholder), attributedPlaceholder, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self updatePlaceholder];
    }

  • (UILabel *)placeholderLabel{
    return objc_getAssociatedObject(self, @selector(placeholderLabel));
    }

  • (void)setPlaceholderLabel:(UILabel *)placeholderLabel{
    objc_setAssociatedObject(self, @selector(placeholderLabel), placeholderLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }

  • (void)updatePlaceholder{
    if( [self.placeholder length] > 0 && self.text.length == 0)
    {
    if (self.placeholderLabel == nil )
    {
    self.placeholderLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.textContainerInset.left,self.textContainerInset.top,self.bounds.size.width ,0)];
    self.placeholderLabel.numberOfLines = 0;
    self.placeholderLabel.backgroundColor = [UIColor clearColor];
    self.placeholderLabel.alpha = 0;
    self.placeholderLabel.font = self.font;
    self.placeholderLabel.textColor = self.placeholderColor;
    [self addSubview:self.placeholderLabel];
    self.text = @" ";
    self.text = @"";
    [self HH_AddNotification];
    [self HH_AddObServer];
    }

      self.placeholderLabel.frame = CGRectMake(self.textContainer.lineFragmentPadding,self.textContainerInset.top,self.bounds.size.width ,0);
      self.placeholderLabel.textAlignment = self.textAlignment;
      self.placeholderLabel.font = self.font;
      self.placeholderLabel.textColor = self.placeholderColor;
    
      if (self.attributedPlaceholder == nil) {
          self.placeholderLabel.text = self.placeholder;
      }else{
          self.placeholderLabel.attributedText = self.attributedPlaceholder;
      }
    
      [self.placeholderLabel sizeToFit];
      [self sendSubviewToBack:self.placeholderLabel];
    

    }
    self.placeholderLabel.alpha = ([[self text] length] == 0);
    }

  • (void)HH_AddNotification{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatePlaceholder) name:UITextViewTextDidChangeNotification object:nil];
    }

  • (void)HH_RemoveNotification{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:nil];
    }

  • (void)HH_AddObServer{
    NSArray *keys = [self HH_ObServerKey];
    for (NSString *obKey in keys) {
    [self addObserver:self forKeyPath:obKey options:NSKeyValueObservingOptionNew context:nil];
    }

}

  • (void)HH_RemoveServer{
    NSArray *keys = [self HH_ObServerKey];
    for (NSString *obKey in keys) {
    [self removeObserver:self forKeyPath:obKey];
    }

}

  • (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    NSArray *keys = [self HH_ObServerKey];
    if ([keys containsObject:keyPath]) {
    [self updatePlaceholder];
    }
    }

  • (NSArray *)HH_ObServerKey {
    return @[@"attributedText",
    @"bounds",
    @"font",
    @"frame",
    @"text",
    @"textAlignment",
    @"textContainerInset"];
    }
    @end
    12.分割线

UITableView的类型有两种UITableViewStylePlain和UITableViewStyleGrouped
Plain类型是没有包边线的

UITableViewStylePlain

Grouped是存在包边线的。

UITableViewStyleGrouped

根据自己的需求选择合适的类型

//设置tableView的style,只有初始化的时候能设置
UITableView *tableView = [[UITableView alloc]initWithFrame:self.view.frame style:UITableViewStyleGrouped];

//分割线的位置调整
tableView.separatorInset = UIEdgeInsetsMake(0, 10, 0, 10);

//分割线颜色
tableView.separatorColor = [UIColor redColor];

//cell也能调整分割线位置
static NSString *identifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: identifier];
if(!cell){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier: identifier];
}
cell.separatorInset = UIEdgeInsetsMake(0, 10, 0, 10);
13.系统版本判断宏
获取当前设备系统版本代码如下:

//获取的到值是字符串,例如iOS10获取到的版本号是10.0
[UIDevice currentDevice].systemVersion
判断系统版本大于小于的宏可以这么写:

//系统版本大于小于的宏

define k_Check_iOS(x) [UIDevice currentDevice].systemVersion.floatValue > x

如果要更精确的判断系统的版本就更麻烦一些了,在iOS里面已经定义了一些系统版本号的宏,如下:

define __IPHONE_2_0 20000

define __IPHONE_2_1 20100

define __IPHONE_2_2 20200

define __IPHONE_3_0 30000

define __IPHONE_3_1 30100

define __IPHONE_3_2 30200

define __IPHONE_4_0 40000

define __IPHONE_4_1 40100

define __IPHONE_4_2 40200

define __IPHONE_4_3 40300

define __IPHONE_5_0 50000

define __IPHONE_5_1 50100

define __IPHONE_6_0 60000

define __IPHONE_6_1 60100

define __IPHONE_7_0 70000

define __IPHONE_7_1 70100

define __IPHONE_8_0 80000

define __IPHONE_8_1 80100

define __IPHONE_8_2 80200

define __IPHONE_8_3 80300

define __IPHONE_8_4 80400

define __IPHONE_9_0 90000

define __IPHONE_9_1 90100

define __IPHONE_9_2 90200

define __IPHONE_9_3 90300

define __IPHONE_10_0 100000

判断宏如下

define kOSVersion ({\

NSArray version = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];
NSInteger versionNum = 0;
if ([version count] > 0) {
versionNum += [version[0] integerValue] * 10000;
}
if ([version count] > 1) {
versionNum += [version[1] integerValue]
100;
}
if ([version count] > 2) {
versionNum += [version[2] integerValue];
}
versionNum;
})

define k_Is_iOS7_1 __IPHONE_7_1 == kOSVersion

define k_Is_iOS8_0 __IPHONE_8_0 == kOSVersion

define k_Is_iOS8_1 __IPHONE_8_1 == kOSVersion

define k_Is_iOS8_2 __IPHONE_8_2 == kOSVersion

define k_Is_iOS8_3 __IPHONE_8_3 == kOSVersion

define k_Is_iOS8_4 __IPHONE_8_4 == kOSVersion

define k_Is_iOS9_0 __IPHONE_9_0 == kOSVersion

define k_Is_iOS9_1 __IPHONE_9_1 == kOSVersion

define k_Is_iOS9_2 __IPHONE_9_2 == kOSVersion

define k_Is_iOS9_3 __IPHONE_9_3 == kOSVersion

define k_Is_iOS10_0 __IPHONE_10_0 == kOSVersion

14.时间格式 YYYY/MM/DD HH:mm:ss

/ 日期分隔符
: 时间分隔符
d 显示日,小于10的时候前面不带0
dd 显示日,小于10的时候前面带0
EEE 将日显示为缩写形式(例如 Sun)。
EEEE 将日显示为全名(例如 Sunday)。
M 将月份显示为不带前导零的数字(如一月表示为 1)。如果这是用户定义的数字格式中的唯一字符,请使用 %M。
MM 将月份显示为带前导零的数字(例如 01/12/01)。
MMM 将月份显示为缩写形式(例如 Jan)。
MMMM 将月份显示为完整月份名(例如 January)。
gg 显示时代/纪元字符串(例如 A.D.)
h 使用 12 小时制将小时显示为不带前导零的数字(例如 1:15:15 PM)。如果这是用户定义的数字格式中的唯一字符,请使用 %h。
hh 使用 12 小时制将小时显示为带前导零的数字(例如 01:15:15 PM)。
H 使用 24 小时制将小时显示为不带前导零的数字(例如 1:15:15)。如果这是用户定义的数字格式中的唯一字符,请使用 %H。
HH 使用 24 小时制将小时显示为带前导零的数字(例如 01:15:15)。
m 将分钟显示为不带前导零的数字(例如 12:1:15)。如果这是用户定义的数字格式中的唯一字符,请使用 %m。
mm 将分钟显示为带前导零的数字(例如 12:01:15)。
s 将秒显示为不带前导零的数字(例如 12:15:5)。如果这是用户定义的数字格式中的唯一字符,请使用 %s。
ss 将秒显示为带前导零的数字(例如 12:15:05)。
f 显示秒的小数部分。例如,ff 将精确显示到百分之一秒,而 ffff 将精确显示到万分之一秒。用户定义格式中最多可使用七个 f 符号。如果这是用户定义的数字格式中的唯一字符,请使用 %f。
t 使用 12 小时制,并对中午之前的任一小时显示大写的 A,对中午到 11:59 P.M 之间的任一小时显示大写的 P。如果这是用户定义的数字格式中的唯一字符,请使用 %t。
tt 对于使用 12 小时制的区域设置,对中午之前任一小时显示大写的 AM,对中午到 11:59 P.M 之间的任一小时显示大写的 PM。对于使用 24 小时制的区域设置,不显示任何字符。
y 将年份 (0-9) 显示为不带前导零的数字。如果这是用户定义的数字格式中的唯一字符,请使用 %y。
yy 以带前导零的两位数字格式显示年份。
yyy 以四位数字格式显示年份。
yyyy 以四位数字格式显示年份。
z 显示不带前导零的时区偏移量(如 -8)。如果这是用户定义的数字格式中的唯一字符,请使用 %z。
zz 显示带前导零的时区偏移量(例如 -08)
zzz 显示完整的时区偏移量(例如 -08:00)
15.PrefixHeader.pch文件添加

  1. 创建文件 .pch文件(commoand + N -> Othe -> PCH File )
  2. 设置PrefixHeader路径(选中Target -> Build Settings ->Prefix Header)

16.use of '@import' when modules are disabled

首先设置选中Target -> Build Settings -> Enable Module (C and Objective-C) 为YES

如果不行,请检查在导入的该头文件的文件格式是否为.mm(编译c++的文件,例如百度地图需要把AppDelegate.m改成AppDelegate.mm)文件。
17.iOS 推送
本地推送。
iOS10以前

  • (void)post_Less_iOS10:(NSDictionary *)userInfo title:(NSString *)title body:(NSString *)body{
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    // 设置触发通知的时间,这里设置的是立即触发
    NSDate *fireDate = [NSDate date];
    notification.fireDate = fireDate;

    // 通知内容
    notification.alertBody = body;
    //标题,iOS8.2之后才有了这个属性
    if ([notification respondsToSelector:@selector(setAlertTitle:)]) {
    notification.alertTitle = title;
    }

    // 通知的声音
    notification.soundName = UILocalNotificationDefaultSoundName;
    //附带内容
    notification.userInfo = userInfo;

    // ios8后,需要添加这个注册,才能得到授权
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    ///设置
    UIUserNotificationType type = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:type
    categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    }

    // 执行通知注册
    [[UIApplication sharedApplication] scheduleLocalNotification:notification];
    }
    AppDelegate.m

  • (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
    if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {//app在前台
    NSLog(@"app在前台");
    }else{//不在前台
    NSLog(@"app不在前台");
    }
    }
    iOS10之后

  • (void)registerNoti{
    // iOS10 兼容
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
    // 使用 UNUserNotificationCenter 来管理通知
    UNUserNotificationCenter *uncenter = [UNUserNotificationCenter currentNotificationCenter];
    // 监听回调事件
    [uncenter setDelegate:self];
    //iOS10 使用以下方法注册,才能得到授权
    [uncenter requestAuthorizationWithOptions:(UNAuthorizationOptionAlert+UNAuthorizationOptionBadge+UNAuthorizationOptionSound)
    completionHandler:^(BOOL granted, NSError * _Nullable error) {
    NSLog(@"%@" , granted ? @"授权成功" : @"授权失败");
    }];
    // 获取当前的通知授权状态, UNNotificationSettings
    [uncenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
    if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined) {
    NSLog(@"未选择");
    } else if (settings.authorizationStatus == UNAuthorizationStatusDenied) {
    NSLog(@"未授权");
    } else if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) {
    NSLog(@"已授权");
    }
    }];
    }
    }

  • (void)post_iOS10:(NSDictionary *)userInfo title:(NSString *)title body:(NSString *)body{

    // 使用 UNUserNotificationCenter 来管理通知
    UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];

    //需创建一个包含待通知内容的 UNMutableNotificationContent 对象,注意不是 UNNotificationContent ,此对象为不可变对象。
    UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
    content.title = [NSString localizedUserNotificationStringForKey:title arguments:nil];
    content.body = [NSString localizedUserNotificationStringForKey:body
    arguments:nil];
    content.sound = [UNNotificationSound defaultSound];

    content.userInfo = userInfo;
    // 在 alertTime 后推送本地推送
    UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger
    triggerWithTimeInterval:1 repeats:NO];

    UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"FiveSecond"
    content:content trigger:trigger];

    //添加推送成功后的处理!
    [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
    }];
    }

pragma mark - UNUserNotificationCenterDelegate

///在前台接收到通知
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
completionHandler(UNNotificationPresentationOptionAlert);//不写这句通知不会出现在前台,如有需要|UNNotificationPresentationOptionSound,角标UNNotificationPresentationOptionBadge
}

///点击通知

  • (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler{
    //handle touch event
    }
    上面代码可以写在appdelegate里面,或者一个单例。registerNoti 方法在发送前或者app启动的时候调用。

注意iOS10之前本地通知在app处于前台的时候是不会出现的,有时或者有些产品需要这样的功能,故此只能自己做个类似通知一样的东西,在这里推荐个EBForeNotification。

18.首字母获取

  • (NSString *)getFirstChat:(NSString *)string{
    NSMutableString *str = [NSMutableString stringWithString:string];
    CFStringTransform((CFMutableStringRef) str, NULL, kCFStringTransformMandarinLatin, NO);
    CFStringTransform((CFMutableStringRef)str, NULL, kCFStringTransformStripDiacritics, NO);
    NSString *pinYin = [str capitalizedString];
    return [pinYin substringToIndex:1];
    }
    19.状态栏

1.启动的时候隐藏状态栏
info.plist 设置字段Status bar is initially hidden 为YES

2.状态栏颜色为白色UIStatusBarStyleLightContent
info.plist 设置字段Status bar style为YES

3.关于View controller-based status bar appearance
//如果View controller-based status bar appearance的值是YES,那么程序中要改变状态栏颜色只能设置整个app的状态,单独设置某个VC是不行的也就是说UIViewController的下面两个方法失效:

  • (UIStatusBarStyle)preferredStatusBarStyle;
    -(BOOL)prefersStatusBarHidden;

4.刷新当前VC的状态栏
//info.plist文件中不能含有View controller-based status bar appearance
[self setNeedsStatusBarAppearanceUpdate];
20.导航栏背景颜色

//这里调用到了下面的颜色生成图片的方法
UIImage *img = [UIImage HH_CreateImageFromColor:color];
[self.navigationBar setBackgroundImage: img forBarMetrics:UIBarMetricsDefault];

//设置阴影,如果不设置导航栏下面有条黑线
[self.navigationBar setShadowImage:img];
21.颜色生成图片

pragma mark - 根据颜色和大小生产图片

  • (UIImage *)HH_CreateImageFromColor:(UIColor *)color size:(CGSize)size
    {
    CGRect imageRect = CGRectMake(0, 0, size.width, size.height);
    UIGraphicsBeginImageContext(imageRect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, imageRect);
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
    }
    22.色值生成颜色
    .h

@interface UIColor (HHCategory)
/**

  • @brief 根据色值得到颜色
  • @param hex 16进制的色值
    **/
    +(UIColor *)HH_ColorWithHex:(int)hex;

/**

  • @brief 根据色值得到颜色
  • @param hexString 16进制色值
    **/
    +(UIColor *)HH_ColorWithHexString:(NSString *)hexString;

/**

  • @brief 根据色值得到颜色
  • @param hexString 16进制色值
  • @param alpha 透明值
    **/

+(UIColor *)HH_ColorWithHexString:(NSString *)hexString alpha:(CGFloat)alpha;

@end
.m

import "UIColor+HHCategory.h"

@implementation UIColor (HHCategory)

pragma mark - 根据色值生成颜色

+(UIColor *)HH_ColorWithHex:(int)hex
{

return [UIColor colorWithRed:((float)((hex & 0xFF0000) >> 16))/255.0 green:((float)((hex & 0xFF00) >> 8))/255.0 blue:((float)(hex & 0xFF))/255.0 alpha:1.0];

}

pragma mark - 根据16进制色值字符串生成颜色

+(UIColor *)HH_ColorWithHexString:(NSString *)hexString
{
return [self HH_GetColorWithHexString:hexString alpha:1.0];
}

pragma mark - 根据16进制色值字符串和透明度生成颜色

+(UIColor *)HH_ColorWithHexString:(NSString *)hexString alpha:(CGFloat)alpha
{
return [self HH_GetColorWithHexString:hexString alpha:alpha];
}

pragma mark - 根据16进制色值字符串和透明度生成颜色

  • (UIColor *)HH_GetColorWithHexString:(NSString *)hexString alpha:(CGFloat)alpha
    {
    float red ,blue,green;
    NSMutableString * colorString = [hexString mutableCopy];
    if ([colorString hasPrefix:@"0x"]||[colorString hasPrefix:@"0X"]) {
    [colorString replaceCharactersInRange:NSMakeRange(0, 2) withString:@""];
    }

    if ([colorString hasPrefix:@"#"]) {
    [colorString replaceCharactersInRange:NSMakeRange(0, 1) withString:@""];
    }

    if ([colorString length]>=2) {
    NSString * oneString = [hexString substringWithRange:NSMakeRange(0, 1)];
    NSString * towString = [hexString substringWithRange:NSMakeRange(1, 1)];
    red = [self hexString:oneString]*16+ [self hexString:towString];
    }
    else
    {
    red = 0;
    }

if ([colorString length]>=4) {
    NSString * oneString  = [hexString substringWithRange:NSMakeRange(2, 1)];
    NSString * towString  = [hexString substringWithRange:NSMakeRange(3, 1)];
    green =  [self hexString:oneString]*16+ [self hexString:towString];
}
else
{
    green = 0;
}

if ([colorString length]>=6) {
    NSString * oneString  = [hexString substringWithRange:NSMakeRange(4, 1)];
    NSString * towString  = [hexString substringWithRange:NSMakeRange(5, 1)];
    blue =  [self hexString:oneString]*16+ [self hexString:towString];
}
else
{
    blue = 0;
}


return [UIColor colorWithRed:red/255 green:green/255 blue:blue/255 alpha:alpha];

}

pragma mark - 根据16进制色值字符串转成数值

+(int)hexString:(NSString *)charString
{
if ([charString isEqualToString:@"0"]) {
return 0;
}
if ([charString isEqualToString:@"1"]) {
return 1;
}
if ([charString isEqualToString:@"2"]) {
return 2;
}
if ([charString isEqualToString:@"3"]) {
return 3;
}
if ([charString isEqualToString:@"4"]) {
return 4;
}
if ([charString isEqualToString:@"5"]) {
return 5;
}
if ([charString isEqualToString:@"6"]) {
return 6;
}
if ([charString isEqualToString:@"7"]) {
return 7;
}
if ([charString isEqualToString:@"8"]) {
return 8;
}
if ([charString isEqualToString:@"9"]) {
return 9;
}

if ([charString isEqualToString:@"a"] ||[charString isEqualToString:@"A"]) {
    return 10;
}
if ([charString isEqualToString:@"b"]||[charString isEqualToString:@"B"]) {
    return 11;
}
if ([charString isEqualToString:@"c"]||[charString isEqualToString:@"C"]) {
    return 12;
}
if ([charString isEqualToString:@"d"]||[charString isEqualToString:@"D"]) {
    return 13;
}
if ([charString isEqualToString:@"e"]||[charString isEqualToString:@"E"]) {
    return 14;
}

if ([charString isEqualToString:@"f"]||[charString isEqualToString:@"F"]) {
    return 15;
}
return 0;

}

@end
23.获取app信息

NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
// 当前应用名称
NSString *appCurName = [infoDictionary objectForKey:@"CFBundleDisplayName"];
if(appCurName == nil){
    appCurName = [infoDictionary objectForKey:@"CFBundleName"];
}
NSLog(@"应用名称:%@",appCurName);
// 版本  比如:1.0.1
NSString *appCurVersion = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
NSLog(@"版本:%@",appCurVersion);

UIDevice *device = [UIDevice currentDevice];
//手机别名
NSString* userPhoneName = [device name];
NSLog(@"手机别名: %@", userPhoneName);
//系统名称
NSString* osName = [device systemName];
NSLog(@"设备名称: %@",osName );
//手机系统版本
NSString* phoneVersion = [device systemVersion];
NSLog(@"手机系统版本: %@", phoneVersion);
//手机型号
NSString* phoneModel = [device model];
NSLog(@"手机型号: %@",phoneModel );
//地方型号  (国际化区域名称)
NSString* localPhoneModel = [device localizedModel];
NSLog(@"国际化区域名称: %@",localPhoneModel );
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容