iOS开发PCH文件、NSLog真机不打印
最后更新于:2022-04-01 09:45:41
### 添加PCH文件
现在Xcode6、7创建一个新的工程时将默认不会再带有PCH文件,需要手动添加PCH文件。
1. 在Supporting Files目录下,选择 File > New > File > iOS > Other > PCH File 然后点击下一步进行命名,建议命名格式为项目名称-Prefix,如图Demo
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-01_56d55db8191d0.jpg)
2. 创建的PCH文件与编译器Xcode进行连接:找到 Project > Build Settings > 搜索 “Prefix Header“;
3. 在Apple LLVM X.0 -Language栏目中能够找到Prefix Header,双击之后添加该PCH文件地址,如图所示:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-01_56d55db82e5c3.jpg)
这样Xcode6、7的PCH文件就能够顺利加到工程中去了。
### NSLog函数真机不打印
在实际项目中NSLog函数打印信息是必不可少的事情,可以友好的帮助我们调试程序,然而在模拟器上占用的是电脑的内存,但在真机上线时如果不把NSLog函数屏蔽掉,势必会造成内存的占用,性能的减弱,这对做一款优秀的App的出发点是十分违背的,所以在真机中借助PCH设置全局变量不打印NSLog函数是实战项目中必不可少的要求。
在刚才建立的PCH中对NSLog进行改造:
~~~
#ifdef DEBUG
#define DLog(fmt, ...) NSLog((@"[文件名:%s]\n" "[函数名:%s]\n" "[行号:%d] \n" fmt), __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__);
#define DeBugLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#define NSLog(...) NSLog(__VA_ARGS__);
#define MyNSLog(FORMAT, ...) fprintf(stderr,"[%s]:[line %d行] %s\n",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#else
#define DLog(...)
#define DeBugLog(...)
#define NSLog(...)
#define MyNSLog(FORMAT, ...) nil
#endif
~~~
* 1) VA_ARGS 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的”,”去掉的作用,否则会编译出错, 你可以试试。
* 2) FILE 宏在预编译时会替换成当前的源文件名
* 3) LINE宏在预编译时会替换成当前的行号
* 4) FUNCTION宏在预编译时会替换成当前的函数名称
### OK了,测试一下吧!真机与模拟的互相切换
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-01_56d55db846008.jpg)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-01_56d55db869b25.jpg)
iOS工具篇–CocoaPods
最后更新于:2022-04-01 09:45:38
> iOS开发过程中有好多第三方框架,十分便捷与开发者用最少的代码完成最优秀的App,一个上线的项目差不多得用到很多的框架,如果我们一个一个进行添加,则显得特别的慢,慢不是重点,重点是还容易出错,例如加载高德地图的框架特别复杂的环境适配,一步出错就会出现不知名的怪错误。所以一个shell命令编辑器就呼之欲出—CocoaPods
### 搭建ruby环境
注意:2015年Apple公司推出了iOS9,用https更替了http协议,所以可能您看到其他资料的CocoaPods并不能进行顺利安装,所以我写的这篇完全适配于新的环境。
* 打开终端,输入安装ruby命令
$gem sources –add [https://ruby.taobao.org/](https://ruby.taobao.org/) –remove [https://rubygems.org/](https://rubygems.org/)
* 过几分钟后 查看安装是否成功
$ gem sources -l
* 如果出现下面这样字样就说明安装ruby环境成功了
**CURRENT SOURCES**
[http://ruby.taobao.org/](http://ruby.taobao.org/)
### 环境搭建好后最后一步安装CocoaPods
~~~
$ sudo gem install cocoapods
~~~
### 使用CocoaPods
#### 1.找到创建工程的文件位置
~~~
cd到 目标工程
~~~
#### 2.创建Podfile文件
可以用Xcode创建也可以用shell命令行创建(推荐用命令行创建)
~~~
1.创建Podfile:
touch Podfile
2.编辑Podfile内容如下://以高德地图为例
platform :ios, '7.0' #手机的系统//完全不用加这一行也行,不加这一行会适配到4.3的系统,建议还是加上吧,现在已经不会再适配7.0以下的了
pod 'AMap3DMap' #3D地图SDK
#pod 'AMap2DMap' #2D地图SDK (2D和3D不能同时使⽤用)
pod 'AMapSearch' #搜索服务SDK
~~~
#### 3.输入:wq进行保存
#### 4.安装第三方框架
~~~
pod install
~~~
如果已经安装需要更新
~~~
pod update
~~~
### 安装成功之后会出现
~~~
localhost:yourWorkDir yourUserName$ pod install
Analyzing dependencies
Downloading dependencies
Installing AMap3DMap(2.4.0)
Installing AMapSearch (2.4.0)
Generating Pods project
Integrating client project !
[!] From now on use `yourProj.xcworkspace`.
~~~
本人在不同的电脑上使用CocoaPods发现使用pod install命令时会出现
~~~
Updating local specs repositories
~~~
卡了几分钟没有进展,原因是因为我们的电脑没有翻墙
所以第三步中如果你的电脑没翻墙可以换成
~~~
pod install --verbose --no-repo-update
~~~
这样就666的运行了
iOS 开始页面实现
最后更新于:2022-04-01 09:45:36
**我们从AppStore里面下载软件的时候,当我们第一次打开的时候总会有一个内容介绍页面(如下图我之前做的这个项目的丑陋的介绍页,卧槽,Boss说漂亮,真TMD怀疑他的审美!哎,创业公司,众多不易),随后再打开就没有了,下面我就给大家分享一下怎样实现该功能**
![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-01_56d55db7efa1a.jpg "")
其实实现的原理很简单,就是本地沙盒保存的版本号跟Info.plist文件里面的版本号进行对比,不一致就说明新安装的或者更新了新版本。此时就应该显示新的版本介绍页了。
好啦,原理说了下面就上代码啦!
~~~
id key = (id)kCFBundleVersionKey;
// 检测是否第一次使用这个版本
NSDictionary *info = [NSBundle mainBundle].infoDictionary;
// 获取当前软件的版本号
NSString *currentVersion = [info objectForKey:key];
// 从沙盒中取出版本号
NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
NSString *saveVersion = [defaults objectForKey:key];
if ([currentVersion isEqualToString:saveVersion]) {
self.window.rootViewController=_MainTabbar;
NSLog(@"不是第一次呀");
}
else
{
[defaults setObject:currentVersion forKey:key];
[defaults synchronize];
NSLog(@"第一次");
UserGuideViewView *user=[[UserGuideViewView alloc]init];
user.delegate=self;
self.window.rootViewController=user;
}
~~~
**是不是很简单呀,恩恩,简单但基本上每个App都要用到的!谢谢!讲解完毕了,请鼓掌吧!**
更新Xcode插件不能用啦
最后更新于:2022-04-01 09:45:34
**每次大家更新完Xcode,是不是发现之前装的插件不能用啦?**
是的!每当Xcode升级之后,都会导致原有的Xcode插件不能使用,这是因为每个插件的Info.plist中记录了该插件兼容的Xcode版本的DVTPlugInCompatibilityUUID,而每个版本的Xcode的DVTPlugInCompatibilityUUID都是不同的。如果想让原来的插件继续工作,我们就得将新版Xcode的DVTPlugInCompatibilityUUID加入到每一个插件的Info文件中,手动添加的话比较费时间还可能出错,所以我写了一个脚本来做这件事。
1.下载refreshPluginsAfterXcodeUpgrading.sh
2.运行 ‘./refreshPluginsAfterXcodeUpgrading.sh’
3.重启Xcode
如果出现这个对话框
![点击 Skip Bunles](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-01_56d55db7ce858.jpg "")
点击 Skip Bunles即可!
哈哈,又可以开心方便的敲代码啦吧?*
最后附上这个脚本下载地址:
[http://download.csdn.net/detail/it_ds/9361011](http://download.csdn.net/detail/it_ds/9361011)
不谢,为人民服务!如果帮你解决问题啦,帮忙正下方点个赞呗!
iOS开发者们如何获取设备型号
最后更新于:2022-04-01 09:45:32
**截止目前,苹果除了很多设备了。iOS开发者们如何获取设备?**
导入头文件
~~~
#include <sys/types.h>
#include <sys/sysctl.h>
~~~
直接调用
~~~
//获得设备型号
+ (NSString *)getCurrentDeviceModel:(UIViewController *)controller
{
int mib[2];
size_t len;
char *machine;
mib[0] = CTL_HW;
mib[1] = HW_MACHINE;
sysctl(mib, 2, NULL, &len, NULL, 0);
machine = malloc(len);
sysctl(mib, 2, machine, &len, NULL, 0);
NSString *platform = [NSString stringWithCString:machine encoding:NSASCIIStringEncoding];
free(machine);
if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 2G (A1203)";
if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G (A1241/A1324)";
if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS (A1303/A1325)";
if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4 (A1332)";
if ([platform isEqualToString:@"iPhone3,2"]) return @"iPhone 4 (A1332)";
if ([platform isEqualToString:@"iPhone3,3"]) return @"iPhone 4 (A1349)";
if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S (A1387/A1431)";
if ([platform isEqualToString:@"iPhone5,1"]) return @"iPhone 5 (A1428)";
if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5 (A1429/A1442)";
if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5c (A1456/A1532)";
if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5c (A1507/A1516/A1526/A1529)";
if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5s (A1453/A1533)";
if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5s (A1457/A1518/A1528/A1530)";
if ([platform isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus (A1522/A1524)";
if ([platform isEqualToString:@"iPhone7,2"]) return @"iPhone 6 (A1549/A1586)";
if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G (A1213)";
if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G (A1288)";
if ([platform isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G (A1318)";
if ([platform isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G (A1367)";
if ([platform isEqualToString:@"iPod5,1"]) return @"iPod Touch 5G (A1421/A1509)";
if ([platform isEqualToString:@"iPad1,1"]) return @"iPad 1G (A1219/A1337)";
if ([platform isEqualToString:@"iPad2,1"]) return @"iPad 2 (A1395)";
if ([platform isEqualToString:@"iPad2,2"]) return @"iPad 2 (A1396)";
if ([platform isEqualToString:@"iPad2,3"]) return @"iPad 2 (A1397)";
if ([platform isEqualToString:@"iPad2,4"]) return @"iPad 2 (A1395+New Chip)";
if ([platform isEqualToString:@"iPad2,5"]) return @"iPad Mini 1G (A1432)";
if ([platform isEqualToString:@"iPad2,6"]) return @"iPad Mini 1G (A1454)";
if ([platform isEqualToString:@"iPad2,7"]) return @"iPad Mini 1G (A1455)";
if ([platform isEqualToString:@"iPad3,1"]) return @"iPad 3 (A1416)";
if ([platform isEqualToString:@"iPad3,2"]) return @"iPad 3 (A1403)";
if ([platform isEqualToString:@"iPad3,3"]) return @"iPad 3 (A1430)";
if ([platform isEqualToString:@"iPad3,4"]) return @"iPad 4 (A1458)";
if ([platform isEqualToString:@"iPad3,5"]) return @"iPad 4 (A1459)";
if ([platform isEqualToString:@"iPad3,6"]) return @"iPad 4 (A1460)";
if ([platform isEqualToString:@"iPad4,1"]) return @"iPad Air (A1474)";
if ([platform isEqualToString:@"iPad4,2"]) return @"iPad Air (A1475)";
if ([platform isEqualToString:@"iPad4,3"]) return @"iPad Air (A1476)";
if ([platform isEqualToString:@"iPad4,4"]) return @"iPad Mini 2G (A1489)";
if ([platform isEqualToString:@"iPad4,5"]) return @"iPad Mini 2G (A1490)";
if ([platform isEqualToString:@"iPad4,6"]) return @"iPad Mini 2G (A1491)";
if ([platform isEqualToString:@"i386"]) return @"iPhone Simulator";
if ([platform isEqualToString:@"x86_64"]) return @"iPhone Simulator";
return platform;
}
~~~
iOS MD5加密
最后更新于:2022-04-01 09:45:29
哈哈!先上理论篇:
MD5的典型应用是对一段信息(Message)产生信息摘要(Message-Digest),以防止被篡改。比如,在UNIX下有很多软件在下载的时候都有一个文件名相同,文件扩展名为.md5的文件,在这个文件中通常只有一行文本,大致结构如:
` MD5 (tanajiya.tar.gz) = 0ca175b9c0f726a831d895e269332461 `
这就是tanajiya.tar.gz文件的数字签名。MD5将整个文件当作一个大文本信息,通过其不可逆的字符串变换算法,产生了这个唯一的MD5信息摘要。为了让读者朋友对MD5的应用有个直观的认识,笔者以一个比方和一个实例来简要描述一下其工作过程:
大家都知道,地球上任何人都有自己独一无二的指纹,这常常成为公安机关鉴别罪犯身份最值得信赖的方法;与之类似,MD5就可以为任何文件(不管其大小、格式、数量)产生一个同样独一无二的“数字指纹”,如果任何人对文件名做了任何改动,其MD5值也就是对应的“数字指纹”都会发生变化。
我们常常在某些软件下载站点的某软件信息中看到其MD5值,它的作用就在于我们可以在下载该软件后,对下载回来的文件用专门的软件(如Windows MD5 Check等)做一次MD5校验,以确保我们获得的文件与该站点提供的文件为同一文件。利用MD5算法来进行文件校验的方案被大量应用到软件下载站、论坛数据库、系统文件安全等方面。
MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹),以防止被“篡改”。举个例子,你将一段话写在一个叫readme.txt文件中,并对这个readme.txt产生一个MD5的值并记录在案,然后你可以传播这个文件给别人,别人如果修改了文件中的任何内容,你对这个文件重新计算MD5时就会发现(两个MD5值不相同)。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的“抵赖”,这就是所谓的数字签名应用。
MD5还广泛用于操作系统的登陆认证上,如Unix、各类BSD系统登录密码、数字签名等诸多方。如在UNIX系统中用户的密码是以MD5(或其它类似的算法)经Hash运算后存储在文件系统中。当用户登录的时候,系统把用户输入的密码进行MD5Hash运算,然后再去和保存在文件系统中的MD5值进行比较,进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。这可以避免用户的密码被具有系统管理员权限的用户知道。MD5将任意长度的“字节串”映射为一个128bit的大整数,并且是通过该128bit反推原始字符串是困难的,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。所以,要遇到了md5密码的问题,比较好的办法是:你可以用这个系统中的md5()函数重新设一个密码,如admin,把生成的一串密码的Hash值覆盖原来的Hash值就行了。
正是因为这个原因,现在被黑客使用最多的一种破译密码的方法就是一种被称为”跑字典”的方法。有两种方法得到字典,一种是日常搜集的用做密码的字符串表,另一种是用排列组合方法生成的,先用MD5程序计算出这些字典项的MD5值,然后再用目标的MD5值在这个字典中检索。我们假设密码的最大长度为8位字节(8Bytes),同时密码只能是字母和数字,共26+26+10=62个字符,排列组合出的字典的项数则是P(62,1)+P(62,2)….+P(62,8),那也已经是一个很天文的数字了,存储这个字典就需要TB级的磁盘阵列,而且这种方法还有一个前提,就是能获得目标账户的密码MD5值的情况下才可以。这种加密技术被广泛的应用于UNIX系统中,这也是为什么UNIX系统比一般操作系统更为坚固一个重要原因。
然并卵,理论那么多,实践就几行代码!
先加上类库的头文件
再封装一个带参数的函数
~~~
+(NSString *) md5: (NSString *) inPutText
{
const char *cStr = [inPutText UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5(cStr, strlen(cStr), result);
return [[NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
] lowercaseString];
}
~~~
最后再调用一下!
` NSLog(@”%@”,[ViewController md5:@”123”]); `
OK,这样一个煎蛋的MD5加密就好啦!
分享一个在线MD5网站:[http://md5jiami.51240.com](http://md5jiami.51240.com)可以验证一下自己解密到的是否正确
**注意:MD5有一个法则,同样的一个数据,每次加密的结果是一样,所以安全系数高的软件还要进行加盐,这个面试估计要问到**
iOS 开发之全局特性设置
最后更新于:2022-04-01 09:45:27
大家有没有发现???发现什么呢?What?
在平常用的App中,每一页的导航栏的颜色和字体都是一样的,有些是背景图片,有些是通过UIColor设置的颜色背景,本人在以前开发中,每次都在每个页面写一次导航栏的背景。唉~,不要笑话me(大神请绕道)
好啦,废话不多说,说重点,其实我们可以在AppDelegate中设置全局导航栏的颜色和字体颜色 ,这样的设置使我们一劳永逸!`//设置导航栏文字颜色
~~~
[[UINavigationBar appearance] setTintColor:[UIColor colorWithRed:0.37 green:0.41f blue:0.48f alpha:1.0f]];
//设置导航栏背景图片
[[UINavigationBar appearance] setBackgroundImage:@"导航栏背景图片.png" forBarMetrics:UIBarMetricsDefault];
~~~
iOS 算法之:阿拉伯数字转化为汉语数字
最后更新于:2022-04-01 09:45:25
**阿拉伯数字转化为汉语数字**
~~~
+(NSString *)translation:(NSString *)arebic
{ NSString *str = arebic;
NSArray *arabic_numerals = @[@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"0"];
NSArray *chinese_numerals = @[@"一",@"二",@"三",@"四",@"五",@"六",@"七",@"八",@"九",@"零"];
NSArray *digits = @[@"个",@"十",@"百",@"千",@"万",@"十",@"百",@"千",@"亿",@"十",@"百",@"千",@"兆"];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:chinese_numerals forKeys:arabic_numerals];
NSMutableArray *sums = [NSMutableArray array];
for (int i = 0; i < str.length; i ++) {
NSString *substr = [str substringWithRange:NSMakeRange(i, 1)];
NSString *a = [dictionary objectForKey:substr];
NSString *b = digits[str.length -i-1];
NSString *sum = [a stringByAppendingString:b];
if ([a isEqualToString:chinese_numerals[9]])
{
if([b isEqualToString:digits[4]] || [b isEqualToString:digits[8]])
{
sum = b;
if ([[sums lastObject] isEqualToString:chinese_numerals[9]])
{
[sums removeLastObject];
}
}else
{
sum = chinese_numerals[9];
}
if ([[sums lastObject] isEqualToString:sum])
{
continue;
}
}
[sums addObject:sum];
}
NSString *sumStr = [sums componentsJoinedByString:@""];
NSString *chinese = [sumStr substringToIndex:sumStr.length-1];
NSLog(@"%@",str);
NSLog(@"%@",chinese);
return chinese;
}
~~~
UIViewController
最后更新于:2022-04-01 09:45:22
UIViewController在UIKit中主要功能是用于控制画面的切换,其中的view属性(UIView类型)管理整个画面的外观.大部分控制器类都会继承UIKit的UIViewController基类,该基类中包含了大量方法,可以重写这些方法来处理视图的加载、视图显示等各种事件。
包括以下常见的重要重写方法:
~~~
- (void)viewDidLoad {
[super viewDidLoad];
//当控制器管理的视图被装载完成后,调用该方法,如果开发者需要在视图装载完成后执行某些代码,即可通过重写该方法完成。重写该方法时不要忘记通过[super ViewDidLoad];代码来调用UIViewController基类的viewDidLoad方法;
}
-(void)viewWillAppear:(BOOL)animated
{
//当该控制器管理的视图将要显示出来时,系统会自动的调用该方法,如果开发者需要在视图将要显示出来的时候执行某些代码,即可通过重写该方法来完成。重写该方法时不要忘记通过[super viewWillAppear:YES];代码来调用UIViewController基类的viewWillAppear:方法;
}
-(void)viewDidAppear:(BOOL)animated
{
//当该控制器管理的视图显示出来时,系统会自动的调用该方法,如果开发者需要在视图显示出来后执行某些代码,即可通过重写该方法来完成。重写该方法时不要忘记通过[super viewDidAppear:YES];代码来调用UIViewController基类的viewDidAppear:方法;
}
-(void)viewWillDisappear:(BOOL)animated
{//当该控制器管理的视图将要隐藏或将要被移除窗口时,系统会自动的调用该方法,如果开发者需要在视图将要隐藏或将要被移除窗口时执行某些代码,即可通过重写该方法来完成。重写该方法时不要忘记通过[super viewWillDisappear:YES];代码来调用UIViewController基类的viewWillDisappear:方法;
}
-(void)viewDidDisappear:(BOOL)animated
{
//当该控制器管理的视图被隐藏或移除窗口时,系统会自动的调用该方法,如果开发者需要在视图被隐藏或移除窗口的时候执行某些代码,即可通过重写该方法来完成。重写该方法时不要忘记通过[super viewDidDisappear:YES];代码来调用UIViewController基类的viewDidDisappear:方法;
}
-(void)viewDidLayoutSubviews
{
//当该控制器管理的视图把它包含的所有子视图排列完成后,系统会自动的调用该方法,如果开发者需要在它包含的所有子视图排列完成后的时候执行某些代码,即可通过重写该方法来完成。重写该方法时不要忘记通过[super viewDidLayoutSubviews];代码来调用UIViewController基类的viewDidLayoutSubviews方法;
}
-(void)viewWillLayoutSubviews
{
//当该控制器管理的视图将要把它包含的所有子视图排列完成后,系统会自动的调用该方法,如果开发者需要在视图将要把它包含的所有子视图排列完成后,即可通过重写该方法来完成。重写该方法时不要忘记通过[super viewWillLayoutSubviews];代码来调用UIViewController基类的viewWillLayoutSubviews方法;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
//内存不足时调用的方法,开发者可在需要时释放一些暂不会使用的对象,进而释放内存(基本上我都没用过这个方法)
}
~~~
ios项目常用模板框架之UITabBar+Nav
最后更新于:2022-04-01 09:45:20
在实际的项目开发中总是有几个比较常见的模板,小编这几天给大伙出几期常用模板的博客,希望大家多提宝贵的意见!
这几个月最常用的莫过于Nav+UITabBar模板了;在实际的项目中,我比较侧重于纯代码,比较不喜欢拖控件,至于利弊在这里不多说了,言归正传。
首先在AppDelegate.m中创建一个空白布景:
~~~
self.window=[[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
初始化UITabBarController
self.tabBarController=[[UITabBarController alloc]init];
~~~
创建两个视图控制器:
~~~
FirstViewController *one=[[FirstViewController alloc]init];
SecondViewController *second=[[SecondViewController alloc]init];
~~~
创建两个导航控制器并 让这两个导航控制器控制好各自的视图控制器:
~~~
UINavigationController *navFirst=[[UINavigationController alloc]initWithRootViewController:one];
UINavigationController *navSecond=[[UINavigationController alloc]initWithRootViewController:second];
~~~
让tabBarController包含这两个导航控制器:
~~~
[self.tabBarController addChildViewController:navFirst];
[self.tabBarController addChildViewController:navSecond];
~~~
对各自的视图控制器进行细腻化的定制:
~~~
one.title=@”联系人”;
one.tabBarItem=[[UITabBarItem alloc]initWithTitle:@”one” image:[UIImage imageNamed:@”“]
selectedImage:nil];
second.title=@”收藏”;
second.tabBarItem=[[UITabBarItem alloc]initWithTitle:@”second” image:nil selectedImage:nil];
~~~
设置改空白布景上的主视图为:tabBarController:
` [self.tabBarController addChildViewController:navSecond]; `
修改布景为红色:
`self.window.backgroundColor=[UIColor redColor]; `
显示布景:
` [self.window makeKeyAndVisible]; `
在FirstViewController中创建二级页面
创建导航栏:
`UIBarButtonItem *rightButton=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:@selector(selectRightAction:) ]; `
实现跳转方法:
~~~
-(void)selectRightAction:(id)sender
{
BackViewController *backButton;
backButton=[[BackViewController alloc]initWithNibName:@"BackViewController" bundle:nil];
backButton.title=@"第二视图层";
[self.navigationController pushViewController:backButton animated:NO];
}
~~~
代码示例下载地址:[http://download.csdn.net/detail/it_ds/8568545](http://download.csdn.net/detail/it_ds/8568545)
ios字体设置
最后更新于:2022-04-01 09:45:18
我们在日常的项目开发中,经常需要为某些字体进行个性化的设置,改变字体的风格:所以就引入了UIFont来设置字体
经常用到是UIFont的一个类函数:
`+fontWithName:(NSString *)fontName size:(CGFloat) fontSize `
创建并且返回一个指定字体类型和大小的字体对象,fontName指定字体集的名字和风格(例如宋体,楷书等这一类型的),fontsize设置字体的大小。
例如:
~~~
_Label = [[UILabel alloc] initWithFrame:CGRectMake(95, 120, 185, 50)];
_Label.text = @"图灵工作室";
[_Label setFont:[UIFont fontWithName:@"Helvetica" size:37.0]];
~~~
字体类型名字如下:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-01_56d55db79566f.jpg)
xcode6.0.1创建空工程/Empty Application
最后更新于:2022-04-01 09:45:16
大家会发现在xcode6中找不到创建空工程的图标了,对于用惯了空工程来说,使用单视图界面会不习惯,甚至不会,接下来将告诉大家如何在xcode6.0.1中创建空工程。
之前版本Xcode创建应用的选项有
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-01_56d55db6bd485.jpg)
Xcode6.0.1就没了这个选项
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-01_56d55db6d2273.jpg)
用single view Application是不是觉得很不好用呢。
下面是解决方法。
首先创建个Single View Application
删除Main.storyboard, LaunchScreen.xib根据自己需要选择是否删除!
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-01_56d55db6e861a.jpg)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-01_56d55db73a540.jpg)
如果ViewController不用也可以顺手删掉了
接下来找到info.plist 删掉Main storyboard file base name这个选项
注意:如果你之前有删除掉LaunchScreen.xib,请将 Launch screen interface file base name 这个选项的内容置空!记得不要删除这个key,不然超过3.5inch的设备会出现上下黑边的情况!
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-01_56d55db753be1.jpg)
然后回到AppDelegate.m的
~~~
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions的方法内创建就可以了
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
ViewController *viewcontroller = [[ViewController alloc]init];
self.window.rootViewController = viewcontroller;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
// Override point for customization after application launch.
return YES;
}
~~~
如果有报错,记得看下是否有导入对应的视图控制器的头文件!
这样就可以开始使用空工程咯~~~~
**当然啦,你觉得第一种方法每次搭建太麻烦了,可以一劳永逸的办法!!!**
这里有一个包,http://download.csdn.net/detail/it_ds/9387057
下载之后把安装包放到到目录{Xcode.app}下的/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/Project Templates/iOS/Application/ 中
这样每次打开XCode后都能看到如下的空工程啦!![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-01_56d55db76eb37.jpg)
UITableView基础(一)
最后更新于:2022-04-01 09:45:13
hello 大家又见面啦,今天小编给大家讲解一下UITableView,这一块知识在我们实际项目中是最为常见的,是ios项目的根骨所在,希望大家能够足够重视,所以小编准备分几次内容给大家一一解析其中的难点,下面是最基础的内容,希望大家能有所收获。
~~~
import <UIKit/UIKit.h>
@interface ViewController : UIViewController<UITableViewDataSource>
//绑定tableView控件,定义变量,方便对控件的代码操作
@property (strong, nonatomic) IBOutlet UITableView *table;
//为tableView上显示数据定义两个变量
@property(nonatomic,strong)NSArray *community;
@property(nonatomic,strong)NSArray *details;
@end
~~~
~~~
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
@synthesize details;
@synthesize community;
- (void)viewDidLoad {
[super viewDidLoad];
//对定义的两个变量赋予初始值
community=[NSArray arrayWithObjects:@"图灵工作社",@"梦翔工作社",@"南工电脑网",@"锋芒工作社", nil];
details=[NSArray arrayWithObjects:@"图灵最牛,挤压群熊",@"不错的社团",@"不错的社团",@"不错的社团", nil];
self.table.dataSource=self;
//添加页眉和页脚,在这里小编分别加载的是图片
self.table.tableHeaderView=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"001.jpg"]];
self.table.tableFooterView=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"001.jpg"]];
}
//UITableView协议里面的方法,对每个UITableCell进行定制和写入内容
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellId=@"cellId";//静态NSString类型,目的是可以重用能添加UITaleCell到重用表格中,和方便从重用表格中调取。
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellId];
if (cell==nil) {//第一次没有表格行(UITableCell)时,定制表格行
switch (indexPath.row%4) {
case 0:
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];//第一种UITableCell风格
break;
case 1:
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];//第二种UITableCell风格
break;
case 2:
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellId];//第三种UITableCell风格
break;
case 3:
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:cellId];//第四种UITableCell风格
break;
<span style="color:#ff0000;">//注意看下下边的图片,比较这四种UITableCell的不同点!!!</span>
}
}
NSUInteger rowNo=indexPath.row;//调取每行UITableCell的索引进行付于初值
cell.textLabel.text=[community objectAtIndex:rowNo];
cell.imageView.image=[UIImage imageNamed:@"001.jpg"];
cell.imageView.highlightedImage=[UIImage imageNamed:@"001.jpg"];
cell.detailTextLabel.text=[details objectAtIndex:rowNo];
return cell;
}
//UIDataSource协议里面的第二个方法:目的告诉系统一个分区里面有多少个表格行(注意是一个分区,不一定是总共有多少表格行)
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return community.count;
}
//UIDataSource协议里面的第二个方法:目的告诉系统有几个分区(几块表格)显然这里返回的是一个分区表格
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
~~~
运行结果如下:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-01_56d55db630874.jpg)
怎么样,这点简单的知识掌握了没有啊?大家要愉快的学习,发觉编程的乐趣,提高自己的效率!后续马上给大家讲解深层次的UITableView知识,希望小编的这点微薄知识能帮到你们!![微笑](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-18_569ca449c5105.gif)
![再见](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-25_56a5a366e5bcb.gif)
![再见](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-25_56a5a366e5bcb.gif)
![再见](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-25_56a5a366e5bcb.gif)
ios学习路线
最后更新于:2022-04-01 09:45:11
首先恭喜你非常有眼光的学习ios开发,面对iphone6手机的全球追捧,以及苹果市值即将破万亿大关的趋势,越来越多的开发者加入了ios开发的潮流中,想在国际浪潮中分得一桶金来!
可能有好多同志对怎样学好ios有所苦恼,今天小编撸了几千行代码,着实无力继续敲下去。特意跟大家分享下学习经验。
首先是经济准备:mac电脑一台,iPhone或者ipad一部(嘿嘿!条件要求蛮高滴,让大部分程序员忘而止步,导致精通ios的人数和质量不高,物以稀为贵,ios工程师就是这个高端,就是这么有钱,就是这么任性)当然经济不允许可以安装黑苹果。(小编我会在以后的日子里教大家安装黑苹果,关注我呦!)
其次得有一颗淡定的心,耐得住寂寞,经得起诱惑,学习并非一朝一夕,一定要有持之以恒的心,冰冻三尺非一日之寒。
好啦,言归正传,扯入正题:
学习ios之前最好学习一下C语言,有了扎实的C语言基础,上手ios开发将不会觉得太过吃力,学习其他语言也容易了许多,之后小编觉得看几天ios的视频,对ios有个大致的概念,接着选择一本适合自己的ios工具书(适合自己的,才是最好的),小编当年学习用的时《疯狂ios讲义》赶脚蛮棒的!
下面分三块学习步骤:ios基础(基础视图,高级视图多控制器管理,MVC、KVC、KVO模式,代理模式,简单通知机制,键盘处理)
ios中级编程(触摸事件、手势处理、多媒体开发、手机本地系统服务、多线程技术、地图应用开发)
ios高级编程(ios数据库开发、推送机制、网络编程)
小编建议在学习高级编程之前最好学习一些数据库知识,对Mysql基础知识要掌握牢固,否则学习学习ios数据库就会变的一头雾水(想想我当年),学习基础的时候要多敲一敲,实践是检验真理的唯一标准!
在此跟大家推荐几个不错的网站:CSDN、cocoachina、code4app等等。多看看别人的技术博客,是提高自己的好方法。有英语条件的提倡学习一些外国文档。感觉自己的基础打好了可以做一些小的项目(嘿嘿!在项目中你会发现自己的基础还是不牢固,正常现象),借此提高自己。学习最重要的是要有耐心!最后跟搭建分享一下导师当年对我讲的一个小故事一次做结尾。
同是一块石头,一半做成了佛,一半做成了台阶。一天,台阶不服气的问佛:"我们本是一块石头,凭什么人们都踩着我,而去朝拜你呢?"佛说:"因为你只挨了一刀,而我经历了千刀万割。人生也是如此,经得起打磨,耐得起寂寞,扛得起责任,肩负起使命!人生才会有价值!
注:欢迎大家关注我的博客,欢迎大家给我留言。后续给大家呈上ios基础知识讲解。你们的支持是小编不竭的动力。
新浪博客:http://weibo.com/u/5173549257/home?wvr=5
南阳理工软件学院
图灵工作室
2014/11/30
前言
最后更新于:2022-04-01 09:45:09
> 原文出处:[iOS开发进阶](http://blog.csdn.net/column/details/iosdevelopment001.html)
作者:[it_ds](http://blog.csdn.net/it_ds)
**本系列文章经作者授权在看云整理发布,未经作者允许,请勿转载!**
# iOS开发进阶
> 主要分享一些iOS开发中一些中上级别的技术、外国译文、项目实战。