赞
踩
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NSArrayController的使用
1.在File’s Owner中創建NSMutableArray
2.拖NSArrayController到Object的列表
3.設置Attributes inspector->Object Controller, Mode選擇Class, Class Name填寫次array中object的類名字, 在 Keys中添加Object中需要現實的變量名字
4.在Binding inspector中,Controller Content點選設置Bind to,在Model Key Path中填入1中Array的名字
5.拖NSTableView到nib中,點選table的一列,在Binding inspector->Value中點擊設置Bind to,
Controller Key設置為arrangedObjects, Model Key Path設置3步中的Object變量名字
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
数据宽度 (%d最大表示4个byte的数据量)
int b=0x10203040;
NSLog(@"%x",b); //%x最多表示4byte
int c=0xFFFFFFFF;
NSLog(@"%ud",c); //%ud unsigned decimal
long a = 0x1020304050607080;
NSLog(@"%lx",a); //%lx可表示多达8个byte
unsigned long a = 0xFFFFFFFFFFFFFFFF;
NSLog(@"%lu",a); //%lx可表示多达8个byte lu表示long unisigned数据
NSLog(@"%lu",sizeof(char)); //1 byte
NSLog(@"%lu",sizeof(short)); //2 byte
NSLog(@"%lu",sizeof(int)); //4 byte
NSLog(@"%lu",sizeof(long)); //8 byte
NSLog(@"%lu",sizeof(long long));//8 byte
NSLog(@"%lu",sizeof(float));//4 byte
NSLog(@"%lu",sizeof(double));//8 byte
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
将CGPoint数据保存到NSArray中
[array addObject:[]NSValue valueWithCGPoint:point];
CGPoint point=[[array objectAtIndex:index] CGPointValue];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
使用NSPopUpButton创建NSToolbar中可以下拉选择的Item方法:
1.在xib中添加NSPopUpButton控件
2.设置PopUp button的属性:
Type: Pull Down
Arrow: No Arrow
Style: Square
Visual: Not Bordered
Title: Remove, this blanks the first menu item as well
Image: 设置显示的图标
Scaling: None
以上设置完之后,调整Button的大小和图标的位置
3.添加DTPopUpButtonCell:NSPopUpButtonCell
@implementation DTPopUpButtonCell
-(void)drawImageWithFrame:(NSRect)cellFrame inView:(NSView *)controlView{
[super drawImageWithFrame:cellFrame inView:controlView];
NSRect imageBounds = [self imageRectForBounds:cellFrame];
NSBezierPath *path=[[NSBezierPath alloc]init];
[path moveToPoint:NSMakePoint(NSMaxX(imageBounds)-1, NSMaxY(imageBounds)-9)];
[path lineToPoint:NSMakePoint(NSMaxX(imageBounds)+5, NSMaxY(imageBounds)-9)];
[path lineToPoint:NSMakePoint(NSMaxX(imageBounds)+2, NSMaxY(imageBounds)-5)];
[path closePath];
[[NSColor colorWithDeviceWhite:20.0/255.0 alpha:0.9]set];
[path fill];
}
-(NSRect)imageRectForBounds:(NSRect)theRect{
NSRect rect=[super imageRectForBounds:theRect];
rect.origin.x-=5;
return rect;
}
@end
4.设置NSPopUpButtonCell的Class为DTPopUpButtonCell
5.PopUp中的每个Item都添加动作(添加方法如NSButton一样)
6.将以上popup控件放倒NSToolbar中,编译使用
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define NNSLog(FORMAT, ...) fprintf(stderr,"%s\n",[[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#ifdef DEBUG
#define NSSLog(FORMAT, ...) fprintf(stderr,"%s:%d\t%s\n",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#else
#define NSSLog(...)
#endif
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RegexKitLite使用中的ICU正则表达式
1.需导入libicucore.dylib库
2.需在target的编译设置中增加 Other Linker Flags = -licucore
看看一些基本的正则表达式的语法:
\:将下个字符标记为一个特殊的字符、一个原义字符、一个向后引用或者一个八进制转义符例如“\n”就是匹配一个换行符。
^:匹配开始位置,^(a)这个就匹配开头必须为a。
$:匹配结束位置,$(a)这个就匹配结尾必须为a。
.:匹配任意字符,除“\n”之外。
*:匹配前面的子表达式零次或者多次,如“xu*”这个表达式就能够匹配“x”和“xuu”。
+:匹配前面的子表达式一次或者多次,如“xu+”这个表达式就能够匹配“xuu”和“xu”,但不能够匹配“x”,这个就是和“*”的区别。
?:匹配前面的子表达式零次或者一次,如“xu?”这个表达式就能够匹配“jian(guo)?”就可以匹配“jian”和“jianguo”。
{n}:n是一个非负数,匹配n次,如“guo{2}”,可以匹配“guoo”,不能匹配“guo”。
{n,}:n是一个非负数,匹配至少n次。
{n, m}:m、n都是非负数,最少匹配n次,最多匹配m次。
(pattern):匹配pattern并获取匹配结果。
(?:pattern):匹配pattern但不获取匹配结果。
正则表达式中?后边可添加的参数有ixsmw, ,如果参数前加减号-,表示取消此功能。 含义分别为:
i RKLCaseless, 忽略大小写
x RKLComments, 允许在patttern中使用空白和#comment
s RKLDotAll ----- if set, a . in a pattern will match a line terminator in the input text.
m RKLMultiline, 多行匹配
w RKLUnicodeWordBoundaries ,Unicode编码字符
例如: @“(?i:Regex)”, @“(?x:Regex)”, @“(?s:Regex)”, @“(?m:Regex)”, @“(?w:Regex)”, @“(?im-w:Regex)”,
例如:@“(?i)Regex”
例如(?:ixsw-m.......), 表示使用ixsw功能,但是屏蔽m功能
x|y:匹配x或y,如“(xu|jian)guo”匹配“xuguo”或者“jianguo”。
[xyz]:字符集合,匹配所包含的任意字符。如“[abc]”可以匹配“apple”中的“a”。
[^xyz]:匹配未被包含的字符。
[a-z]:字符范围,匹配指定范围内的任意字符。
[^a-z]:匹配指定不在范围内的任意字符。
\b:匹配一个单词的边界,如“guo\b”可以匹配“xujianguo”中的“guo”。
\B:匹配非单词边界,如“jian\B”可以匹配“xujianguo”中的“jian”。
\d:匹配一个数字字符,等价于“[0-9]”。
\D:匹配一个非数字字符。
\f:匹配一个换页符。
\n:匹配一个换行符。
\r:匹配一个回车符。
\s:匹配任何空白字符
\S:匹配任何非空白字符
\w:匹配任何字类字符,包括下划线,与[A-Za-z0-9_]等效
\W:匹配任何非字类字符,与[^A-Za-z0-9_]等效
匹配中文字符的正则表达式: [\u4e00-\u9fa5]
匹配双字节字符(包括汉字在内):[^\x00-\xff]
匹配空白行的正则表达式:\n\s*\r
匹配首尾空白字符的正则表达式:^\s*|\s*$
匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
匹配网址URL的正则表达式:[a-zA-z]+://[^\s]*
匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7} 评注:匹配形式如 0511-4405222 或 021-87888822
匹配腾讯QQ号:[1-9][0-9]{4,}
匹配中国邮政编码:[1-9]\d{5}(?!\d) 评注:中国邮政编码为6位数字 --- 零宽断言,(?!\d)表示非数字的后续内容。 例如,\w+(?!\d) 表示字母后面不跟数字,且不捕获数字。
匹配身份证:\d{15}|\d{18} 评注:中国的身份证为15位或18位
匹配ip地址:\d+\.\d+\.\d+\.\d+
匹配特定数字:
^[1-9]\d*$ //匹配正整数
^-[1-9]\d*$ //匹配负整数
^-?[1-9]\d*$ //匹配整数
^[1-9]\d*|0$ //匹配非负整数(正整数 + 0)
^-[1-9]\d*|0$ //匹配非正整数(负整数 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ //匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ //匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$ //匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ //匹配非负浮点数(正浮点数 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ //匹配非正浮点数(负浮点数 + 0)
评注:处理大量数据时有用,具体应用时注意修正
匹配特定字符串:
^[A-Za-z]+$ //匹配由26个英文字母组成的字符串
^[A-Z]+$ //匹配由26个英文字母的大写组成的字符串
^[a-z]+$ //匹配由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$ //匹配由数字和26个英文字母组成的字符串
^\w+$ //匹配由数字、26个英文字母或者下划线组成的字符串
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Xcode中常用标注(swift & ObjC)
//!!!!:其它工站 结果
//MARK:版本
#pragma mark- 检测网络每3s
//TODO: 一般用于写到哪了 做个标记,让后回来继续
//FIXME: 警告
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
宏定义直接存取文件和字典
#define CloseTimeFile(num) [[NSString stringWithFormat:@"~/Library/Preferences/CloseTime_%d.plist",num]stringByExpandingTildeInPath]
#define CTDict(num) [NSMutableDictionary dictionaryWithContentsOfFile:CloseTimeFile(num)]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如何在Objective-C中定义和使用Block代码块
~~~~~~
~~~~~~
1、作为变量
//1 返回值类型 (^block的名称)(参数类型) = ^返回值类型(参数) {...};
//2 returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};
2、作为属性
//1 @property (nonatomic, copy) 返回值类型 (^block的名称)(参数类型);
//2 @property (nonatomic, copy) returnType (^blockName)(parameterTypes);
3、作为方法声明的参数
//1 - (void)方法名:(返回值类型 (^)(参数类型))block的名称;
//2 - (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName;
4、作为方法实现的参数
//1 [对象/类 方法名:^返回值类型 (参数) {...}];
//2 [someObject someMethodThatTakesABlock:^returnType (parameters) {...}];
5、作为typedef
//1 typedef 返回值类型 (^类型名称)(参数类型);
类型名称 block的名称 = ^返回值类型(参数) {...};
//2 typedef returnType (^TypeName)(parameterTypes);
TypeName blockName = ^returnType(parameters) {...};
~~~~~~
//使用示例1
double (^multiplyTwoValues)(double,double)=^double (double fv, double sv){
return fv*sv;
};
double rslt=multiplyTwoValues(60,5);
NSLog(@"%f",rslt);
~~~~~~
//使用示例2
void (^simpleBlock)(void);
simpleBlock=^{
NSLog(@"this is a block");
};
simpleBlock();
~~~~~~
//使用示例3
//BlockTest.h
#import <Cocoa/Cocoa.h>
typedef BOOL(^BlockName)(int obj); //定义Block
@interface BlockTest : NSObject
-(NSIndexSet *)getPersonInfo:(BlockName)block;
@end
//BlockTest.m
#import “BlockTest.h”
@implementation BlockTest
-(NSIndexSet *)getIndexSet:(BlockName)block{
__block NSMutableIndexSet *set=[NSMutableIndexSet indexSet];//要与外部变量沟通,需使用__block
for(int i=0; i<10; i++){//使用Block
if (block(i)) {
NSLog(@"%d add to index set",i);
[set addIndex:(NSUInteger)i];
}
}
return set;
}
@end
//使用BlockTest
NSIndexSet *tmpset = [[[BlockTest alloc]init] getIndexSet:^BOOL(int a){
if (a > 5) return YES;
return NO;
}];
[tmpset enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop){
NSLog(@"get index set : %ld", idx);
}];
~~~~~~
//使用示例4 -- C语言中的函数指针
在C语言中我们以 returntype (*name) (arg); 的格式定义一个函数指针变量。或者以 typedef的形式定义一个函数指针类型。
// C语言的函数指针声明
int (*addInC)(int , int ) ;
// 声明一个函数指针类型,类型名为AddOperation
typedef int (*AddOperation)(int, int);
// 普通C语言函数
int doAdd(int a, int b) {
return a + b ;
}
//使用
int main(int argc, const char * argv[])
{
@autoreleasepool {
// addInC指针变量指向doAdd函数
addInC = doAdd;
// 函数指针调用,实际上调用的是doAdd(5,6)
NSLog(@" addInC : %i.", addInC(5, 6)) ;
// 声明一个aop函数指针变量,也指向doAdd
AddOperation aop = doAdd ;
NSLog(@" AddOperation : %i.", aop(100, 23) );
}
return 0;
}
输出 :
addInC : 11.
AddOperation : 123.
~~~~~~
//使用示例5 -- block的递归调用
代码块想要递归调用,代码块变量必须是全局变量或者是静态变量,这样在程序启动的时候代码块变量就初始化了,可以递归调用
~~~~~~
//使用示例6 -- block可直接使用和改变全局变量
运行打印结果:
global:1001
global:1001
~~~~~~
//使用示例7 -- block可直接使用局部变量,但改变局部变量需要在变量前加上关键字__block, 否则不能通过编译
运行打印结果:
local:501
local:501
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mac OS下开启系统自带的FTP服务器功能
sudo -s launchctl load -w /System/Library/LaunchDaemons/ftp.plist //开启ftp
sudo -s launchctl unload -w /System/Library/LaunchDaemons/ftp.plist //关闭ftp
想开机自启动ftp服务就编辑ftp.plist
<dict>
<key>Disabled</key> --> 改为Enabled
<true/>
开启后的根目录为$HOME --- 使用ftp localhost验证即可
用户名&密码跟电脑的一样
开启SFTP需要在System Preferences -> sharing,勾上"Remote Login” --- 使用sftp localhost验证即可
~~~~~~
开启Apache
#sudo apachectl start
http://blog.csdn.net/ynnmnm/article/details/50903933
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
df命令可以显示目前所有文件系统的可用空间及使用情形。df 统计数据块使用情况
df -h
du:查询文件或文件夹的磁盘使用空间. du 统计文件大小相加
du -h --max-depth=1 work/testing/logs/*
查看linux文件目录的大小和文件夹包含的文件数
统计总数大小
du -sh xmldb/
du -sm * | sort -n //统计当前目录大小 并安大小 排序
du -sk * | sort -n
du -sk * | grep guojf //看一个人的大小
du -m | cut -d "/" -f 2 //看第二个/ 字符前的文字
查看此文件夹有多少文件 /*/*/* 有多少文件
du xmldb/
du xmldb/*/*/* |wc -l
wc [-lmw] 参数说明:
-l :多少行
-m:多少字符
-w:多少字
ls以K、M、G为单位查看文件大小
ls -lh
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如何在NSTableView中实现全选功能
- (void)keyDown:(NSEvent*)theEvent {
if([theEvent modifierFlags] & NSCommandKeyMask) {
NSString* theString = [theEvent charactersIgnoringModifiers];
if([theString characterAtIndex:0] == 'A' || [theString characterAtIndex:0] == 'a') {
[tableView selectAll];
}
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如何封装结构题对象到NSMutableArray中
使用NSValue
用NSValue包装:
typedef struct {
float real;
float imaginary;
} ImaginaryNumber;
ImaginaryNumber miNumber;
miNumber.real = 1.1;
miNumber.imaginary = 1.41;
NSValue *miValue = [NSValue value: &miNumber withObjCType:@encode(ImaginaryNumber)];
ImaginaryNumber miNumber2;
[miValue getValue:&miNumber2];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Web服务器启动
1.Mac OS X 自带了 Apache 和 PHP 环境,我们只需要简单的启动它就行了。
2.输入 httpd -v 可以查看 Apache 版本信息
3.启动 Apache:sudo apachectl start
4.停止 Apache:sudo apachectl stop
5.重启 Apache:sudo apachectl restart
启动后,在浏览器中输入 http://127.0.0.1 或 http://localhost 如果看到 It Works! 页面
站点的根目录为系统级根目录 /Library/WebServer/Documents。
启动后,你可以通过编辑 /etc/apache2/httpd.conf 文件来修改 Apache 配置。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xcode Mac OS旧程序编译出现@Synthesize异常
Semantic issue: Synthesized property 'myProperty' must either be named the same as a compatible ivar or must explicitly name an ivar.
原因:
xcode对@property和@Synthesize在32-bit intel和64-bit intel中的实现方法不同,针对64-bit intel的编译将更完善
解决方法:
Build Setting -> Architectures设置为Standard Architectures(64-bit intel)(x86_64)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
枚举类型的定义格式
typedef NS_ENUM(NSInteger,JHLineChartType){
JHChartLineEveryValueForEveryX=0,
JHChartLineValueNotForEveryX
};
typedef enum {
SpeedTypeLow=0,
SpeedTypeMiddle,
SpeedTypeHigh,
SpeedTypeUnknown,
}SpeedType;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
用Xcode8.0上传项目时被驳回说是info.plist里面没有设置
NSPhotoLibraryUsageDescription、
NSCameraUsageDescription、
NSContactsUsageDescription、
NSMicrophoneUsageDescription等字段,
之前这些都是预设的不用加,现在强制了
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xcode8.0/xcode8.1 注释快捷键⌘+/失效
这个是因为苹果解决xcode ghost。把插件屏蔽了。
解决方法:命令运行 sudo /usr/libexec/xpccachectl
然后必须重启电脑后生效。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mac OS 常用終端工具
檢查系統信息:
system_profiler SPMemoryDataType
sudo chmod -R a+rw /usr/local/share
Lsof “lists on its standard output file information”, lsof -i tcp:8080
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ios app访问http服务器遇到Transport Security的错误的解决方法
原因:ios9之后,苹果将原http协议改成了https协议,使用TLS1.2 SSL加密请求数据。
解决方法:编辑info.plist,加入如下设置:
<plist>
<dict>
...........
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
</true>
</dict>
</dict>
</plist>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//brew 架设hls服务器的方法过程
1.安装brewhome
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2.卸载brew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"
3.安装nginx服务器
brew tap homebrew/nginx
4.安装Nginx服务器和rtmp模块
brew install nginx-full --with-rtmp-module
5.检查安装信息
brew info nginx-ful
//重要文件路径
//nginx服务器操作基本指令
sudo /usr/local/Cellar/nginx-full/1.10.2/bin/nginx //启动服务器
sudo /usr/local/Cellar/nginx-full/1.10.2/bin/nginx -s reload //重新加载设置
sudo /usr/local/Cellar/nginx-full/1.10.2/bin/nginx -s quit //退出
sudo /usr/local/Cellar/nginx-full/1.10.2/bin/nginx -s reopen //重启服务
sudo /usr/local/Cellar/nginx-full/1.10.2/bin/nginx -s stop //停止服务
//至此服务器已经启动,正常在safari中输入路径http://localhost:8080即可打开nginx的欢吟页面
//安装ffmpeg工具
brew install ffmpeg
视频转换指令
ffmpeg -re -i Movie.m4v -vcodec copy -f flv rtmp://localhost:1935/hls/movie
ffmpeg -re -i Movie.m4v -vcodec libx264 -acodec aac -strict -2 -f flv rtmp://localhost:1935/rtmplive/room
其中rtmp的1935之后路径设置“application hls”中后一个关键字相同,最后的movie可随便指定
//服务器设置
//usr/local/etc/nginx/nignx.conf文件中设置如下
http {
server {
//其中添加以下设置项
location /hls {
types{
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root html;
add_header Cache-Control no-cache;
}
}
}
rtmp {
server {
listen 1935;
application abcd {
live on;
record off;
}
application hls {
live on;
hls on;
hls_path /usr/local/var/www/hls;
hls_fragment 5s;
}
}
}
// 修改~/.bash_profile之后,重新加载配置的方法source file
//m3u8文件的结尾处添加如下行,将表示点播功能,如果没有此行,将为直播模式
#EXT-X-ENDLIST
//设置系统默认的xcode版本
xcode-select --switch <xcode app path.app>
//查看brew的配置
brew --config
Xcode: 8.1 => /Volumes/hed/Applications/Xcode.app/Contents/Developer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
从本app bundle中的Localiziable.strings文件中的key读取相对应的value值
文件定义格式
”key1”=“value1”;
”key2”=“value2”;
”key3”=“value3”;
NSString *str=NSLocalizedStringWithDefaultValue(@“key1”, @"Localizable", [NSBundle mainBundle], defaultValue, nil);
同类的函数还有
NSString *str=NSLocalizedString(key, comment) //默认的.strings文件名称为”Localizable.strings”
NSString *str=NSLocalizedStringFromTable(key, tbl, comment) //tbl是指所定义的”.strings”文件名称
NSString *str=NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment) //bundle指.strings文件所在的bundle
NSString *str=NSLocalizedStringWithDefaultValue(key, tbl, bundle, val, comment) //val: 如果查找key失败所返回的值
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NSTextField可设置delegate并自动响应enter键动作
delegate方法:
-(void)controlTextDidEndEditing:(NSNotification *)obj
此方法为所有的NSControl子类设置delegate后都可以使用的
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NSView上鼠标事件响应方法:
1.添加监控,使用如下方法
- (void)updateTrackingAreas{
NSArray *trackings = [self trackingAreas];
for (NSTrackingArea *tracking in trackings) {
[self removeTrackingArea:tracking];
}
NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] options:NSTrackingMouseEnteredAndExited| NSTrackingMouseMoved | NSTrackingActiveAlways owner:self userInfo:nil];
[self addTrackingArea:trackingArea];
}
2.之后即可在NSView中重写以下方法,
-(void)mouseMoved:(NSEvent *)theEvent{}
-(void)mouseDragged:(NSEvent *)theEvent{}
-(void)mouseDown:(NSEvent *)theEvent{}
-(void)mouseUp:(NSEvent *)theEvent{}
3.使用下边方法获取当前鼠标位置
NSPoint point = [theEvent locationInWindow]
NSPoint orgPoint = [self convertPoint:[theEvent locationInWindow] toView:self];
4.改变鼠标图标
NSCursor *curos = [[NSCursor alloc] initWithImage:[NSImage imageNamed:name] hotSpot:[[NSCursor currentCursor]hotSpot]];
[curos set];
//----------
[[NSCursor arrowCursor] set];
[[NSCursor disappearingItemCursor] set];
[[NSCursor dragLinkCursor]set];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
生成隨機數的方法
1.生成隨機u_int32_t正整數
NSUInteger r = arc4random();
2.生成0~N-1之間的u_int32_t隨機整數
NSUInteger r = arc4random_uniform(N); 或者 NSUInteger r = arc4random() % N;
3.生成0~1之間的double型隨機數
srand48(time(0));
double r = drand48();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
数据存储模式 和 数据所占字节数
// int a = 0x01020304
// 其位權由高到低依此為0x01,0x02,0x03,0x04
// interl的cpu採用小端存儲模式,所以在計算機裡邊的存儲為:低地址位存儲低權重數,高地址位存儲高權重位
// 所以在計算機中存儲的方式位0x04,0x03,0x02,0x01, 因此在直接將int數據轉換位NSData時,將表示為04030201
// OS X 10.11.6
// char:1 byte
// unsigned char:1 byte
// unichar:2 byte
// short int:2 byte
// int:4 byte
// long int:8 byte
// double:8 byte
// float:4 byte
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C语言中二维数组的定义
// C 語言定義二維書組時,必須指定列的大小,行數可以不指定
// int a[x][y], x 可以省略,y不能省略
// 同理三位數組,int a[x][y][z] x可以省略,y/z不可以省略
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
idpbgdp2@gmail.com
1dpbg1e
user: 93826439@qq.com
PW: Idpbg789.
10.199.28.152
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如何求字符串所占的size
CGSize sr=[aString sizeWithAttributes:@{NSFontAttributeName:[NSFont systemFontOfSize:9]}];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
系统任务的设置路径为
/Library/LaunchAgents
/System/Library/LaunchAgents
~/Library/LaunchAgents
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
键盘值keycode的集合
使用Carbon.framework中的KVK_ANSI_xxx的预定义
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
模拟器显示视图的时候好似慢动作
去掉选项Simulator->Debug->slow animations,即可变为正常显示
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
被GH过的Mac系统如何获取到管理员权限:
1. Macmini插上键盘
2.按住Window+S键,重启电脑
3.出现/root#界面 或者base-3.2#界面松开键盘 -- 背景全黑,全英文
4.点击回车,进入可输入界面
5.输入以下指令
mount -uaw(with network)
rm -rf /var/db/.AppleSetupDone
6.重启电脑,此时将进入到电脑第一次启动时的设置页面,正常设置开机即可获取到管理员权限了
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Java中定义类方法和变量是通过static来实现的, 一旦定义就不允许修改的,需要使用final来修饰
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
XCode无法自动智能提示时的解决方法:
删除~/Library/Developer/Xcode/DerivedData之下的所有内容,然后重启xcode
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
实现单例模式,至少需完成以下步骤(前4项必须完成):
1. 在.m文件开头定义静态实例 static Food * class = nil;
2.实现类方法sharedClass,其中@synchronized是实现线程安全
static Food * class = nil;
+(Food *)sharedFood{
@synchronized(self) {
if (!class) {
class=[[self alloc]init];
}
return class;
}
}
3.重写alloc方法
+(id)allocWithZone:(NSZone *)zone{
@synchronized(self) {
if (!class) {
class=[super allocWithZone:zone];
}
return class;
}
}
4.重写init方法
-(id)init{
@synchronized(self) {
if (self=[super init]) {
return self;
}
return nil;
}
}
5.其它如果要实现copy时,也保持单例模式,必须重写copywithZone方法
+(id)copyWithZone:(struct _NSZone *)zone{
return [self sharedFood];
}
-(id)copyWithZone:(NSZone *)zone{
return self;
}
6.要想全面实现,也可重写release/autorelaese/retain方法等
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AR中model.dat数据的配置
sample.mp4
//文件名称
40.0 40.0 0.0
//识别到的标示卡的原点位置(可能是标识卡的中心位置),这几个值表示将要现实的3d物体/视频的原点相对于标识卡原点的位置关系
//通常情况下,标识卡在建立数据模型是,就已经确定了x,y,z的方向
90.0 1.0 0.0 0.0
//这里表示虚拟物体展示的角度
//90 = 表示垂直于video中的标识卡显示模式
//1.0 0.0 0.0 = 表示虚拟物体以什么样的姿态展示出来,即那一面潮向观众。 -- 相对于标识卡的标准模式
1.0 1.0 1.0
//模型相对于标识卡有一个磨人比例,此三个值表示相对于此默认比例的一个显示比例
MARKER 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在Terminal中创建一个cocos2d程序的方法为:
cocos new -p com.gdadmin.test -l cpp -d ~/Desktop/workspace helloworld
aesw:/ admin$ cocos new -h
usage: cocos new [-h] [-p PACKAGE_NAME] [-d DIRECTORY] [-t TEMPLATE_NAME]
[--ios-bundleid IOS_BUNDLEID] [--mac-bundleid MAC_BUNDLEID]
[-e ENGINE_PATH] [--portrait] [--no-native]
(-l {cpp,lua,js} | --list-templates | -k TEMPLATE_NAME)
[PROJECT_NAME]
Creates a new project.
positional arguments:
PROJECT_NAME Set the project name.
optional arguments:
-h, --help show this help message and exit
-p PACKAGE_NAME, --package PACKAGE_NAME
Set a package name for project.
-d DIRECTORY, --directory DIRECTORY
Set the path where to place the new project.
-t TEMPLATE_NAME, --template TEMPLATE_NAME
Set the template name you want create from.
--ios-bundleid IOS_BUNDLEID
Set a bundle id for iOS project.
--mac-bundleid MAC_BUNDLEID
Set a bundle id for Mac project.
-e ENGINE_PATH, --engine-path ENGINE_PATH
Set the path of engine.
--portrait Set the project be portrait.
-l {cpp,lua,js}, --language {cpp,lua,js}
Major programming language you want to use, should be
[cpp | lua | js]
--list-templates List available templates. To be used with --template
option.
-k TEMPLATE_NAME, --template-name TEMPLATE_NAME
Name of the template to be used to create the game. To
list available names, use --list-templates.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cocos2d HelloWorld ios App中build好的libcocos2d ios.a文件的路径为
/Users/gdadmin/Library/Developer/Xcode/DerivedData/helloworld-ermbjtxjdcnebfbcbtcdznxmirmc/Build/Products/Debug-iphoneos
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在UITableViewCell中通过tag取出subviewde方法
NSString *identify=@"beaconCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identify forIndexPath:indexPath];
BRTBeacon *beacon = [brts objectAtIndex:indexPath.row];
UILabel *lbl=(UILabel *)[cell viewWithTag:10];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如何定义info.plist文件
Target -> Build Setting -> All -> Packaging -> info.plist File需要定义文件名称 / Expand Build Setting in info.plist file需要设置为YES
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
usr/include/Availability.h中定义了很多常用的宏定义变量内容
如:判定是否是ios 5.0及以上版本的变量
#import <Availability.h>
#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif
#ifdef __OBJC__
#define Lang(en,zh) [[NSLocale preferredLanguages][0] rangeOfString:@"zh"].location==0?zh:en
#endif
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
App如何向系统通知栏中发送通知(发送本地通知)
//如何发送本地通知
#pragma monitor
- (void)sendLocalNotification:(NSString*)msg
{
UILocalNotification *notice = [[UILocalNotification alloc] init];
notice.alertBody = msg;
notice.alertAction = Lang(@"Open", @"打开软件");
notice.soundName = UILocalNotificationDefaultSoundName;
notice.userInfo = @{@"msg":@"whatever you want"};
[[UIApplication sharedApplication] presentLocalNotificationNow:notice];
}
如何接收本地通知,在AppDelegate中实现如下方法:
-(void)application:(nonnull UIApplication *)application didReceiveLocalNotification:(nonnull UILocalNotification *)notification{
//here we can use the user info to define that app will show which one view controlelr
NSLog(@"local notification:%@",notification.userInfo);
//接收到通知后,实现跳转到固定页面的方法,此时root view controller已经加载成功,可在main view controller中的viewWillAppear中监听次通知,从而实现条组昂
[[NSNotificationCenter defaultCenter] postNotificationName:@"ToNextView" object:nil];
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
快捷显示Alert View的方法(AlertSheet的使用方法)
#define showAlert(msg) [[[UIAlertView alloc] initWithTitle:Lang(@"Tips", @"提示") message:msg delegate:nil cancelButtonTitle:Lang(@"OK", @"确定") otherButtonTitles: nil] show];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xcode中工程常用系统变量
$(SRCROOT) : xcodeproj文件所在完整路径
$(PROJECT_NAME) : 工程名字
$(EXECUTABLE_NAME)
$(PRODUCT_BUNDLE_IDENTIFIER)
$(BUILD_DIR)
$(CONFIGURATION)
$(EFFECTIVE_PLATFORM_NAME)
$(CACHE_ROOT)
$(PROJECT_TEMP_DIR)
$(TARGET_TEMP_DIR)
$(CURRENT_VARIANT)
$(CURRENT_ARCH)
$(inherited)
$(CURRENT_FOLDER_PATH)
$(PROJECT_DIR) xcideproj文件所在的路径
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如何创建并加载一个Prefix.pch文档
1. 创建
点击工程 -> 右键 -> New File -> iOS / Mac OS -> Other -> PCH File
2. 加载
在Targets -> Build Setting -> All -> Apple LLVM 7.0 - Language中作如下设置
Precompile Prefix Header 设置为 YES
Prefix Header 设置为所创建的Prefix.pch文件全称 (如果与xcodeproj文件不在同一层路径下,还要带上相对路径,如BeaconTest/BeaconTest-PrefixHeader.pch)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如果遇到添加了.a文件后,编译时仍旧找不到library,需要添加library path给target
Targets -> Build setting -> All -> Search Paths -> Header Search path 添加header文件路径 / Library Search paths添加.a的link文件路径
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
当从网络上如果有要求固定的provisioning profile才能运行的,需要在Targets -> Build Setting -> All -> Code Signing中将Provisioning Profile设置为Automatic即可
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
遇到与c++混编时,有时出现不显荣的内容,需要在如下路径改变编译器
Unsupported compiler 'com.apple.compilers.llvmgcc42' selected for architecture 'armv7'
Unable to determine concrete GCC compiler for file /Volumes/hed/IOS/AR/0311/01 Professional_iOS_AugmentedReality-master/Professional_iOS_AugmentedReality-master/Ch8/Ch8/libs/cocos2d/CCAction.m of type sourcecode.c.objc.
在Target -> Building Setting -> Build Options -> compiler for c/c++/Objective-c修改为Default compiler即可
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在ARC模式下,要想将self赋值给void *,需要做一个强制桥接设定,否则将报数据错误或者方法找不到的异常
void *var = (__brige void *) self;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
当进行OC和C++混编的时候,如果遇到无法识别编译C++的时候,可进行如下动作
1. 将.m文件修改为.mm
2. 设置Targets -> Apple LLVM 7.0 - Language -> Compile Sources As -> Objective-C++
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
异常处理
clang: error: -fembed-bitcode is not supported on versions of iOS prior to 6.0
在Targets -> Build settings -> build options -> Enable Bitcode, 将其值设置为No
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
异常处理
clang: error: garbage collection is no longer supported
OSX旧版本程序移植到新版本XCode上时会提示不支持Garbage Collection,修改方法如下
在Target -> Build Setting -> All -> User-Defined设置,
将其中的GCC_ENABLE_OBJC_GC supported设置项变更为unsupported即可
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
将一个UIImageView作为一个UIView的BackgroundView(背景图片)来使用的方法
-(void)backgroundImage:(NSString *)imageName{
CGRect rect=self.view.frame;
// Do any additional setup after loading the view, typically from a nib.
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(-10, -10, rect.size.height+20, rect.size.height+20)];
imageView.contentMode=UIViewContentModeScaleToFill;
imageView.image=[UIImage imageNamed:imageName];
[self.view insertSubview:imageView atIndex:0];
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如何改变UITableView上Header的背景色(ios6.0及以上)
-(void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section{
view.tintColor=[UIColor colorWithR:210 G:237 B:255 A:1.0];
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UITableView如何控制ScrollView(滚动条)自动滚动到某一行
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
使用UIBezierPath和CAShapLayer实现画圆的功能(此方法也可以实现画直线/画椭圆/画矩形等)
-(void)drawBackgroundCircle{
UIBezierPath *backPath=[UIBezierPath bezierPathWithArcCenter:self.circleCenter radius:self.circleRadius startAngle:0 endAngle:2*M_PI clockwise:YES];
CAShapeLayer *backLayer=[CAShapeLayer layer];
backLayer.fillColor=[UIColor clearColor].CGColor;
backLayer.strokeColor=self.backColor.CGColor;
backLayer.lineWidth=self.lineWidth;
backLayer.path=backPath.CGPath;
[self.layer addSublayer:backLayer];
}
实现圆形进度条的方法可:将圆周分成100份,每次画1份的弧长度,用NSTimer累加来实现表示。 而对于进度减少的方法,可从self.view.layer的sublayers中依此减去原来的subleyer来实现。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS中实现CGPoint和NSValue/NSString的转换方法
NSString *pointString=NSStringFromCGPoint(CGPoint p);
CGPoint point=CGPointFromString(NSString *pointString);
NSValue *value=[NSValue valueWithCGPoint:(CGPoint)point];
CGPoint point=[value CGPointValue];
其它如CGSize,CGRect,CGVector,CGAffineTransform,UIEdgeInsets,UIOffset等都可以使用此方法转换
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UIVIew中画图(画直线/画圆)的方法如下:
- (void)drawCircle:(CGPoint)p withColor:(UIColor *)cirColor{
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(ctx, cirColor.CGColor);
CGContextAddArc(ctx, p.x, p.y, 50, 0, 2 * M_PI, 1);//context,圆心x,y, 半径, 起始位置(角度), 圆弧度,逆时针|顺时针
CGContextFillPath(ctx);
}
-(void)drawLine:(CGPoint)p withColor:(UIColor *)lineColor{
CGContextRef ctxref=UIGraphicsGetCurrentContext();
CGContextBeginPath(ctxref);
CGContextMoveToPoint(ctxref, p.x-50>0?p.x-50:0, p.y);
CGContextAddLineToPoint(ctxref, p.x+50>self.frame.size.width?self.frame.size.width:p.x+50, p.y);
CGContextMoveToPoint(ctxref, p.x, p.y-50>0?p.y-50:0);
CGContextSetLineWidth(ctxref, 2);
CGContextAddLineToPoint(ctxref, p.x, p.y+50>self.frame.size.height?self.frame.size.height:p.y+50);
CGContextSetStrokeColorWithColor(ctxref, lineColor.CGColor);
CGContextStrokePath(ctxref);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如何取得一个字符串所占用的长宽, 数组定义
NSString *str=@"请在时间内,拨动[静音控制键]以及[两个音量键]";
NSDictionary *dict=[NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:16],NSFontAttributeName, nil];
CGSize asize=[str sizeWithAttributes:dict];
CGSize nsize=[str sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16]}]; //字典的定义方式
NSArray *aaa=@[@"111",@"555"]; //数组的定义方式
//NSDictionary的访问:dictionary[@“key”], 定义NSDictionary *dict=@{@“key”:@“value”,@“key1”:@“value1”};
//NSArray的访问:array[0]; 定义NSArray *array=@[@“value1”,@“value2”];
UIColor *colors[3] = {[UIColor blackColor], [UIColor darkGrayColor], [UIColor lightGrayColor]};
NSNumber *number = @3; //可直接使用@数字定义NSNumber
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UIViewController中如何隐藏状态栏
if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
[self prefersStatusBarHidden];
[self performSelector:@selector(setNeedsStatusBarAppearanceUpdate) withObject:nil];
}
-(BOOL)prefersStatusBarHidden{
return YES;//yes=隐藏,no=显示
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UITableView和UICollectionView在使用自定义的Cell时的注意事项
1.UICollectionView必须注册cell的class,而UITableView不需要
[self.testCollectionView registerClass:[ManualTestCollectionViewCell class] forCellWithReuseIdentifier:@"TestItem"];
2.Cell的使用稍有不同
2.1 UICollectionView中的Cell加载
ManualTestCollectionViewCell *cell=(ManualTestCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"TestItem" forIndexPath:indexPath];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ManualTestCollectionViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
2.2 UITableView中的Cell加载
ManualCell *cell = (ManualCell *)[tableView dequeueReusableCellWithIdentifier:@"TestItem"];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ManualCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UITableView设置cell不可选择/不可上下滚动
(UITableViewCell *)cell.userInteractionEnabled=NO; //cell不可选择
(UITableViewCell *)cell.selectionStyle=UITableViewCellSelectionStyleNone;
(UITableView *)tableView.scrollEnabled=NO;//table view不能上下滚动
//全部不可选
-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *){
return nil;
}
//不可选
self.tableView.allowsSelection=NO;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
视图大小自适应和subview操作
UIlabel 的numberOfLines表示去掉其行数限制
1.使用SizeToFit方法达到自适应,如UILabel自动适应文字的内容多少
2.[subview removeFromSuperview]; //移除
3.[UIView addSubview:Subview]; //添加
4.[UIView bringSubviewToFront:Subview]; //上移一层
5.[UIView sendSubviewToBack:Subview]; //下移一层
6.[UIView exchangeSubviewAtIndex:indexA withSubviewAtIndex:indexB]; //交换
7.NSInteger index=[[UIView subviews] indexOfObject:Subview_名称]; //获取subview的index
8. UILabel label=[UILable new];
label.text=@“text”
label.textAligment = UITextAlignmentCenter;
label.backgroundColor = [UIColor balckColor];
label.textColor = [UIColor whiteColor];
label.font=[UIFont systemFontOfSize:14];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如何加载一个自定义的Nib/xib视图文件
UIView *customizedView = [[UINib nibWithNibName:@"buttonTestFor4" bundle:nil] instantiateWithOwner:self options:nil][0];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UI动画和交互体系
CoreAnimation-UIView animations-UIKit Dynamics
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS中使用CoreGraphics.framework来遍历UIImage中每个pixel的RGBA值(检查每个像素的RGB值)
// Return a bitmap context using alpha/red/green/blue byte values
CGContextRef CreateRGBABitmapContext (CGImageRef inImage)
{
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void *bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
size_t pixelsWide = CGImageGetWidth(inImage);
size_t pixelsHigh = CGImageGetHeight(inImage);
bitmapBytesPerRow = ((int)pixelsWide * 4);
bitmapByteCount = (bitmapBytesPerRow * (int)pixelsHigh);
colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL){
fprintf(stderr, "Error allocating color space");
return NULL;
}
// allocate the bitmap & create context
bitmapData = malloc( bitmapByteCount );
if (bitmapData == NULL){
fprintf (stderr, "Memory not allocated!");
CGColorSpaceRelease( colorSpace );
return NULL;
}
context = CGBitmapContextCreate (bitmapData, pixelsWide,pixelsHigh, 8, bitmapBytesPerRow,
colorSpace, kCGImageAlphaPremultipliedLast); if (context == NULL){
free (bitmapData);
fprintf (stderr, "Context not created!");
}
CGColorSpaceRelease( colorSpace );
return context;
}
// Return Image Pixel data as an RGBA bitmap
unsigned char *RequestImagePixelData(UIImage *inImage)
{
CGImageRef img = [inImage CGImage];
CGSize size = [inImage size];
CGContextRef cgctx = CreateRGBABitmapContext(img);
if (cgctx == NULL)
return NULL;
CGRect rect = {{0,0},{size.width, size.height}};
CGContextDrawImage(cgctx, rect, img);
unsigned char *data = CGBitmapContextGetData (cgctx);
CGContextRelease(cgctx);
return data;
}
+(UIImage*)blackWhite:(UIImage*)inImage
{
unsigned char *imgPixel = RequestImagePixelData(inImage);
CGImageRef inImageRef = [inImage CGImage];
GLuint w = (GLuint)CGImageGetWidth(inImageRef);
GLuint h = (GLuint)CGImageGetHeight(inImageRef);
int wOff = 0;
int pixOff = 0;
for(GLuint y = 0;y< h;y++)
{
pixOff = wOff;
for (GLuint x = 0; x<w; x++)
{
int red = (unsigned char)imgPixel[pixOff];
int green = (unsigned char)imgPixel[pixOff+1];
int blue = (unsigned char)imgPixel[pixOff+2];
//int alpha = (unsigned char)imgPixel[pixOff+3]; //不透明度
int bw = (int)((red+green+blue)/3.0);
imgPixel[pixOff] = bw;
imgPixel[pixOff+1] = bw;
imgPixel[pixOff+2] = bw;
pixOff += 4;
}
wOff += w * 4;
}
NSInteger dataLength = w * h * 4;
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, imgPixel, dataLength, NULL);
// prep the ingredients
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * w;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
// make the cgimage
CGImageRef imageRef = CGImageCreate(w, h, bitsPerComponent, bitsPerPixel, bytesPerRow,
colorSpaceRef,bitmapInfo,provider,NULL, NO, renderingIntent);
UIImage *my_Image = [UIImage imageWithCGImage:imageRef];
CFRelease(imageRef);
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(provider);
return my_Image;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS中如何保存一个ViewController中的View的截屏图片
-(UIImage *)screenshotForCurrentView{
UIGraphicsBeginImageContext(self.bounds.size); //self = UIView object
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenImage=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//UIImageWriteToSavedPhotosAlbum(timg, self, nil, nil);//timg = UIImage object, 保存图片到相册
return screenImage;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
检测手机是否越狱
-(BOOL)isJailbroken
{
#if !(TARGET_IPHONE_SIMULATOR)
if ([[NSFileManager defaultManager] fileExistsAtPath:@"/Applications/Cydia.app"] ||
[[NSFileManager defaultManager] fileExistsAtPath:@"/Library/MobileSubstrate/MobileSubstrate.dylib"] ||
[[NSFileManager defaultManager] fileExistsAtPath:@"/bin/bash"] ||
[[NSFileManager defaultManager] fileExistsAtPath:@"/usr/sbin/sshd"] ||
[[NSFileManager defaultManager] fileExistsAtPath:@"/etc/apt"] ||
[[NSFileManager defaultManager] fileExistsAtPath:@"/private/var/lib/apt/"] ||
[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.example.package"]]) {
return YES;
}
FILE *f = NULL ;
if ((f = fopen("/bin/bash", "r")) ||
(f = fopen("/Applications/Cydia.app", "r")) ||
(f = fopen("/Library/MobileSubstrate/MobileSubstrate.dylib", "r")) ||
(f = fopen("/usr/sbin/sshd", "r")) ||
(f = fopen("/etc/apt", "r"))) {
fclose(f);
return YES;
}
fclose(f);
NSError *error;
NSString *stringToBeWritten = @"This is a test.";
[stringToBeWritten writeToFile:@"/private/jailbreak.txt" atomically:YES encoding:NSUTF8StringEncoding error:&error];
[[NSFileManager defaultManager] removeItemAtPath:@"/private/jailbreak.txt" error:nil];
if(error == nil)
{
return YES;
}
#endif
return NO;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS中检测指纹识别是否可用
- (void)authentication:(NSString *)itemName{
LAContext *myContext = [[LAContext alloc] init];
NSError *error = nil;
NSString *myLocalizedReasonString = @"检测指纹识别是否可用";
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]){
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:myLocalizedReasonString reply:^(BOOL success, NSError *error){
if (error){
NSLog(@"Authenticated error ");
return;
}
if (success){
NSLog(@"Authenticated success ");
// User authenticated successfully, take appropriate action
}else{
NSLog(@"Authenticated failed ");
// User did not authenticate successfully, look at error and take appropriate action
}
}];
}else{
NSLog(@"Authenticated could not evaluate policy ");
// Could not evaluate policy; look at error and present an appropriate message to user
[self performSelectorOnMainThread:@selector(authenticationFail:) withObject: itemName waitUntilDone:NO];
}
}
-(void)authenticationFail:(NSString *)itemName{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"⚠警告" message:@"指纹密码未开启,请在设置中开启指纹密码后重新测试!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS中如何调用外部程序
使用UIApplication中的方法openURL来开启
web link: @“http://www.apple.com” -- safri打开网页
mail link: @“mailto:monster@n-i-l-x.example.com?subject=hello%20mail!” --- 发送mail
phone link: @“tel:150-0000-0000” ---- 拨打电话
text link: @“sms:150-0000-0000” --- 发送短信
map link: @“http://maps.google.com/maps?ll=31.143289%2C121.347239&z=15” --- 地图定位
例如拨打112电话的功能调用如下:
NSURL *phoneUrl = [NSURL URLWithString:@"tel:112”];
if ([[UIApplication sharedApplication]canOpenURL:phoneUrl]){
[[UIApplication sharedApplication] openURL:phoneUrl];
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
使用IOS7原生API进行二维码条形码的扫描
IOS7之前,开发者进行扫码编程时,一般会借助第三方库。常用的是ZBarSDK,IOS7之后,系统的AVMetadataObject类中,
为我们提供了解析二维码的接口。经过测试,使用原生API扫描和处理的效率非常高,远远高于第三方库。
一、使用方法示例
官方提供的接口非常简单,代码如下:
@interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>//用于处理采集信息的代理
{
AVCaptureSession * session;//输入输出的中间桥梁
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//获取摄像设备
AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//创建输入流
AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
//创建输出流
AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];
//设置代理 在主线程里刷新
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
//初始化链接对象
session = [[AVCaptureSession alloc]init];
//高质量采集率
[session setSessionPreset:AVCaptureSessionPresetHigh];
[session addInput:input];
[session addOutput:output];
//设置扫码支持的编码格式(如下设置条形码和二维码兼容)
output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
AVCaptureVideoPreviewLayer * layer = [AVCaptureVideoPreviewLayer layerWithSession:session];
layer.videoGravity=AVLayerVideoGravityResizeAspectFill;
layer.frame=self.view.layer.bounds;
[self.view.layer insertSublayer:layer atIndex:0];
//开始捕获
[session startRunning];
}
之后我们的UI上已经可以看到摄像头捕获的内容,只要实现代理中的方法,就可以完成二维码条形码的扫描:
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
if (metadataObjects.count>0) {
//[session stopRunning];
AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex : 0 ];
//输出扫描字符串
NSLog(@"%@",metadataObject.stringValue);
}
}
二、一些优化
通过上面的代码测试,我们可以发现系统的解析处理效率是相当的高,IOS官方提供的API也确实非常强大,然而,我们可以做进一步的优化,将效率更加提高:
首先,AVCaptureMetadataOutput类中有一个这样的属性(在IOS7.0之后可用):
@property(nonatomic) CGRect rectOfInterest;
这个属性大致意思就是告诉系统它需要注意的区域,大部分APP的扫码UI中都会有一个框,提醒你将条形码放入那个区域,这个属性的作用就在这里,它可以设置一个范围,只处理在这个范围内捕获到的图像的信息。如此一来,可想而知,我们代码的效率又会得到很大的提高,在使用这个属性的时候。需要几点注意:
1、这个CGRect参数和普通的Rect范围不太一样,它的四个值的范围都是0-1,表示比例。
2、经过测试发现,这个参数里面的x对应的恰恰是距离左上角的垂直距离,y对应的是距离左上角的水平距离。
3、宽度和高度设置的情况也是类似。
3、举个例子如果我们想让扫描的处理区域是屏幕的下半部分,我们这样设置
output.rectOfInterest=CGRectMake(0.5,0,0.5, 1);
具体apple为什么要设计成这样,或者是这个参数我的用法那里不对,还需要了解的朋友给个指导。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS读取机身存储容量大小(参看DiskSpace.h 磁盘空间)
NSDictionary *fattributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil];
long long capacity = [[fattributes objectForKey:NSFileSystemSize]longLongValue];//所得到的是byte
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS读取机器的颜色
UIDevice *device = [UIDevice currentDevice];
SEL selector = NSSelectorFromString(@"deviceInfoForKey:");
if (![device respondsToSelector:selector]) {
selector = NSSelectorFromString(@"_deviceInfoForKey:");
}
NSString *colorStr = [device performSelector:selector withObject:@"DeviceColor”]; //机身屏幕面的颜色
NSString *enclosureColor = [device performSelector:selector withObject:@"DeviceEnclosureColor”];//机身后壳的颜色
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS读取机种信息,如iphone7,1等,(参照class ReadiPhonePlatform.h)
#import <mach/mach.h>
#import <sys/sysctl.h>
size_t size;
sysctlbyname("hw.machine",NULL,&size,NULL,0);
char * machine = malloc(size);
sysctlbyname("hw.machine", machine, &size, NULL, 0);
NSString *platform = [NSString stringWithCString:machine encoding:NSUTF8StringEncoding];
free(machine);
此中platform即所读取到的机种信息,如@"iPhone1,1”,@"iPhone3,1”,@"iPod1,1”等
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS中侦测静音键的状态,ON/OFF(github实例MuteDetector-master)
使用第三方类库SKMuteSwitchDetector.h来实现侦测,十分简便
[SKMuteSwitchDetector checkSwitch:^(BOOL success, BOOL silent) {
//success表示是否侦测到状态,true=成功,false=失败
//silent表示当前静音键的状态,OFF==静音键在上边,ON==静音键在下边
}];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS中侦测音量加/减(+/-)键事件(github上有完整实例,RBVolumeButtons-master)iOS 7.0以上使用
使用第三方类库RBVolumeButtons.h来实现侦测,且不显示系统自带的音量大小的图形
使用方法如下:
1.创建一个全局变量RBVolumeButtons *rbVolButton;
2.在ViewDidLoad中对其进行初始化,并添加加键和减键的侦测响应block
rbVolButton=[[RBVolumeButtons alloc] init];
rbVolButton.upBlock=^{
NSLog(@"up音量+键被按下”);//音量+键被按下
};
rbVolButton.downBlock=^{
NSLog(@"down音量-键被按下”);//音量-键被按下
};
3.在需要的地方启动或者停止事件坚挺
[rbButton startStealingVolumeButtonEvents]; //开始监听,开始后,+键==upBlock内的代码将得到响应 -键==downBlock内的代码将得到响应
[rbButton stopStealingVolumeButtonEvents]; //停止监听
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS中Home+Power键的测试(截屏键组合,github实例ShotBlocker-master)
使用第三方开源类库ShotBlocker来实现对信号和截屏图像的获取
//以下语句一旦开始运行,就处于侦测截屏信号状态,当有信号被截获时,将触发block中的代码
[[ShotBlocker sharedManager] detectScreenshotWithImageBlock:^(UIImage *screenshot){
NSLog(@"screenshot:%@",screenshot);//截获到的截屏图像screenshot
}];
//以下语句停止侦测截屏信号
[[ShotBlocker sharedManager] stopDetectingScreenshots];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS中如何单独侦测Home键或者Power键被按下(此功能通常在AppDelegate中实现,github实例ios-home-vs-lock-button-master)
所使用的是在单独点击一个键的时候,app会进入到后台或者机台进入到sleep状态,通过状态变化来侦测
1.定义函数
static void displayStatusChanged(CFNotificationCenterRef center,
void *observer,
CFStringRef name,
const void *object,
CFDictionaryRef userInfo) {
if (name == CFSTR("com.apple.springboard.lockcomplete")) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"kDisplayStatusLocked"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
2.在函数application:didFinishLaunchingWithOptions:中注册通知
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
NULL,
displayStatusChanged,
CFSTR("com.apple.springboard.lockcomplete"),
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
3.在函数applicationWillEnterForeground:中标示状态变更
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"kDisplayStatusLocked"];
[[NSUserDefaults standardUserDefaults] synchronize];
4.在函数applicationDidEnterBackground:中侦测状态变更
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
if (state == UIApplicationStateInactive) {
NSLog(@"Sent to background by locking screen”);//power键的侦测
} else if (state == UIApplicationStateBackground) {
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"kDisplayStatusLocked"]) {
NSLog(@"Sent to background by home button/switching to other app”);//点击home键的状态
} else {
NSLog(@"Sent to background by locking screen”);//点击power键进入休眠状态
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS中通过UIImagePickerController对系统相机的调用--iRa手动测试中,可通过此方法对前摄像头/后摄像头测试
1.判定设备是否可以有相机设备可用
[UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]
2.从相机获取UIImage
UIImagePickerController *picker=[[UIImagePickerController alloc]init];
picker.delegate = (id)self;
picker.allowsEditing = YES; //此项指是否在拍摄完毕照片时,对照片大小进行剪辑。
picker.sourceType = UIImagePickerControllerSourceTypeCamera; //定义从Camera来获取UIImage ,UIImagePickerControllerSourceTypePhotoLibrary表示从相册选取照片
picker.cameraDevice = UIImagePickerControllerCameraDeviceRear; //初始显示为后置摄像头,当从相册选取照片时,此处不能设置 rear -- 后部
//picker.cameraDevice = UIImagePickerControllerCameraDeviceFront; //初始显示为前置摄像头
[self presentViewController:picker animated:YES completion:NULL]; //显示系统自带的相机拍摄界面 present-显示
3.对系统相机拍摄的图片&视频的操作(delegate实现)
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary<NSString *,id> *)editingInfo{
NSLog(@"get image”);//此处的image即获取到的图片
[picker dismissViewControllerAnimated:YES completion:^{}];//控制拍摄UI消失
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[picker dismissViewControllerAnimated:NO completion:^{}];//点击相机上的cancel按钮时,退出拍摄UI dismiss-清除
NSLog(@"cancle");
}
4.如果要进行视频测试,还必须设置视频参数
UIImagePickerController *picker=[[UIImagePickerController alloc]init];
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.cameraDevice = UIImagePickerControllerCameraDeviceRear; // UIImagePickerControllerCameraDeviceFront
picker.delegate = (id)self;
picker.allowsEditing = NO;
picker.showsCameraControls=YES;
picker.mediaTypes=[NSArray arrayWithObjects:@"public.movie", nil];
picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
picker.cameraViewTransform = CGAffineTransformIdentity;
picker.cameraFlashMode = UIImagePickerControllerCameraFlashModeOff;
picker.videoQuality = UIImagePickerControllerQualityType640x480;
picker.extendedLayoutIncludesOpaqueBars = YES;
[self presentViewController:picker animated:YES completion:NULL];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS中如何实现点击Button向上/向下弹出一个选择列表功能(参照实例FDTakeController,NIDropDown.h)
使用独立类库NIDropDown.h来实现(QRCoderReader),其核心在于View的嵌套显示,大小调整以及动画的变化过程
1.在一个个的UIView的子类中如何实现动画显示效果的
在view由一个大小变更到另外一个大小的时候,已动画显示的设置如下:
[UIView beginAnimations:nil context:nil];//设置动画内容,档为nil/nil时,使用下文所设置内容
[UIView setAnimationDuration:0.5]; //设置动画时间,即要花费多长时间从现在的大小变化到目标大小
//设置目标大小,即变化后的大小
[UIView commitAnimations]; //开始动画
2.btn的superview添加一个UIView
3.UIView里边再嵌套来一个UITableView,每次大小有变化时,都适用动画的效果
4.可以用一句对其他属性添加动画
[UIView animateWithDuration:1.5 animations:^{ showview.alpha = 0; } completion:^(BOOL finished) { [showview removeFromSuperview]; }];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如何在app中设置使App不支持屏幕旋转
1.整个app中所有的view controller都不支持旋屏,则只需配置AppDelegate方法
-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskPortrait;
}
2.控制应用某个view controller的旋屏
for ios4,5,需要重写UIViewController的方法
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
return NO;
}
for ios 6 & ++ 重写UIViewController的如下方法
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;//支持旋转屏幕
}
-(BOOL)shouldAutorotate{
return NO;//开启旋转用YES,禁用旋转用NO
}
设置ios app固定横屏显示
info.plist文件中设置Supported interface orientations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如何设置使App在运行时,不锁屏,不给sleep掉
[[UIApplication sharedApplication]setIdleTimerDisabled:YES]; //设置程序运行的时候不会锁屏,不会被系统sleep掉
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如何实现键盘弹出时,UI上移的功能(功能实现的关键在于抓取到键盘的变化 & 获取到键盘的高度)
1.首先存储原始view大小和变更变量
定义一个app的全局变量CGRect viewFrame和CGFloat change, 在-(void)viewDidLoad{}中初始化值
CGRect viewFrame=self.view.frame;
CGFloat change=0.0;
2.注册keboard的观察员方法
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillAppear:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillDisappear:) name:UIKeyboardWillHideNotification object:nil];
3.实现以上两个通知所对应的方法
-(CGFloat)keyboardEndingFrameHeight:(NSDictionary *)userInfo{//此处使用键盘通知的内容抓取到键盘的高度
CGRect frame=[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect keyboardFrame=[self.view convertRect:frame fromView:nil];
return keyboardFrame.size.height;
}
-(void)keyboardWillAppear:(NSNotification *)aNotification{
NSLog(@"receive notification");
if (change==0) {
CGRect currectFrame=self.view.frame;
CGFloat bottom=currectFrame.size.height-loginButton.frame.origin.y-loginButton.frame.size.height;
change=[self keyboardEndingFrameHeight:[aNotification userInfo]];
if (change>bottom) {
change=change-bottom;
}
currectFrame.origin.y=currectFrame.origin.y - change;
self.view.frame=currectFrame;
}
}
-(void)keyboardWillDisappear:(NSNotification *)aNotification{
self.view.frame=viewFrame;
change=0.0;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在iOS9.0及以后,UIAlertView被UIAlertController替代,其使用方法为
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ios中如何显示一个数据加载中的等待窗口(UIAlertView实现的PopupView样式弹窗)
其核心是在AlertView中加载一个Activity indicator view
-(void)showActivityIndicator
{
alertView = [[UIAlertView alloc] initWithTitle:@"数据加载中..." message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles: nil];
NSString *iosVersion = [[UIDevice currentDevice]systemVersion];
NSLog(@"iosVersion:%d",[[iosVersion substringToIndex:1]intValue]);
if ([[iosVersion substringToIndex:1]intValue] > 6)
{
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[indicator startAnimating];
[alertView setValue:indicator forKey:@"accessoryView"];
}
[alertView show];
}
-(void)dismissActivityIndicator
{
[alertView dismissWithClickedButtonIndex:0 animated:YES];
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iRa中功能学习
1.SIM卡侦测
使用框架CoreTelephony.framework
CTTelephonyNetworkInfo *networkInfo = [[CTTelephonyNetworkInfo alloc]init];
CTCarrier *carrier = networkInfo.subscriberCellularProvider;
// carrier.mobileCountryCode -- 国家代码 mcc:国家代码(3位)(中国:460,台湾:466)
// carrier.mobileNetworkCode -- mnc:运营商网络代码(2位)(46000中国移动td,46001中国联通,46002中国移动gsm,46003中国电信)
if (carrier.mobileCountryCode == nil || [carrier.mobileCountryCode isEqualToString:@""]) {//此处通过国家代码侦测是否已插入sim卡
//未插入SIM卡
}else{
//已插入SIM卡
}
2.侦测是否已开启3G网络
使用第三方类库Reachability
Reachability ability=[Reachability currentReachabilityStatus];
[ability startNotifier]
NetworkStatus internetStatus = [ability currentReachabilityStatus];
typedef enum : NSInteger {
NotReachable = 0, //Can't connect to the internet.
ReachableViaWiFi, //The connection to the internet via WiFi has been established
ReachableViaWWAN //The connection to the internet via WWAN has been established.
} NetworkStatus;
3.获取iOS系统版本
NSString *iosVersion = [[UIDevice currentDevice]systemVersion];
4.LCD测试
每1.3s播放一张图片,仅此而已!!
5.加速器测试/ 陀螺仪
使用框架CoreMotion.framework
//accelerometer = 加速计,加速度传感器 (侦测手机的摆放姿态)
//startAccelerometerUpdatesToQueue:withHandler:
CMMotionManager *motionManager = [[CMMotionManager alloc]init];
motionManager.accelerometerUpdateInterval = 0.2;//设置加速计更新数据的时间,此为0.2s抓取一次数据
//加速器侦测数据的方法
[self.motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMAccelerometerData *accelerometerData,NSError *error)
{
CMAcceleration acceleration = accelerometerData.acceleration;
//x的值:acceleration.x
//y的值:acceleration.y
//z的值:acceleration.z
// 通过侦测x, y, z的值的取值范围,侦测是否处于屏幕向上,屏幕向下,屏幕向左,向右,向前,向后
//手机平放到桌面上,home键靠近自己,且朝上
//x表示横向的值,y表示竖向的值,z表示垂直于桌面方向的值
//出现错误时,error!=nil
}];
//fabs(rotation.y) -- 求浮点数的绝对值
// gyro = 陀螺仪,回转仪 -- 侦测自身旋转方向 陀螺仪(gyroscope),又叫角速度传感器,
//他的测量物理量是偏转,倾斜时的转动角速度。是一种用来传感与维持方向的装置,基于角动量守恒的理论设计出来的
//startGyroUpdatesToQueue:withHandler:
motionManager.gyroUpdateInterval = 0.2;//设置陀螺仪更新数据的时间,此为0.2s抓取一次数据
[self.motionManager startGyroUpdatesToQueue:[NSOperationQueue currentQueue]withHandler:^(CMGyroData *gyroData,NSError *error){
CMRotationRate rotation=gyroData.rotationRate;
//x的值 rotation.x
//y的值 rotation.y
//z的值 rotation.z
// 通过前后两次侦测到的x,y,z的值的变化范围来判定是否ok
//角速度有3个表示,分别是沿着垂直于x轴的面上的旋转速度,垂直于y轴方向上的旋转速度,垂直于z轴方向的旋转速度
//由此可知道当前正朝着那个方向运动,所以用语导航和游戏控制
}];
6.震动马达测试(vibration)-- 手动测试通过比对震动次数和用户点击次数比对来判定是否pass,而自动测试通过震动并观察陀螺仪是否有变动来判定是否pass
使用AudioToolbox.framework
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate); //控制手机震动
//手动测试的方法:随即震动n次,然后让op点击屏幕n次,如果前后次数相等则测试pass,否则测试fail
如何自动以用户点击屏幕的事件:(使用UIKit中的UITapGestureRecognizer)
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleGesture:)];
-(void)handleGesture:(UIGestureRecognizer *)gestureRecognizer
{
/*CGPoint p = [gestureRecognizer locationInView:self.view];//获取点击位置
if (CGRectContainsPoint(mySensitiveRect, p)) {//比较一个CGPoint是否在一个Rect之内
NSLog(@"got a tap in the region i care about");
}else{
NSLog(@"got a tap, but not wherr i need it");
}*/
tapNum++;
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
}
如何设置震动马达的震动的频率和时间长度和次数
NSMutableDictionary *dictShort = [NSMutableDictionary dictionary];
NSMutableArray *arrShort = [NSMutableArray array];
[arrShort addObject:[NSNumber numberWithBool:YES]];//vibrate for 500ms
[arrShort addObject:[NSNumber numberWithInt:500]];
[arrShort addObject:[NSNumber numberWithBool:NO]];//stop for 200ms
[arrShort addObject:[NSNumber numberWithInt:200]];//可使用多次像上边这样的重复设置来控制震动的长度和间隔
[dictShort setObject:arrShort forKey:@"VibePattern"];
[dictShort setObject:[NSNumber numberWithInt:1] forKey:@"Intensity"];
AudioServicesPlaySystemSoundWithVibration(4095,nil,dictShort);
7.GPS测试(GPS)&指南针测试(compass) -- gps测试是根据当前的工厂位置和所定位的位置进行比对判定是否pass,指南针测试是看用户转动手机,是否可正确指示方向判定是否pass
使用CoreLocation.framework
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[CLLocationManager locationServicesEnabled] // 侦测GPS是否开启
在alloc实例后,需要设置以下参数项,然后在delegate方法中获取到最新的数据
locationManager.delegate = self; //设置代理对象 必须设置
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; //设置定位精度(desired:期望,Accuracy精度)必须设置
locationManager.distanceFilter = kCLDistanceFilterNone; //设置过滤方法,即距离变更多少的时候触发delegate方法 必须设置
[locationManager startUpdatingLocation]; //开始GPS位置侦测 --- GPS测试使用
[locationManager stopUpdatingLocation]; //停止GPS位置侦测 --- GPS测试使用
//测试GPS所使用的delegate方法如下
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ //ios6.0之后
CLLocation *newLocation = [locations lastObject];
//获取到当前位置的经纬度,从而实现定位
//newLocation.horizontalAccuracy — 位置的精度(半径)。位置精度通过一个圆表示,实际位置可能位于这个圆内的任何地方。
//这个圆是由coordinate(坐标)和 horizontalAccuracy(半径)共同决定的,horizontalAccuracy的值越大,那么定义的圆就越大,因此位置精度就越低。
//如果horizontalAccuracy的值为负, 则表明coordinate的值无效。
//newLocation.coordinate.latitude -- 纬度
//newLocation.coordinate.longitude -- 经度
//newLocation.verticalAccuracy — 海拔高度的精度。为正值表示海拔高度的误差为对应的米数;为负表示altitude(海拔高度)的值无效。
//newLocation.altitude — 海拔高度。正数表示在海平面之上,而负数表示在海平面之下。
//newLocation.speed — 速度。该属性是通过比较当前位置和前一个位置,并比较它们之间的时间差异和距离计算得到的。
//鉴于Core Location更新的频率,speed属性的值 不是非常精确,除非移动速度变化很小。
//在iRa中,首先获取到
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
if(error.code == kCLErrorLocationUnknown) {
NSLog(@"Currently unable to retrieve location."); }
else if(error.code == kCLErrorNetwork) {
NSLog(@"Network used to retrieve location is unavailable."); }
else if(error.code == kCLErrorDenied) {
NSLog(@"Permission to retrieve location is denied.");
[manager stopUpdatingLocation]; }
}
可根据实际情况来指定位置精度。例如,对于只需确定用户在哪个国家的应用程序,没有必要要求Core Location的精度为10米。要指定精度,可在启动位置 更新前设置位置管理器的desiredAccuracy。有6个表示不同精度的枚举值:
extern const CLLocationAccuracy kCLLocationAccuracyBestForNavigation;
extern const CLLocationAccuracy kCLLocationAccuracyBest;
extern const CLLocationAccuracy kCLLocationAccuracyNearestTenMeters;
extern const CLLocationAccuracy kCLLocationAccuracyHundredMeters;
extern const CLLocationAccuracy kCLLocationAccuracyKilometer;
extern const CLLocationAccuracy kCLLocationAccuracyThreeKilometers;
对位置管理器启动更新后,更新将不断传递给位置管理器委托,直到停止更新。
要消失GPS在地图上的位置,可使用MapKit.framework中的MKMapView,--- MKMapView就是一个地图
对MKMapView,最基本的操作需要设置两项内容
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
self.mapView.showsUserLocation = YES;
self.mapView.delegate = self;
- (void) mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{//此为MKMapView显示当前GPS定位的方法
self.mapView.centerCoordinate = userLocation.location.coordinate;
}
//所显示地图类型的设置
self.mapView.mapType = MKMapTypeSatellite //卫星图
self.mapView.mapType = MKMapTypeStandard
//地图的放大与缩小
MKUserLocation *userLocation = self.mapView.userLocation;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.location.coordinate, 2000, 2000);
[self.mapView setRegion:region animated:NO];
//判定GPS定位服务是否开启/指南针功能是否开启的方法
if ([CLLocationManager locationServicesEnabled] && [CLLocationManager headingAvailable])
{
[self.locationManager startUpdatingLocation];
[self.locationManager startUpdatingHeading];
}
//位置管理器有一个headingAvailable属性,它指出设备是否装备了磁性指南针。如果该属性为YES,就可以使用Core Location来获取航向(heading)信息。
//测试compass(指南针)所使用的代理方法
[CLLocationManager headingAvailable] // 侦测设备是否支持指南针服务
locationManager.headingFilter = kCLHeadingFilterNone; //设置过滤侦测角度,即heading变化多少触发delegate方法 必须设置
[locationManager startUpdatingHeading]; //开始磁力侦测 --- compass测试使用
[locationManager stopUpdatingHeading]; //停止磁力侦测 --- compass测试使用
//实现以下delegate方法
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在获取到指南方向后,需要控制UI上的一个图片跟随旋转,其实现方法如下:
self.view.layer.anchorPoint = CGPointMake(0.5, 0.5);//set the anchorPoint anchor==锚
if ([iPhonePlatform hasPrefix:@"iPad"]) {//设置UIImage对象的center,即旋转时的中心点
self.arrowImage.center = CGPointMake(386, 320);
}else
self.arrowImage.center = CGPointMake(158, 240);
if ([UIImage respondsToSelector:@selector(setTranslatesAutoresizingMaskIntoConstraints:)]) {//关闭旋转时自动调节大小功能
self.arrowImage.translatesAutoresizingMaskIntoConstraints = NO;//rotate UIView around its center keeping its size
}
CGAffineTransform transform = CGAffineTransformMakeRotation(heading);//获取旋转参数
self.arrowImage.transform = transform;//控制图片旋转
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
无论是trueHeading还是magneticHeading,在实际指南针的比对时,都需要有一个根据当前设备的姿态的参数转换,起转换方式如下
- (float)magneticHeading: (float)heading{
float realHeading = heading;
switch ([UIDevice currenctDevice].orientation){
case UIDeviceOrientationPortrait:
break;
case UIDeviceOrientationPortraitUpsideDown:
realHeading = realHeading + 180.0f;
break;
case UIDeviceOrientationLandscapeLeft:
realHeading = realHeading + 90.0f;
break;
case UIDeviceOrientationLandscapeRight:
realHeading = realHeading - 90.0f;
break;
default:
break;
}
while (realHeading > 360.0f){
realHeading = realHeading - 360;
}
return realHeading;
}
8.闪光灯测试 -- 手电筒
使用AVFoundation.framework中的AVCaptureDevice
AVCaptureDevice *device=[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device lockForConfiguration:nil]) {
if (device.torchMode==AVCaptureTorchModeOn) {
[device setTorchMode:AVCaptureTorchModeOff];
}else{
[device setTorchMode:AVCaptureTorchModeOn];
}
}
[device unlockForConfiguration];
9.边缘触控检测方法
目前实现的测试方法其核心是按照屏幕的大小,全部铺满UIButton,之后检测是否每个button都被按到。
其操作核心是
1.用code的方式创建button和其响应方法并设置frame和一些基本属性,以及创建后在UI上的显示
2.要实现多点触动的侦测
UIButton *subBtn = [UIButton buttonWithType:UIButtonTypeCustom];//UIButtonTypeRoundedRect
[subBtn setTitle:@"X" forState:UIControlStateNormal];
[subBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
subBtn.frame = CGRectMake(index * (btnWidth + Width_Space) + Start_X, page * (btnHeight + Height_Space)+Start_Y, btnWidth, btnHeight);
subBtn.multipleTouchEnabled = YES;
subBtn.userInteractionEnabled = NO;
subBtn.opaque = NO;
subBtn.alpha = 0.8;
subBtn.tag = i;
[self.view addSubview:subBtn];
[self.baseButton addTarget:self action:@selector(touchesMoved:withEvent:) forControlEvents:UIControlEventAllTouchEvents];
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
for (UITouch *touch in touches){
CGPoint touchLocation = [touch locationInView:self.view];
for (NSInteger i = 1 ; i <= touchTTL; i++){
UIButton *btn = (UIButton *)[self.view viewWithTag:i];
if (CGRectContainsPoint(btn.frame, touchLocation))
{
btn.backgroundColor = [UIColor cyanColor];
[touchArray replaceObjectAtIndex:(i-1) withObject:[NSNumber numberWithBool:YES]];
break;
}
}
}
}
10.感距测试(接近传感器)
UIDevice *device = [UIDevice currentDevice];
device.proximityMonitoringEnabled = YES; //proximit = 接近
device.proximityState==1
device.proximityState==0
11.如何侦测耳机是否已插入
ios7,8,9使用AVFoundation.framework
AVAudioSessionRouteDescription *route = [[AVAudioSession sharedInstance]currentRoute]; //Route-途径
for (AVAudioSessionPortDescription* desc in [route outputs]){
if ([[desc portType] isEqualToString:AVAudioSessionPortHeadphones]){
//耳机已插入
}
}
iOS5,6使用AudioToolbox.framework
AudioSessionInitialize(NULL, NULL, NULL, NULL);
UInt32 routeSize;
AudioSessionGetPropertySize(kAudioSessionProperty_AudioRouteDescription, &routeSize);
CFDictionaryRef desc;
AudioSessionGetProperty(kAudioSessionProperty_AudioRouteDescription, &routeSize, &desc);
CFArrayRef outputs = CFDictionaryGetValue(desc, kAudioSession_AudioRouteKey_Outputs);
CFDictionaryRef dict = CFArrayGetValueAtIndex(outputs,0);
CFStringRef output = CFDictionaryGetValue(dict, kAudioSession_AudioRouteKey_Type);
if (CFStringCompare(output, kAudioSessionOutputRoute_Headphones,0) == kCFCompareEqualTo) {
//耳机已插入
}
12.如何播放app本身所带的视频
使用MediaPlayer.framework
NSURL *movieURL = [NSURL [[NSBundle mainBundle] pathForResource:@"movie" ofType:@"mp4"]];
MPMoviePlayerController *theMovie=[[MPMoviePlayerController alloc] initWithContentURL: movieURL];
//theMovie.scalingMode = MPMovieScalingModeAspectFill;
theMovie.repeatMode = MPMovieRepeatModeOne;
theMovie.controlStyle = MPMovieControlStyleNone;
//theMovie.controlStyle = MPMovieControlStyleEmbedded;
//theMovie.controlStyle = MPMovieControlStyleFullscreen;
//theMovie.view.transform = CGAffineTransformConcat(theMovie.view.transform, CGAffineTransformMakeRotation(M_PI_2));
UIWindow *backgroundWindow = [[UIApplication sharedApplication]keyWindow];
[theMovie.view setFrame:backgroundWindow.frame];
[backgroundWindow addSubview:theMovie.view];
// Movie playback is asynchronous, so this method returns immediately.
[theMovie play];
//可添加对播放结束的侦测,并添加此时对界面的切换 playback -- 播放设备
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(myMovieFinishedCallback:) name: MPMoviePlayerPlaybackDidFinishNotification object: theMovie];
在通知方法中实现[myMovie.view removeFromSuperview];来消除视频播放界面,同时可注销通知的监听
12. 后置摄像头实现二维码扫描功能--可用于后置摄像头的功能检测--使用AVFoundation
//定义一个capture session 验证ok
AVCaptureSession *captureSession=[[AVCaptureSession alloc]init];
//1.定义session输入
NSError *error;
AVCaptureDevice *captureDevice=[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input=[AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
[captureSession addInput:input];
//定义session输出
AVCaptureMetadataOutput *captureMetadataOutput=[[AVCaptureMetadataOutput alloc]init];
[captureSession addOutput:captureMetadataOutput];
// [captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// [captureMetadataOutput setMetadataObjectTypes:[captureMetadataOutput availableMetadataObjectTypes]];
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create("myQueue", NULL);
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
[captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObjects:AVMetadataObjectTypeQRCode, nil]];
//设定session的可视化输出
AVCaptureVideoPreviewLayer *videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:captureSession];
[videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[videoPreviewLayer setFrame:baseview.frame];//baseView是在UIView上定义的视频预显示区域,可使一个UIView对象
[self.view.layer addSublayer:videoPreviewLayer];
//开始运行
[captureSession startRunning];
要想实现直接的扫描二维码功能,需要在实现AVCaptureMetadataOutput的代理AVCaptureMetadataOutputObjectsDelegate对抓取的数据进行处理
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{//验证ok
if (metadataObjects != nil && [metadataObjects count] > 0)
{
AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode])
{
NSLog(@"扫描到的字符:%@",[metadataObj stringValue]);
[captureSession stopRunning];
}
}
}
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
CGRect highlightViewRect = CGRectZero;
AVMetadataMachineReadableCodeObject *barCodeObject;
NSString *detectionString = nil;
NSArray *barCodeTypes = @[AVMetadataObjectTypeUPCECode,AVMetadataObjectTypeCode39Code,
AVMetadataObjectTypeCode39Mod43Code,AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode93Code,
AVMetadataObjectTypeCode128Code,AVMetadataObjectTypePDF417Code,
AVMetadataObjectTypeQRCode,AVMetadataObjectTypeAztecCode];
for (AVMetadataObject *metadata in metadataObjects) {
for (NSString *type in barCodeTypes) {
if ([metadata.type isEqualToString:type]) {
barCodeObject = (AVMetadataMachineReadableCodeObject *)[_videoPreviewLayer transformedMetadataObjectForMetadataObject:(AVMetadataMachineReadableCodeObject *)metadata];
highlightViewRect = barCodeObject.bounds;
detectionString = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];//detection string是扫描到的字符
}
}
}
}
13.如何播放app本身内部所带的音频文件--声音播放
使用AVFoundation.framework中的AVAudioPlayer
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:beepURL error:&error];
[audioPlayer prepareToPlay];
其中有play, pause, stop, enableRate, delegate, numberOfLoops等参数可设置
播放声音之前,如何设定播放方式,比如是通过听筒还是扬声器
An audio session is a singleton object
1.耳机插入后,直接默认的就是耳机播放。拔出耳机后,默认的恢复到插入耳机之前的状态,即之前是听筒播放就恢复成听筒,是扬声器播放就恢复成扬声器
2.设置听筒播放的方法:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];//建立连接
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];//设置session种类
//设置为receiver(听筒)播放
NSError *error;
if ([audioSession respondsToSelector:@selector(overrideOutputAudioPort: error:)]) {//iOS 6.0及以上
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:&error];
}else{//iOS 6.0及以下
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None;
AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
}
[audioSession setActive:YES error:&error];
//设置为speaker(扬声器)播放
NSError *error;
if ([audioSession respondsToSelector:@selector(overrideOutputAudioPort: error:)]) {//iOS 6.0及以上
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
}else{//iOS 6.0及以下
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
}
[audioSession setActive:YES error:&error];
系统声音服务(System Sound Services)--AudioToolBox.framework
提供了一个接口,用于播放不超过30s的声音,他支持的文件格式有限,只有CAF,AIF和使用PCM或IMA/ADPCM数据的WAV文件
用词方法播放一个声音文件的方法步骤如下:
NSURL *url=[[NSBundle mainBundle] URLForResource:@"beep" withExtension:@"mp3"];
SystemSoundID soundid;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundid); //创建声音id -SoundID
AudioServicesPlaySystemSound(soundid); //播放声音
//AudioServicesPlayAlertSound(soundid); -- 播放声音同时震动
//AudioServicesDisposeSystemSoundID(soundid); -- 销毁声音
使用AVAudioPlayer播放音频
--用来播放声音时,所声明的变量不能是局部变量,否则播放没有声音,也不报错
--要想使用外音播放,必须设置AVAudioSession,否则也容易引起没声音的问题(此session也需要时全局变量)
- (IBAction)playBeep:(id)sender {
NSURL *url=[[NSBundle mainBundle] URLForResource:@"audio4" withExtension:@"mp3"];
NSError *error;
AVAudioPlayer *audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
audioPlayer.delegate=(id)self;
audioPlayer.numberOfLoops=-1;//<0表示无限次,=0表示1次,>0表示n+1次
audioPlayer.volume=0.8;//音量0.0-1.0之间
audioPlayer.currentTime=15.0;//可以指定从任意位置开始播放
NSUInteger channels=audioPlayer.numberOfChannels;//只读属性
NSTimeInterval duration=audioPlayer.duration;//获取持续时间
audioPlayer.meteringEnabled=YES;//开启仪表计数功能
[audioPlayer updateMeters];//更新仪表计数
[audioPlayer prepareToPlay];//分配播放所需要的资源,并将其加入到内部播放队列
[audioPlayer play];//播放
}
- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player{
//处理中断代码
}
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player{
//外部中断结束,重新回到应用程序时执行
}
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withFlags:(NSUInteger)flags{
}
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withOptions:(NSUInteger)flags{
}
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error{
//解码错误
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
//播放完成
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
使用AVAudioRecorder+AVAudioSession录音
1.定义录制声音的存放文件和路径
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
NSString *soundFilePath = [docsDir stringByAppendingPathComponent:@"sound.caf"];
NSURL *tempSoundFileURL = [NSURL fileURLWithPath:soundFilePath];
2.定义录制声音所必须要的参数设置
NSDictionary *recordSettings = [NSDictionary
dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:AVAudioQualityMin],
AVEncoderAudioQualityKey,
[NSNumber numberWithInt:16],
AVEncoderBitRateKey,
[NSNumber numberWithInt: 2],
AVNumberOfChannelsKey,
[NSNumber numberWithFloat:44100.0],
AVSampleRateKey,
nil];
3.设置audio session工作模式和所要使用的录音设备(通常下面一个麦克风,背部上边一个麦克风)
audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&theError];
//ios > 5.0时,所需要的设置方法比较简单一些
[audioSession setMode:AVAudioSessionModeVideoRecording error:&theError]; //Front built-in microphone
[audioSession setMode:AVAudioSessionModeMeasurement error:&theError];//bottom built-in microphone
[audioSession setActive:YES error:&theError];//使设置立即生效
// iOS < 5.0时,所需要的设置方法为:
//1. 找出内置麦克风的port资源
// Get the set of available inputs. If there are no audio accessories attached, there will be
// only one available input -- the built in microphone.
NSArray* inputs = [audioSession availableInputs];
// Locate the Port corresponding to the built-in microphone.
AVAudioSessionPortDescription* builtInMicPort = nil;
for (AVAudioSessionPortDescription* port in inputs){
if ([port.portType isEqualToString:AVAudioSessionPortBuiltInMic]){//内置麦克风的描述字段
builtInMicPort = port;
break;
}
}
//2.设置录音所使用的麦克风设备
// loop over the built-in mic's data sources and attempt to locate the front microphone or bottom microphone
AVAudioSessionDataSourceDescription* microphoneDataSource = nil;
for (AVAudioSessionDataSourceDescription* source in builtInMicPort.dataSources){
if ([source.orientation isEqual:AVAudioSessionOrientationFront]){ //front的麦克风,AVAudioSessionOrientationBottom == bottom的麦克风
microphoneDataSource = source;
[builtInMicPort setPreferredDataSource:microphoneDataSource error:&theError];
[audioSession setPreferredInput:builtInMicPort error:&theError];
break;
}
} // end data source iteration
4. 初始化audio recorder并开始录音
AVAudioRecorder *audioRecorder = [[AVAudioRecorder alloc] initWithURL:tempSoundFileURL settings:recordSettings error:&error];
[audioRecorder prepareToRecord];
//_audioRecorder.recording -- 正在录音
//_audioRecorder record --录音开始
//[_audioRecorder stop]; -- 停止录音
5.audio recorder的delegate方法
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag //正常录音结束
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error //编码错误
- (void)audioRecorderBeginInterruption:(AVAudioRecorder * _Nonnull)recorder //出现中断
- (void)audioRecorderEndInterruption:(AVAudioRecorder * _Nonnull)recorder //结束中断,回到app
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14. iRa手动线中通过网络显示一个网页,来判定Wifi/网络是否OK
UIWebView的使用,直接LoadRequest实现加载http://www.baidu.com, UIWebView就是一个微型浏览器
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
15. 获取网络的IP地址,
-(NSString *)getWiFiIPAddress
{
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
NSString *wifiAddress = nil;
NSString *cellAddress = nil;
NSString *addr;
if (!getifaddrs(&interfaces))
{
//Loop through linked list of interfaces
temp_addr = interfaces;
while (temp_addr !=NULL)
{
sa_family_t sa_tyep = temp_addr->ifa_addr->sa_family;
if (sa_tyep == AF_INET || sa_tyep ==AF_INET6)
{
NSString *name = [NSString stringWithUTF8String:temp_addr->ifa_name];
addr = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
if ([name isEqualToString:@"en0"])
{//wifi地址
wifiAddress = addr;
cellAddress = @" ";
}
else if ([name isEqualToString:@"pdp_ip0"])
{//数字网络地址
cellAddress = addr;
wifiAddress = @" ";
}
else
wifiAddress = @" ";
}
temp_addr = temp_addr->ifa_next;
}
//free memory
freeifaddrs(interfaces);
}
return wifiAddress;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS CPU和内存信息读取
//CPU Frequency
int cpuFreq;
int mib[2];
mib[0] = CTL_HW;
mib[1] = HW_CPU_FREQ;
size_t length = sizeof(cpuFreq);
if (sysctl(mib,2,&cpuFreq,&length,NULL,0)<0)
perror("getting cpu frequency");
double cpuFreqd=(double)cpuFreq/1000000000;
self.cpuFreqButton.text = [[NSString alloc]initWithFormat:@"%.2f GHz",cpuFreqd];
//Number of CPUs
int nCpu;
mib[0] = CTL_HW;
mib[1] = HW_NCPU;
length = sizeof(nCpu);
if (sysctl(mib,2,&nCpu,&length,NULL,0))
perror("getting the number of CPUs");
self.cpuNoButton.text = [[NSString alloc]initWithFormat:@"%u",nCpu];
//Non-kernel Memory
int nonkernelMem;
mib[0] = CTL_HW;
mib[1] = HW_USERMEM;
length = sizeof(nonkernelMem);
if (sysctl(mib,2,&nonkernelMem,&length,NULL,0))
perror("getting non-kernel memory");
double nonkernelMemGB = (double)nonkernelMem/1024/1024/1024;
self.userMemButton.text = [[NSString alloc]initWithFormat:@"%.2f GB",nonkernelMemGB];
//Total Memory(Physical RAM)
uint64_t physicalMem;
mib[0] = CTL_HW;
mib[1] = HW_MEMSIZE;
length = sizeof(physicalMem);
if (sysctl(mib,2,&physicalMem,&length,NULL,0))
perror("getting physical memory");
double physicalMemGB = (double)physicalMem/1024/1024/1024;
self.totalMemButton.text = [[NSString alloc]initWithFormat:@"%.2f GB",physicalMemGB];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ios9.0+xcode7.0在访问http的时候会出现错误“the resource could not be loaded because the App Transport Secunity policy requires a secure connection”
解决方法是在Info.plist中手动添加以下设置项目
造成这种现象的原因为
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OC如何删除一行中所有的空白和换行符
[[string componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsJoinedByString:@""]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OC如何实现sha1以及sha224等加密方式
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
//常用加密方式有sha1,sha224,sha256,sha384,sha512, S H A = Secure Hash Algorithm
//以上两个头文件必须使用,
//函数CC_SHA1数字可变动,参数CC_SHA1_DIGEST_LENGTH数字可变动实现不同的加密方式
-(NSString *)sha1{
const char *cstr=[self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data=[NSData dataWithBytes:cstr length:self.length];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, (int)data.length, digest);
NSMutableString *output=[NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH*2];
for (int i=0; i<CC_SHA1_DIGEST_LENGTH; i++) {
[output appendFormat:@"%02x",digest[i]];
}
return output;
}
-(NSString *)sha256{
const char *cstr=[self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data=[NSData dataWithBytes:cstr length:self.length];
uint8_t digest[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(data.bytes, (int)data.length, digest);
NSMutableString *output=[NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
for (int i=0; i<CC_SHA256_DIGEST_LENGTH; i++) {
[output appendFormat:@"%02x",digest[i]];
}
return output;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
JSON string到字典以及字典到json string的转换方法
-(NSDictionary *)toDictionaryForJsonString{
NSDictionary *dict = nil;
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
if (jsonData)
{
NSError *error;
dict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
}
return dict;
}
-(NSString *)dictionaryToJsonStandard{
NSString *jsonString = nil;
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self
options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
error:&error];
if (! jsonData) {
NSLog(@"Got an error: %@", error);
} else {
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
return jsonString;
}
从json文件中读取关键key的值
#define JSONFILE @"/vault/data_collection/test_station_config/gh_station_info.json"
NSData *data=[NSData dataWithContentsOfFile:JSONFILE];
json=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
-(NSString *)site{
return [[json valueForKey:@"ghinfo"]objectForKey:@"SITE"];
}//FXZZ & FXGL
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ios上如何实现隐藏键盘的功能?
->点击背景view实现隐藏键盘
1. 在storyboard,点击背景view,将他的custom class设置为UIControl
2. 右击背景view弹出面板,添加touch down事件,实现如下方法
[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
->点击键盘上的return键,隐藏键盘
3. 对于ios上的文本框,在处于编辑状态时,自动弹出键盘,要想实现编辑完成后隐藏键盘,需添加Did End On Exit事件,实现如下方法
[sender resignFirstResponder];
4. 如何实现点击文本框时弹出时间选择器UIDatePicker
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iOS中如何能够更好的使用Autolayout
其应用的关键是center的使用以及相对于边缘的关系的定义。
可首先在view上边创建一个button,设置为diable和hidden,然后设置次button在整个视图的中间位置
然后所有创建的其它的控件都要使用次button作为基准点,建立他们的相对关系。从而达到完美Autolayout的目的。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ios autolayout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
添加信任账户信息
设置->通用->描述文件->开发商应用->选择账户->点击并在其中选择验证信任
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Xcode 7.0上开发的ios app对iphone 6是屏幕适配的,但是默认情况下,对iphone 5s的屏幕是不适配的
这造成app在iphone 5s上运行的时候,上下分别出现一个黑边,状态栏等也不是靠向最上边
需要创建一个名字为Default-568h@2x.png的640x1136大小的图片来替代launch screen,从而达到自适配iphone 5s屏幕的目的
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OC中判定某个object是否是某个class的实例
BOOL result = [object isKindOfClass:[NSDictionary class]]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!@! ios电池各种参数的侦测方法实例
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。