【不定期总结】遇到的各个小技巧
本人太懒了。。总是静不下来做总结。
思前想后,写点算点吧。希望警醒自己,方便他人。有的也不算技巧。只是解决问题的方法,能解决问题,不见得是最好的。也希望得到大神的斧正。
1、隐藏状态栏
iOS7中,明显,度娘的方法
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
没有得到希望的效果。
最简单的方法是,直接在RootViewController.m里面(Cocos2d-x项目),加上:
//ADD 20130926 FOR iOS7(隐藏状态栏) - (BOOL)prefersStatusBarHidden { return YES; }
2、Cell接收的回调函数
我犯了一个非常煞笔的错误,写在这警醒自己。我在
[tableView setEditing:YES animated:YES];
时,希望改变这个TableView里的Cell的属性。寻找API提供的回调函数时,找到了这个
setEditing:(BOOL)editing
发现没有回调事件,于是得出结论,没有相关API,自己去写代理。其实系统原本已经封装好了,对应的回调应该时
setEditing:(BOOL)editing animated:(BOOL)animated
调用什么方法,监听什么回调。这么傻的问题,估计只有我会犯。另外,千万记住,实现回调的时候,首先执行
[super setEditing:editing animated:animated];
3、视图跳转
3.1、我有三个界面,分别为A、B、C。其中A通过Push到C,B通过Modal到C。C怎么返回?
首先明确的时,Push的界面通过pop返回,Modal的界面通过Dismiss返回。这时候C又不知道时Push还是Modal,怎么知道选择哪种返回方式呢?
答:让C知道。方法我暂时想的通过参数,进入C的时候,通过参数指明类型。返回的时候就知道了。
- (IBAction)btnBack:(id)sender { switch (mode) { case EntryModePush: [self.navigationController popViewControllerAnimated:YES]; break; case EntryModeModal: [self dismissViewControllerAnimated:YES completion:nil]; break; } }
mode是自己定义的枚举。大家可以根据需要自己定义。不过我真的觉得这种做法好学生的感觉。不知道有没有更像Coder一点做法。
【后注】:
if (self.navigationController) { [self.navigationController popViewControllerAnimated:YES]; }else{ [self dismissViewControllerAnimated:YES completion:nil]; }
or(by 点特.)
UIViewController *vc; vc = [self.navigationController popViewControllerAnimated:YES]; if (!vc) { [self dismissViewControllerAnimated:YES completion:nil]; }
3.2、假设有这么一个需求,需要在任意的ViewController,跳转回初始的VC。(例如场景:注销登录后返回登录界面。)
实现的方法很多,比如加入Nav,然后poptoroot等……比如:
self.view.window.rootViewController = self.storyboard.instantiateInitialViewController;
4、No code signature found等其他若干问题
不得不说,经典的东西总有他的道理。有些问题,不要从字面上去解决。
Remember:
1.多喝水
2.重启一下Xocde
5、UIButton传参
这是一个老生常谈的问题,都知道UIButton设置监听的方法
[button addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
这时候由于业务需要,需要给btnClick方式带一个参数。
简单情况下,如果参数是int类型,我们可以直接给button.tag设置数值。然后
[button addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
在
-(void)btnClick:(UIButton *)btn
方法里btn.tag即是我们传递的值。
如果需要传递的参数是字符串呢?笔者在这里可以很负责的讲,UIButton没办法直接传递!至少写博之时是没办法的。
但是确实有这种需求,怎么办?
笔者推荐两种方法:
5.1、强传:
api没提供直接传的方法,那么就自己加吧。自己重写一个Button可以继承于UIButton,给一个或若干个根据需求需要的属性。在使用的时候,把需要的参数写入属性。搞定!很简单,就不贴代码了。
5.2、通过数据源:
笔者想,可能这才是苹果官方的用意。故意不提供传参的方法,让开发者清楚:视图和事件,不应该和数据搅杂在一块。
举个例子:
我有10个按钮,点击每个按钮会打开不同的图片。
难道要把图片传给按钮吗???
当然不用!想想你的图片从哪来的?你只需要知道你点了哪个按钮,然后从数据源中取出相应按钮的数据。就完成了。
6 编码
6.1、常用的编码UTF-8。
个人理解:编码:
[string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
解码:
[string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
但是api的方法是不完善的。一些特殊符号得不到相应的处理。比如:!$&'()*+,-./:;=?@_~%#[]
NSString *str = @"+";
str = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
这个时候"+"仍然是"+",而不是预期的"%2b"。
这个时候需要特殊情况特殊处理,从http://blog.csdn.net/typingios/article/details/9136005找到了参考方案。但是不知道为什么文章作者参数貌似搞错了。
自己整理修改后如下,新建category,然后需要使用的类头文件import "NSString+URL.h" 即可调用.
NSString+URL.h
@interface NSString (URL) - (NSString *)URLEncodedString; @end
NSString+URL.m
- (NSString *)URLEncodedString { NSString *encodedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,(CFStringRef)self,NULL,(CFStringRef)@"!$&'()*+,-./:;=?@_~%#[]",kCFStringEncodingUTF8)); return encodedString; }
调用的地方
NSString *str = @"+"; str = [str URLEncodedString];
输出结果为预期"%2b"
7 资源
有些时候我们会遇到这种情况,明明把资源文件拷贝进了工程,但是在
[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"文件名"];
后发现,系统找不到这个路径。甚至在查看app的包内容也看不到。
这个时候把我们的工程找到,在build phases里的Copy Bundle Rescources里重新加一遍就好。
8 IB连接
有些时候觉得自己真是钻牛角尖。大家知道,有个很简便的方法关联IB中的View和IB所在的类。
但是今天不知道为何(到现在都不知道为何!只能解释xcode疯了)始终不让我连。纠结了好久好久都没找到方法……
其实只要手动写上IBOutlet,再连就好了。
9 Nav导航
自定义UINavigation的leftItem从而自定义返回事件后,手势右滑返回失效了。在rootVC设置
self.navigationController.interactivePopGestureRecognizer.delegate = self.navigationController; self.navigationController.interactivePopGestureRecognizer.enabled = YES;
即可
10 Snapshotting a view that has not been rendered results in an empty snapshot.
这玩意我在两个地方遇到过,这里记载UIAlertController里的情况。当(1、iOS8以上设备;2、
UIAlertControllerStyleActionSheet;3、iPad而非iPhone)使用alertController时,每新增一个选项,就会报一次异常。强迫症不能忍。
解决方法是
[actionSheet setPreferredContentSize: actionSheet.view.frame.size];
初始化完之后加上这么一句。
顺带,iPad上使用UIAlertControllerStyleActionSheet崩溃的原因,是因为在iPad上和iPhone上视图弹出的方式不同,当在iPad上使用时,必须设置其锚点。
actionSheet.popoverPresentationController.sourceView = sender; actionSheet.popoverPresentationController.sourceRect = sender.bounds;
(什么时候想起再继续吧)