B8-iOS 开发的一些tips(上)
1、真机调试
1> 项目更换了证书和描述文件重新调试时,会运行失败,提示The application could not be verified.此时把设备上原项目删除,再调试运行即可。
2> Code Signing证书为distribution时,调试项目会提示加载失败,启动超时(time out),改为developer证书即可。
2、隐藏手机状态栏的几个方法
方法一、
// Setting statusBarHidden does nothing if your application is using the default UIViewController-based status bar system. @property(nonatomic,getter=isStatusBarHidden) BOOL statusBarHidden; - (void)setStatusBarHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation NS_AVAILABLE_IOS(3_2); [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone]; //不知道怎么使。。。
方法二、
- (BOOL)prefersStatusBarHidden { return YES; }
方法三、创建window级别设置为UIWindowLevelAlert,将状态栏遮住(常见发微博等提示消息功能)
static UIWindow *_window; @implementation HelpViewController - (void)viewDidLoad { [super viewDidLoad]; _window = [[UIWindow alloc] init]; _window.frame = self.view.frame; _window.windowLevel = UIWindowLevelAlert; [_window addSubview:textView]; _window.hidden = NO; }
3、Application loader的使用
详细内容链接,http://blog.csdn.net/nogodoss/article/details/8217062
4、宏替换NSLog函数,在发布后使NSLog函数无效,避免NSLog耗费性能
#ifdef DEBUG // 处于开发阶段 #define MYLog(...) NSLog(__VA_ARGS__) #else // 处于发布阶段 #define MYLog(...) #endif
5、要转成URL的字符串如果包含汉字,需要先将字符串转义
NSString *str = [NSString stringWithFormat:@"http://%@:%d/%@/cpi/msg/findDocumentId?loginname=%@",constants.webServer, constants.webPort, constants.man,self.userid]; NSString *urlString = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSURL *url = [NSURL URLWithString:urlString];
6、应用评分功能的实现
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"itms://itunes.apple.com/cn/app/id%d?mt=8",ZAppleID]]]; // 打开手机上的iTunes Store显示应用,ZAppleID是应用在iTunesConnect的Apple ID [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"itms-apps://itunes.apple.com/cn/app/id%d?mt=8",ZAppleID]]]; // 打开手机上的App Store显示应用,ZAppleID是应用在iTunesConnect的Apple ID
7、应用内实现应用评分(不跳转)(评论按钮无效,可下载)
此方法从iOS6开始,参考文章:http://blog.sina.com.cn/s/blog_6b8c3d7a0101apjz.html
- 导入StoreKit.framework
- #import <StoreKit/SKStoreProductViewController.h>
- 遵守代理 <SKStoreProductViewControllerDelegate>
- 实现如下:
- (void)evaluate { //初始化控制器 SKStoreProductViewController *storeProductViewContorller = [[SKStoreProductViewController alloc] init]; //设置代理请求为当前控制器本身 storeProductViewContorller.delegate = self; //加载一个新的视图展示 [storeProductViewContorller loadProductWithParameters: //appId唯一的 @{SKStoreProductParameterITunesItemIdentifier : @"967710424"} completionBlock:^(BOOL result, NSError *error) { //block回调 if(error){ NSLog(@"error %@ with userInfo %@",error,[error userInfo]); }else{ //模态弹出appstore [self presentViewController:storeProductViewContorller animated:YES completion:^{ } ]; } }]; } //取消按钮监听 - (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController { [self dismissViewControllerAnimated:YES completion:^{ ZLog(@"杀了控制器"); }]; }
8、Xcode断点
只要把断点设在 property 的声明上,就可以断到这个 property 所有的改变。Objective-C 和 Swift 通用。(补充,应该是断在了此属性的setter和getter方法。)
9、NSJSONReadingOptions
NSJSONReadingMutableContainers // 返回可变容器,NSMutableDictionary或NSMutableArray。 NSJSONReadingMutableLeaves // 返回的JSON对象中字符串的值为NSMutableString NSJSONReadingAllowFragments // 允许JSON字符串最外层既不是NSArray也不是NSDictionary,但必须是有效的JSON Fragment。例如使用这个选项可以解析 @“123” 这样的字符串。
10、scrollView的几个属性contentSize contentOffset contentInset
1>不能向上滑动很可能是因为contentSize的大小不对。
scrollView的几个属性contentSize contentOffset contentInset。
contentSize是scrollview可以滚动的区域,比如frame = (0 ,0 ,320 ,480) contentSize = (320 ,960),代表你的scrollview可以上下滚动,滚动区域为frame大小的两倍。
contentOffset是scrollview当前显示区域顶点相对于frame顶点的偏移量,比如上个例子你拉到最下面,contentoffset就是(0 ,480),也就是y偏移了480。
contentInset是scrollview的contentview的顶点相对于scrollview的位置,例如你的contentInset = (0 ,100),那么你的contentview就是从scrollview的(0 ,100)开始显示。
另外UITableView是UIScrollView的子类,它们在上述属性又有所不同,tabelview的contentsize是由它的下列方法共同实现的:
- (NSInteger)numberOfSections;
- (NSInteger)numberOfRowsInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
它会自动计算所有的高度和来做为它的contentsize的height。
11、关于点击状态栏不回到顶部问题解决方法
@property(nonatomic) BOOL scrollsToTop; // default is YES.
设置这个属性,可以让点击状态栏不回到顶部,但是如果我们需要让他回到顶部,程序又不响应操作,这时的解决方法:
刚才上面的官方文档说了,只有当一个主控制器有一个scrollview 并把这个属性设置为yes,其他的scrollview.scrollsToTop = NO
这样才会响应这个事件,原理很简单,如果有2个scrollview,系统根本不知道你需要哪个滚动到最上面。
12、UIImageView显示成圆形的两种方案
1》剪切imageView
self.faviconImageV.layer.cornerRadius = self.faviconImageV.width * 0.5; // 一定要有frame self.faviconImageV.layer.masksToBounds = YES; // 默认NO // self.faviconImageV.layer.borderWidth = 5.0; // self.faviconImageV.layer.borderColor = [UIColor purpleColor].CGColor;
2》画出一个圆的image
self.faviconImageV.image = [self circleImage:[UIImage imageWithData:data] withParam:0]; // 此方法可以写在UIImage的分类里面 - (UIImage *) circleImage:(UIImage *) image withParam:(CGFloat) inset { UIGraphicsBeginImageContext(image.size); CGContextRef context =UIGraphicsGetCurrentContext(); //圆的边框宽度为2,颜色为红色 CGContextSetLineWidth(context,2); CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); CGRect rect = CGRectMake(inset, inset, image.size.width - inset *2.0f, image.size.height - inset *2.0f); CGContextAddEllipseInRect(context, rect); CGContextClip(context); //在圆区域内画出image原图 [image drawInRect:rect]; CGContextAddEllipseInRect(context, rect); CGContextStrokePath(context); //生成新的image UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage;
13、UIColor,CGColor,CIColor三者的区别和联系
14、为项目替换发布证书和描述文件后,打包一直报错的问题
In Xcode Preferences
- > In Accounts click on your Apple ID
- > Click View Details
- > Click on your projects Provisioning Profile
- > Click refresh button bottom left
15、tabBar的代理默认就是tabBarViewController
若用代码再去设置tabBar的代理是tabBarViewController,运行就会报错。
错误信息:Changing the delegate of a tab bar managed by a tab bar controller is not allowed.
16、.gitignore文件的使用
例如:忽略所有的.DS_Store文件。
参考链接:http://www.cnblogs.com/haiq/archive/2012/12/26/2833746.html
17、在github更新自己fork的代码
参考链接:http://www.360doc.com/content/13/1217/22/14570841_338006038.shtml
18、打开car文件的方法
1、http://joaoa.com/ThemeEngine/
2、https://github.com/devcxm/iOS-Images-Extractor
19、LaunchImage的一个错误解决方案。
项目适配iOS7或之前时,Xcode会警告,要求在Images.xcassets使用LaunchImage。删除Launch Screen.xib,在Images.xcassets添加LaunchImage之后。下方第二张图,选中的地方会出现LaunchImage选项,此时如果删除Images.xcassets包含的LaunchImage,重新使用Launch Screen.xib时,运行就会报错,即下面第一张图。然后在第二张图里面删除LaunchImage选项即可解决。
20、关于idfa
从2月初开始,Apple开始拒绝采集IDFA(identifier for advertising)而未集成任何广告服务的应用进入AppStore。所以无广告应用在使用友盟等第三方时,需要使用不采集idfa版本SDK。关于应用提交时,idfa选项的解释,参考链接:http://bbs.umeng.com/thread-6242-1-1.html
21、真机调试无法运行的一个问题
下图的情况是因为,当前工程的开发证书和以前调试此工程使用的证书不一致。解决方法:把手机上面以前调试留下的应用删除即可。
22、automaticallyAdjustsScrollViewInsets
在UIViewController的view上面add自定义tableview及各种UIView时。界面切换中,tableView的UITableViewWrapperView莫名其妙移动。原因是UIViewController的automaticallyAdjustsScrollViewInsets属性默认是YES,改为NO,即可。
23、modal相关的一个问题
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion NS_AVAILABLE_IOS(5_0); // 调用次方法的时候,调用者控制器,必须要viewDidAppear。否则编译器会打印警告。 /* 2015-09-02 16:07:23.541 openBridge[11650:3375584] Presenting view controllers on detached view controllers is discouraged <HMCHomeViewController: 0x15f615500>. 2015-09-02 16:07:23.597 openBridge[11650:3375584] Unbalanced calls to begin/end appearance transitions for <HMCTabBarController: 0x15f511320>. */
24、navgationBar颜色和状态栏字体颜色的设置
项目结构,UITabBarController -> UINavigationController -> UIViewController。在给childVc包装UINavigationController时,用下面代码可以更改所有导航栏的颜色。
[childVc.navigationController.navigationBar setBarTintColor:HMCBaseColor];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
电池栏颜色设置方案二、
- (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; } // 1、在外面包裹了导航控制器的控制器里,重写此方法不会被调用。除非自定义导航栏,不用系统导航栏。 self.navigationController.navigationBarHidden = YES; // 2、当包裹了导航控制器的控制器里,并且要使用系统导航栏时,可以用下句代码实现效果 self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
25、开发证书相关
1》遵守协议UIScrollViewDelegate 2》实现代理方法 - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { // 记录滑动结束时的位置 self.contentInset = scrollView.contentInset; } 3》刷新后,设置位置 self.tableView.contentInset = self.contentInset;
28、在系统版本低的设备调试,使用高系统版本的方法时,无警告。
// 例:此方法8.0之后才有,用Xcode7,在7.0的设备调试时不报错。但是alert创建后即变为空。 UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];