iOS 那些必备却又记不清的知识点...
2019-05-07 本文已影响0人
iOS_July
内容较多,建议command + F,去吧:
一、tableView刷新指定行
//一个section刷新
NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:section];
[tableview reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];
//一个cell刷新
NSIndexPath *indexPath=[NSIndexPath indexPathForRow:row inSection:section];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation:UITableViewRowAnimationNone];
二、tableView胡乱漂移
_tableView.estimatedRowHeight = 0;
_tableView.estimatedSectionHeaderHeight = 0;
_tableView.estimatedSectionFooterHeight = 0;
三、模型 嵌套 模型数组
- json类似于:
NSArray *tempArr = @[@{@"checkProject":@"第一",@"status":@"-1",@"countList":
@[
@{@"checkContent":@"checkProject",@"status":@"-1"},
@{@"checkContent":@"什么项目呀",@"status":@"0"},
@{@"checkContent":@"喵喵喵",@"status":@"1"},
@{@"checkContent":@"已执行",@"status":@"2"},
@{@"checkContent":@"好的呀👌",@"status":@"3"},]},
@{@"checkProject":@"第二",@"status":@"-1",@"countList":@[
@{@"checkContent":@"checkProject",@"status":@"-1"},
@{@"checkContent":@"什么项目呀",@"status":@"0"},
@{@"checkContent":@"喵喵喵",@"status":@"1"},
@{@"checkContent":@"已执行",@"status":@"2"},
@{@"checkContent":@"好的呀👌",@"status":@"3"},]},
@{@"checkProject":@"第三",@"status":@"-1",@"countList":@[
@{@"checkContent":@"checkProject",@"status":@"-1"},
@{@"checkContent":@"什么项目呀",@"status":@"0"},
@{@"checkContent":@"喵喵喵",@"status":@"1"},
@{@"checkContent":@"已执行",@"status":@"2"},
@{@"checkContent":@"好的呀👌",@"status":@"3"},]},
@{@"checkProject":@"第四",@"status":@"-1",@"countList":@[
@{@"checkContent":@"checkProject",@"status":@"-1"},
@{@"checkContent":@"什么项目呀",@"status":@"0"},
@{@"checkContent":@"喵喵喵",@"status":@"1"},
@{@"checkContent":@"已执行",@"status":@"2"},
@{@"checkContent":@"好的呀👌",@"status":@"3"},]}];
- 除了
tempArr
本身可转成一个模型外,其中包含countList
,也是一个模型。 - 在
模型的 .h
中:
//内部模型
@interface EHSCheckPlanDetailCountListModel : NSObject
/** status*/
@property (nonatomic, copy) NSString * status;
/** 检查项目名称*/
@property (nonatomic, copy) NSString *checkProject;
/** 检查内容*/
@property (nonatomic, copy) NSString *checkContent;
@end
//外部模型
@interface EHSCheckPlanDetailModel : NSObject
/** status*/
@property (nonatomic, copy) NSString * status;
/** 检查项目名称*/
@property (nonatomic, copy) NSString *checkProject;
/** 嵌套model*/
@property (nonatomic, strong) NSMutableArray *countList;
@end
- 这时候 是不能 直接使用的,需要在
.m
中,转换一下:
@implementation EHSCheckPlanDetailCountListModel
@end
@implementation EHSCheckPlanDetailModel
+ (NSDictionary *)mj_objectClassInArray{
return @{ @"countList" : [EHSCheckPlanDetailCountListModel class]};
}
@end
四、模型转 id 等 关键字
- 在
.h
中:
/** id*/
@property (nonatomic, copy) NSString *ID;
- 在
.m
中:
+ (NSDictionary *)replacedKeyFromPropertyName{
return @{@"ID":@"id"};
}
五、字符串截取
//1.截取字符串
NSString *string =@"123456789";
NSString *str1 = [string substringToIndex:5];//截取 到 下标5之前的字符串
NSLog(@"截取的值为:%@",str1);
NSString *str2 = [string substringFromIndex:3];//从 下标3之后的字符串 开始截取
NSLog(@"截取的值为:%@",str2);
六、判断字符串是否包含字符&&截取
if([@"abc" rangeOfString:@"a"].location !=NSNotFound) {
NSLog(@"yes");
}else {
NSLog(@"no");
}
NSString *string =@"123456789";
NSRange range = [string rangeOfString:@"4"];//匹配得到的下标
NSLog(@"rang:%@",NSStringFromRange(range));
string = [string substringWithRange:range];//截取范围内的字符串
NSLog(@"截取的值为:%@",string);
七、字符串分割为数组
NSString *string =@"123456789";
NSArray *array = [string componentsSeparatedByString:@"5"]; //从字符'5'中分隔成2个元素的数组
NSLog(@"array:%@",array);
八、数组转字符串
NSString *str = [arr componentsJoinedByString:@","];//以","为分隔符
九、数组是否存在指定字符串
NSString *str = @"12";
NSArray *array=@[@"12",@"22",@"13",@"3567"];
BOOL isbool = [array containsObject: str];
十、通知传值
-
NSNotification
通知中心传值,可以跨越多个页面传值, 一般多用在push后面的页面传给前面的页面 - 思路:
- 在第一个界面建立一个通知中心, 通过通知中心,注册一个监听事件,写好接受通知的事件。
- 在第一个界面中的dealloc中, 将通知中心remove掉
- 在第二个界面中, 建立一个通知中心, 通过通知中心, 发送通知
(发送通知的过程就是传值的过程,将要传输的值作为object的值传给第一个界面 )
- 第一个页面:
- (void)viewDidLoad {
[super viewDidLoad];
[self registerNotification];
}
#pragma mark - --------- 通知相关 ---------
- (void)registerNotification{
//通知中心是个单例
NSNotificationCenter *notiCenter = [NSNotificationCenter defaultCenter];
// 注册一个监听事件。第三个参数的事件名, 系统用这个参数来区别不同事件。
[notiCenter addObserver:self selector:@selector(receiveNotification:) name:kNotificationAddManPush object:nil];
}
- (void)receiveNotification:(NSNotification *)noti
{
// NSNotification 有三个属性,name, object, userInfo,其中最关键的object就是从第三个界面传来的数据。name就是通知事件的名字, userInfo一般是事件的信息(多个信息传递)。
NSLog(@"%@ === %@ === %@", noti.object, noti.userInfo, noti.name);
}
- (void)dealloc
{
// 移除当前对象监听的事件
[[NSNotificationCenter defaultCenter] removeObserver:self];
//[[NSNotificationCenter defaultCenter] removeObserver:self name:kNotificationAddManPush object:nil];
}
- 第二个界面:
NSDictionary *dict = @{@"model":__weakSelf.dataList,@"name":smodel.employeeName};
// 创建一个通知中心
// 发送通知. 其中的 kNotificationAddManPush 填写第一界面的Name, 系统知道是第一界面来相应通知, object就是要传的值。 UserInfo是一个字典, 如果要用的话,提前定义一个字典, 可以通过这个来实现多个参数的传值使用。
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
//发送通知
[center postNotificationName:kNotificationAddManPush object:@"人员选择" userInfo:dict];
[self.navigationController popViewControllerAnimated:YES];
十一、Domain=SDWebImageErrorDomain Code=0 "Downloaded image has 0 pixels" UserInfo
- 先吐槽一下,当你知道答案后会让你不知所措
- 在网页上可以打开,SDWebImage就是死活缓存不了,换一张其他的网图却又可以显示...
- 有的说是请求头,但当你设置请求头之后,依旧是 返回0像素图片....真正原因其实是Cookies!
-
SDWebImageHandleCookies!
[cell.imgView sd_setImageWithURL:[NSURL URLWithString:imgUrl] placeholderImage:normalImg options:SDWebImageHandleCookies];
十二、the document "units.h" could not be saved.you don't have permission
- 我相信你已经在
stackoverflow
上逛了一会回来了,心情还美丽吗? - 我的解决办法是,关机、重启!
关不了?那就暴力点呗~
十三、pop返回到指定界面
{
EHSTroubleFillViewController *vc = [[EHSTroubleFillViewController alloc]init];
[self PopToViewControllerWithVC:vc];
}
#pragma mark - ------- 返回到指定界面 -------
- (void)PopToViewControllerWithVC:(UIViewController *)targetVC
{
UIViewController *target = nil;
for (UIViewController * controller in self.navigationController.viewControllers) {
if ([controller isKindOfClass:[targetVC class]]) {
target = controller;
}
}
if (target) {
[self.navigationController popToViewController:target animated:YES];
}
}
十四、Label计算显示百分数
- 1.不需要保留小数 && 不要四舍五入
float p = [model.studiedCount floatValue]/[model.totalCount floatValue];
[self.progressView setProgress:p animated:YES];//我设置的进度条,可忽略
CGFloat result = p * 100;
if (result == 100) {
self.learnLab.text = @"100%";
}else{
NSString *resultStr = [NSString stringWithFormat:@"%f",result];//避免.f会四舍五入的情况
NSArray *tempA = [resultStr componentsSeparatedByString:@"."];
self.learnLab.text = [NSString stringWithFormat:@"%@%%",tempA.firstObject];
}
- 2.需要保留小数 && 四舍五入
float p = [model.count floatValue]/[model.allCount floatValue];
CGFloat result = p * 100;
if (result == 100) {
self.percentageLab.text = @"100%";
}else{
self.percentageLab.text = [NSString stringWithFormat:@"%.1f%%",result];//需要保留小数 && 四舍五入
}
十五、Label置顶、置底显示
- 当设置
numberOfLines
与相关高度之后,Label的内容在很多的情况下看不出异常,但是如果Label内容很少,不足以支撑换行,那么这时候情况就开始诡异了,它会垂直居中显示。 - 改善:
- Label扩展.h里:
///置顶显示
- (void)setAlignmentTop;
///置底显示
- (void)setAlignmentBottom;
- Label扩展.m里
///置顶显示
-(void)setAlignmentTop
{
// 对应字号的字体一行显示所占宽高
CGSize fontSize = [self.text sizeWithAttributes:@{NSFontAttributeName:self.font}];
// 多行所占 height*line
double height = self.frame.size.height;
// 显示范围实际宽度
double width = self.frame.size.width;
// 对应字号的内容实际所占范围
CGSize stringSize = [self.text boundingRectWithSize:CGSizeMake(width, height) options:(NSStringDrawingUsesLineFragmentOrigin) attributes:@{NSFontAttributeName:self.font} context:nil].size;
// 剩余空行
NSInteger line = (height - stringSize.height) / fontSize.height;
// 用回车补齐
for (int i = 0; i < line; i++) {
self.text = [self.text stringByAppendingString:@"\n "];
}
}
///置底显示
-(void)setAlignmentBottom
{
CGSize fontSize = [self.text sizeWithAttributes:@{NSFontAttributeName:self.font}];
double height = fontSize.height*self.numberOfLines;
double width = self.frame.size.width;
CGSize stringSize = [self.text boundingRectWithSize:CGSizeMake(width, height) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:self.font} context:nil].size;
NSInteger line = (height - stringSize.height) / fontSize.height;
// 前面补齐换行符
for (int i = 0; i < line; i++) {
self.text = [NSString stringWithFormat:@" \n%@", self.text];
}
}
十六、Label首行缩进
#pragma mark - 首行缩进
- (void)adjustLabelStyle:(UILabel *)label contentStr:(NSString *)contentStr
{
NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
paraStyle.alignment = NSTextAlignmentLeft; //对齐
paraStyle.headIndent = 0.0f;//行首缩进
//参数:(字体大小17号字乘以2,34f即首行空出两个字符)
CGFloat emptylen = label.font.pointSize * 2;
paraStyle.firstLineHeadIndent = emptylen;//首行缩进
paraStyle.tailIndent = 0.0f;//行尾缩进
paraStyle.lineSpacing = 2.0f;//行间距
NSAttributedString *attrText = [[NSAttributedString alloc] initWithString:contentStr attributes:@{NSParagraphStyleAttributeName:paraStyle}];
label.attributedText = attrText;
}
十七、绘制虚线间隔
- image的扩展中,为类方法,如果不写在扩展里,或者用的场景较少,可直接改成类方法。
/**
返回一张 虚线 image
@param imageView imageView
@param lineColor lineColor
@param vertical 是则 绘制垂直虚线/否则 为水平虚线
@return image
*/
+ (UIImage *)imageWithLineWithImageView:(UIImageView *)imageView lineColor:(UIColor *)lineColor vertical:(BOOL)vertical{
CGFloat width = imageView.frame.size.width;
CGFloat height = imageView.frame.size.height;
//画线
if (vertical) {
UIGraphicsBeginImageContext(imageView.frame.size);
[imageView.image drawInRect:CGRectMake(0, 0, width, height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGFloat lengths[] = {5,5};//虚线的长度设置
CGContextRef context =UIGraphicsGetCurrentContext();
CGContextBeginPath(context);
CGContextSetLineWidth(context,1);
CGContextSetStrokeColorWithColor(context, lineColor.CGColor);
CGContextSetLineDash(context, 0, lengths,2);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, 0,height);
CGContextStrokePath(context);
CGContextClosePath(context);
}else{
UIGraphicsBeginImageContext(imageView.frame.size);
[imageView.image drawInRect:CGRectMake(0, 0, width, height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGFloat lengths[] = {5,5};//虚线的长度设置
CGContextRef line = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(line, lineColor.CGColor);
CGContextSetLineDash(line, 0, lengths, 1);
CGContextMoveToPoint(line, 0, 1);
CGContextAddLineToPoint(line, width-5, 1);
CGContextStrokePath(line);
}
return UIGraphicsGetImageFromCurrentImageContext();
}
- 使用:
UIImageView *padV2 = [[UIImageView alloc]initWithFrame:CGRectMake(0, CGRectGetMaxY(examineeBtn.frame)+10, WIDTH, 1)];
padV2.image = [UIImage imageWithLineWithImageView:padV2 lineColor:JHRGB(200, 200, 200)];
[contentView addSubview:padV2];
十八、简单的GCD延时执行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
});
十九、删除Xcode的多余证书
- 前往
~/Library/MobileDevice/Provisioning Profiles
二十、UITextField 修改Placeholder颜色
// "通过KVC修改占位文字的颜色"
[textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];