IOS开发中遇到问题备忘录

在开发中经常会遇到一些问题,刚开始感觉匪夷所思,但是当你真正探究,理解了就会发现确实如此。

19、translatesAutoresizingMaskIntoConstraints

translatesAutoresizingMaskIntoConstraints属性和autolayout有关,

如果你定义的view想用autolayout,就将translatesAutoresizingMaskIntoConstraints设为NO,如果你使用的不是autolayout,就将translatesAutoresizingMaskIntoConstraints设为YES,对应关系如下

autolayout translatesAutoresizingMaskIntoConstraints
NO
YES

18、navigationBar setBackgroundImage和setBarTintColor区别

在处理导航要不要透明时发现了下面的问题,
[nav.navigationBarsetBackgroundImage:[UIImageimageNamed:@"bt_green.png"]forBarMetrics:UIBarMetricsDefault];用这个来跑的效果是在Xib里UI不用+64像素,
[nav.navigationBar setBarTintColor:[ColorTool colorWithHexString:COLOR_THEME_NAVIGATION]]; [nav.navigationBar setTintColor:[ColorTool colorWithHexString:COLOR_THEME_NAVIGATION]];
使用这2个方法来定义导航颜色时,在Xib里的UI实际位置需要+64个像素,
使用设置了
nav.navigationBar.translucent =NO;在配合上面2个方法就能达到和setBackgroundImage一样的效果。这都是在ios7之后的变化。
可以去体验下。

  • navigation controller容器中布局到ios7中往上偏移了64px
    iOS6中默认的布局将从navigation bar的底部开始,但到了iOS7中默认布局从navigation bar的顶部开始,这就是为什么所有的UI元素都往上漂移了。因为在iOS7中,苹果引入了一个新的属性,叫做[UIViewController setEdgesForExtendedLayout:],它的默认值为UIRectEdgeAll,使用edgesForExtendedLayout指定视图的哪条边需要扩展,不用理会操作栏的透明度。所以这种情况快速修复的方法是:在-(void)viewDidLoad中添加如下一行代码:
self.edgesForExtendedLayout = UIRectEdgeNone;  
extendedLayoutIncludesOpaqueBars

关于这个属性的测试版本中默认值是YES,正式版本是NO!
如果你使用了不透明的navigation bar,设置edgesForExtendedLayout 还是默认值UIRectEdgeAll,你又想整个view全屏(navigation bar下面的内容网上漂移64px) extendedLayoutIncludesOpaqueBars 的值设置为YES。

17、other linker flags参数的作用

在前面我们说如果出现问题要在Other Linker Flags中加入-ObjC或者-all_load或者-force_load,我们为什么要加入这样的参数呢,他们究竟做了什么事呢?下面就是对这个三个参数的一个讲解.

  • ObjC: 一般这个参数足够解决前面提到的问题,这个flag告诉链接器把库中定义的Objective-C类和Category都加载进来。这样编译之后的app会变大,因为加载了很多不必要的文件而导致可执行文件变大。但是如果静态库中有类和category的话只有加入这个flag才行,但是Objc也不是万能的,当静态库中只有分类而没有类的时候,Objc就失效了,这就需要使用-all_load或者-force_load了。

  • -all_load: -all_load会强制链接器把目标文件都加载进来,即使没有objc代码。但是这个参数也有一个弊端,那就是你使用了不止一个静态库文件,那么你很有可能会遇到ld: duplicate symbol错误,因为不同的库文件里面可能会有相同的目标文件 这里会有两种方法解决 1:用命令行就行拆包. 2:就是用下面的这个参数

  • -force_load: 这个flag所做的事情跟-all_load其实是一样的,只是-force_load需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载 .

总结

  • 个人建议ObjC与force_load搭配使用比较好.

16、 如果项目中打了断点,但是Debug时不停,那可能时BuildSettings中了关掉了。修改Generate Debug SymbolsYES

QQ20171024-114840.png

15、数组中排序可能使用 NSStringCompareOptions,每个参数的意义如下:

typedefNS_OPTIONS(NSUInteger, NSStringCompareOptions) {
    NSCaseInsensitiveSearch = 1,    //不区分大小写比较
    NSLiteralSearch = 2,    //逐字节比较 区分大小写
    NSBackwardsSearch = 4,    //从字符串末尾开始搜索
    NSAnchoredSearch = 8,    //搜索限制范围的字符串
    NSNumericSearch = 64,    //按照字符串里的数字为依据,算出顺序。例如 Foo2.txt < Foo7.txt < Foo25.txt
    NSDiacriticInsensitiveSearchNS_ENUM_AVAILABLE(10_5, 2_0) = 128,//忽略 "-" 符号的比较
    NSWidthInsensitiveSearchNS_ENUM_AVAILABLE(10_5, 2_0) = 256,//忽略字符串的长度,比较出结果
    NSForcedOrderingSearchNS_ENUM_AVAILABLE(10_5, 2_0) = 512,//忽略不区分大小写比较的选项,并强制返回 NSOrderedAscending 或者 NSOrderedDescending
    NSRegularExpressionSearchNS_ENUM_AVAILABLE(10_7, 3_2) = 1024   //只能应用于 rangeOfString:..., stringByReplacingOccurrencesOfString:...和 replaceOccurrencesOfString:... 方法。使用通用兼容的比较方法,如果设置此项,可以去掉 NSCaseInsensitiveSearch 和 NSAnchoredSearch
};

14、NavigationBar自定义高度和调整子控件的位置

  • 设置navigationbar的高度
 UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, ScreenWidth, 64)];
   [self.navigationController.navigationBar addSubview:view];

  • 设置子空间的位置
-(void)viewWillAppear:(BOOL)animated{

    [super viewWillAppear:animated];
    [self.navigationController.navigationBar setTitleVerticalPositionAdjustment:20.0 forBarMetrics:UIBarMetricsDefault];
    [self.navigationItem.leftBarButtonItem setBackgroundVerticalPositionAdjustment:20.0 forBarMetrics:UIBarMetricsDefault];
    
}

- (void)viewDidDisappear:(BOOL)animated{
    [self.navigationController.navigationBar setTitleVerticalPositionAdjustment:0.0 forBarMetrics:UIBarMetricsDefault];
    [self.navigationItem.leftBarButtonItem setBackgroundVerticalPositionAdjustment:0.0 forBarMetrics:UIBarMetricsDefault];
}

注:上述运行结果的前提是使用自定义图片的leftBarButtonItem作为返回按钮替代系统默认的 backBarButtonItem,并且你的leftBarButtonItem是使用 initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action这个方法创建的(原因我后面会讲)。

问题1:系统默认的导航栏返回按钮垂直位置无法调节。

当返回按钮使用系统默认的backBarButtonItem的时候,使用UIBarButtonItem的- (void)setBackButtonBackgroundVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics来调整它的垂直位置,不起作用。

问题2:自定义的返回按钮在导航栏中的垂直位置仅在某一种情况下可以调节。

后来我又发现,即使不用系统默认地返回按钮,使用自定义的leftBarButtonItem,也只在使用 initWithImage:style target:action:这个方法创建的UIBarButtonItem时生效,使用其他init方法情况一律无效。至于什么原因不明觉厉。

参考:小荷才露尖尖角的iOS 如何自定义NavigationBar的高度

13、point的转换

-(CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;//点转换
-(CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view;//点转换
-(CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;//矩形转换
-(CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;//矩形转换

使用注意:
1.使用convertPoint:toView:时,调用者应为covertPoint的父视图。即调用者应为point的父控件。toView即为需要转换到的视图坐标系,以此视图的左上角为(0,0)点。
2.使用convertPoint:fromView:时正好相反,调用者为需要转换到的视图坐标系。fromView为point所在的父控件。
3.toView可以为nil。此时相当于toView传入self.view.window

12、CATransform3D是一个4 x 4的矩阵,矩阵中每一个值所代表的意义

struct CATransform3D
{
CGFloat m11(x缩放), m12(y切变), m13(旋转), m14();
CGFloat m21(x切变), m22(y缩放), m23(), m24();
CGFloat m31(旋转), m32( ), m33(), m34(透视效果,要操作的这个对象要有旋转的角度,否则没有效果。正直/负值都有意义);
CGFloat m41(x平移), m42(y平移), m43(z平移), m44();
};

11、Xcode7 升级到Xcode8 一编写代码就闪退问题,记录下,希望对有些小伙伴有用。PS:也是网上友人的解决方法。

xcode升级到8之后 ,插件不能用了,就又从心装了一下插件装完插件之后,再打开xcode,发现一写代码就闪退,很是郁闷。。。网上找了一下资料,发现是插件KSImageName的问题,于是把这个插件删除,重启了一下xcode就可以了
xcode插件的路径:~/Library/Developer/Xcode/Plug-ins
老版本:~/Library/Developer/Application Support/Developer/Shared/Xcode/Plug-ins

10、Xcode 工程文件打开不出来, cannot be opened because the project file cannot be parsed.

svn更新代码后,打开xcode工程文件,会出现 xxx..xcodeproj cannot be opened because the project file cannot be parsed.

因为.xcodeproj工程文件冲突了,然后还是会强制更新,内部文件出现了冲突,所以解析不了文件。

会出现这样的冲突消息

<<<<<<< .mine 9ADAAC6A15DCEF6A0019ACA8 .... in Resources */, ======= 52FD7F3D15DCEAEF009E9322 ... in Resources */, >>>>>>> .r269

解决方法:
- 1.对.xcodeproj 文件右键,显示包内容
- 2.双击打开 project.pbxproj 文件
- 3.找到以上类似的冲突信息(可以用commad + f 搜索)
- 4.删除 <<<<<<<,======,>>>>>>这些行
- 5.保存,退出
- 6.重新打开.xcodeproj文件即可

9 、button 文字图片上下/左右经常会用到,记录一下

  • 上下:
    self.rechargeButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;//使图片和文字水平居中显示

    [self.rechargeButton setTitleEdgeInsets:UIEdgeInsetsMake(self.rechargeButton.imageView.frame.size.height+10 ,-self.rechargeButton.imageView.frame.size.width, 0.0,0.0)];//文字距离上边框的距离增加imageView的高度,距离左边框减少imageView的宽度,距离下边框和右边框距离不变

    [self.rechargeButton setImageEdgeInsets:UIEdgeInsetsMake(-10, 0.0,0.0, -self.rechargeButton.titleLabel.bounds.size.width)];//图片距离右边框距离减少图片的宽度,其它不边
  • 左右:(因为默认button 图片在左,文字在右, 下面代码是反过来的: 文字 图片)
    [self.DetailButton setTitleEdgeInsets:UIEdgeInsetsMake(0, -self.DetailButton.imageView.bounds.size.width, 0, self.DetailButton.imageView.bounds.size.width)];

    [self.DetailButton setImageEdgeInsets:UIEdgeInsetsMake(0, self.DetailButton.titleLabel.bounds.size.width, 0, -self.DetailButton.titleLabel.bounds.size.width)];

8、解决pod update 更新缓慢的问题。

第一次导入第三包:
pod install --verbose --no-repo-update
以后每次更新:
pod update --verbose --no-repo-update

7、三种设置图片圆角的方法

  • 1.通过Layer的属性来设置圆角
// 设置圆角半径
view.layer.cornerRadius = cornersSize;
view.layer.masksToBounds = YES;
  • 2.通过Layer和bezierPath来设置圆角,下面的方法是写在UIImageView的一个Category中,所以selfUIImageView,可以根据项目需求对方法进行相应的改变:
//设置圆角
- (void)useShaperLayerCornersSize:(CGFloat)cornersSize {
    
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:cornersSize];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = self.bounds;
    maskLayer.path = maskPath.CGPath;
    self.layer.mask = maskLayer;
}
重点:CALayer 有个 mask 属性,用作 layer 的遮罩。这个遮罩和普通盖在上面的显示层不同,普通的遮罩是,盖上去,就遮住了下面的内容,而 mask 则是遮什么显示什么。
  • 3、通过Graphics 和 BezierPath 设置圆角,下面这个方法也是写在UIImageView的分类中:
- (void) userGraphicsCornersSize:(CGFloat )cornersSize{
    
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 1.f);
    
    [[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:self.frame.size.width] addClip];
    [self drawRect:self.bounds];
    self.image = UIGraphicsGetImageFromCurrentImageContext();
    //结束画图
    UIGraphicsEndImageContext();
    
}

6、UITableView当Style是Plain时,如果数据没有一屏幕,下面的这样显示,没有数据有一行行分割线,这样的界面往往不是我们想要的。

table_line.png

如何让没有数据的行不显示呢?

  • 1、TableView.tableFooterView = [[UIView alloc] init];,通过设置TableView的footerView来实现。
  • 2、TableView.separatorStyle = UITableViewCellSeparatorStyleNone;设置不显示分割线来实现。
    有时候可能设置BackgroundColor来使tableView更美观。

5、IOS中NSLog输出格式大全:

格式 对象
%zd NSInteger
%tu NSUInteger
%02d 不满两位的整数补0
%.2f 保留两位小数
%@ 对象
%d, %i 整数
%u 无符整形
%f 浮点/双字
%x, %X 二进制整数
%o 八进制整数
%zu size_t
%p 指针
%e 浮点/双字 (科学计算)
%g 浮点/双字
%s C 字符串
%.*s Pascal字符串
%c 字符
%C unichar
%lld 64位长整数(long long)
%llu 无符64位长整数
%Lf 64位双字

4、如何设置TabBar图片的渲染颜色

  • 使用过TabBarController的小伙伴都知道,苹果提供按钮选中的默认颜色是蓝色,假如UI给你一张有颜色的TabBar选中图片,如下:


    projecselect.png

    但是你会悲催的发现事实不是这样的,而是下面这样的:


    QQ20170224-145338.png

    如何使用原始的图片呢?
    实际上当你设置选中图片时,如果不需要渲染图片,需要这样设置
[tabBarItem setSelectedImage:[[UIImage imageNamed:@"xxx"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];

UIImageRenderingModeAlwaysOriginal 这个属性可以完成你所想要的效果。

  • 如果你想你的TabBar跟随主题颜色变化,当然也可以提供多套主题颜色相关的图片,但是这样太繁琐了,我们可以通过设置TabBar的tintColor来实现:
self.tabBar.tintColor = [UIColor orangeColor];

3、UITableView分割线

  • IOS7以后UITableView的分割线距离左侧会有一点的距离,如何让分割线从屏幕左边开始呢?分别在ViewController中这两个方法中添加如下代码:
//设置分割线距离左侧屏幕距离为零 ios 7;
-(void)viewDidLayoutSubviews
{
    if ([self.mainTableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [self.mainTableView setSeparatorInset:UIEdgeInsetsMake(0,0,0,0)];
    }
    
    if ([self.mainTableView respondsToSelector:@selector(setLayoutMargins:)]) {
        [self.mainTableView setLayoutMargins:UIEdgeInsetsMake(0,0,0,0)];
    }
}


-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
        [cell setSeparatorInset:UIEdgeInsetsZero];
    }
    
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

2、NavigationBar 设置Item颜色和文字颜色

  • iOS7以前:

    • tintColor:设置navigationBar和navigationItem的颜色,navigationItem里面的字体默认为白色,如果想修改navigationItem字体颜色,需要自定义给navigationItem(Custom)。
  • iOS7之后(新增barTintColor属性):

    • tintColor:不再是以前的设置navigationBar和navigationItem的颜色,而是变成了只修改navigationItem里面的字体颜色。
    • barTintColor:设置navigationBar和navigationItem的颜色,由于iOS7的navigationItem以文字的方式体现,默认为蓝色,所以barTintColor看似乎对navigationItem无效。
  • 此外,如果想修改NavigationBar标题的颜色,可以通过设置titleTextAttributes属性来改变,颜色,字体,阴影等都可以设置

NSDictionary * dict = [NSDictionary dictionaryWithObject:color forKey:NSForegroundColorAttributeName];
 //大功告成
 self.navigationController.navigationBar.titleTextAttributes = dict;

1、图片缓存

应用中经常会加载图片,SDWebImage为我们提供了方便高效的请求网络资源图片的方法,但是有时候我们需要请求的图片可能服务器修改了,但是SDWebImage缓存还没有失效,这样的话就无法正确实时的展示服务器修改的图片。

  • SDWebImage可以通过- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options方法中的options - SDWebImageOptions来设置缓存策略。SDWebImageRefreshCached每次都刷新缓存,但是这需要服务器配合:setHeader("Cache-Control", "no-cache");要禁用缓存。

  • 还有一种方法就是简单粗暴的,直接清空图片缓存

    • 一种是磁盘缓存
      [[[SDWebImageManager sharedManager] imageCache] clearDisk];
    • 一种为内存缓存
      [[[SDWebImageManager sharedManager] imageCache] clearMemory];
    • 在IOS7中你会发现使用这两个方法缓存总清除不干净,即使断网下还是会有数据。这是因为在IOS7中,缓存机制做了修改,使用上述两个方法只清除了SDWebImage的缓存,没有清除系统的缓存,所以我们可以在清除缓存的代理中额外添加以下
      [[NSURLCache sharedURLCache] removeAllCachedResponses];

PS: 后面会持续更新...

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

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,103评论 4 62
  • Swift版本点击这里欢迎加入QQ群交流: 594119878最新更新日期:18-09-17 About A cu...
    ylgwhyh阅读 25,374评论 7 249
  • 今夜的星空很美 风静悄悄,土壤脉搏 震颤着的大地心跳 孤独像一张网 裹挟心灵走向深渊 被风雨磨砺过的心会受伤吗 不...
    夏光草木阅读 93评论 2 8
  • 昨天享受了一天助人之后的喜悦,让自己非常满足。一个对他人有偏见的妹妹,开始思考人与人的差异以及人们需要的沟通和交流...
    奇迹之光阅读 337评论 0 1