Learn Mac os/iOS program


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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可表示多达8byte

unsigned long a = 0xFFFFFFFFFFFFFFFF;

NSLog(@"%lu",a); //lx可表示多达8byte   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}mn都是非负数,最少匹配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:匹配xy,如“(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

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的递归调用

代码块想要递归调用,代码块变量必须是全局变量或者是静态变量,这样在程序启动的时候代码块变量就初始化了,可以递归调用

  1. static void (^ const blocks)(int) = ^(int i)  
  2. {  
  3.     if (i > 0) {  
  4.         NSLog(@"num:%d", i);  
  5.         blocks(i - 1);  
  6.     }  
  7. };  
  8. blocks(3); 

~~~~~~

//使用示例6 -- block可直接使用和改变全局变量

  1. int global = 1000;  
  2. int main(int argc, const char * argv[])  
  3. {  
  4.     @autoreleasepool {  
  5.         void(^block)(void) = ^(void)  
  6.         {  
  7.             global++;  
  8.             NSLog(@"global:%d", global);  
  9.         };  
  10.         block();  
  11.         NSLog(@"global:%d", global);  
  12.     }  
  13.     return 0;  

运行打印结果:

global:1001

global:1001

~~~~~~

//使用示例7 -- block可直接使用局部变量,但改变局部变量需要在变量前加上关键字__block, 否则不能通过编译

  1. __block int local = 500;  
  2. void(^block)(void) = ^(void)  
  3. {  
  4.     local++;  
  5.     NSLog(@"local:%d", local);  
  6. };  
  7. block();  
  8. NSLog(@"local:%d", local); 

运行打印结果:

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>Disabledkey>  --> 改为Enabled

        <true/>


开启后的根目录为$HOME --- 使用ftp localhost验证即可

用户名&密码跟电脑的一样

开启SFTP需要在System Preferences -> sharing,勾上"Remote Login” --- 使用sftp localhost验证即可

~~~~~~

开启Apache

#sudo apachectl start

  1. 打开Apche的配置文件,/etc/apache2/httpd.conf
  2. httpd.conf中找到#Include /private/etc/apache2/extra/httpd-vhosts.conf,去掉前面的#,保存。
  3. 打开Apache虚拟主机配置文件,/etc/apache2/extra/httpd-vhosts.conf
  4. 注释掉文件中配置的2个虚拟主机例子

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:多少字


lsKMG为单位查看文件大小

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.启动 Apachesudo apachectl start

4.停止 Apachesudo apachectl stop

5.重启 Apachesudo 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等字段,

之前这些都是预设的不用加,现在强制了

  • NSContactsUsageDescription -> 通讯录
  • NSMicrophoneUsageDescription -> 麦克风
  • NSPhotoLibraryUsageDescription -> 相册
  • NSCameraUsageDescription -> 相机
  • NSLocationAlwaysUsageDescription -> 地理位置
  • NSLocationWhenInUseUsageDescription -> 地理位置


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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,加入如下设置:

   ...........

   NSAppTransportSecurity

   

         NSAllowsArbitraryLoads

        

   


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//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安装所在位置  /usr/local/Cellar/nginx-full/1.10.1/bin/nginx
  • nginx配置文件所在位置  /usr/local/etc/nginx/nginx.conf
  • nginx服务器根目录所在位置  /usr/local/var/www

//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

其中rtmp1935之后路径设置“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;

        }

    }

}

  1. //所增加协议配置的说明
  2. 1. rtmp是协议名称
  3. 2. server 说明内部中是服务器相关配置
  4. 3. listen 监听的端口号, rtmp协议的默认端口号是1935
  5. 4. application 访问的应用路径是 abcd 或者 hls
  6. 5. live on; 开启实时
  7. 6. record off; 不记录数据
  1. 7. hls on; 开启hls
  1. 8. hls_path; ts文件存放路径
  1. 9. hls_fragment 5s; 每个TS文件包含5秒的视频内容


// 修改~/.bash_profile之后,重新加载配置的方法source file


//m3u8文件的结尾处添加如下行,将表示点播功能,如果没有此行,将为直播模式

#EXT-X-ENDLIST


//设置系统默认的xcode版本

xcode-select --switch


//查看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不可以省略


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[email protected]

1dpbg1e


user: [email protected]

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方法等



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ARmodel.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

#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];

}


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

如何改变UITableViewHeader的背景色(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];



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

使用UIBezierPathCAShapLayer实现画圆的功能(此方法也可以实现画直线/画椭圆/画矩形等)

-(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,CGRectCGVectorCGAffineTransformUIEdgeInsetsUIOffset等都可以使用此方法转换



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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=显示

}



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

UITableViewUICollectionView在使用自定义的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

        {

            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:[email protected]?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 ()//用于处理采集信息的代理

{

    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

#import

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];  //停止监听



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

iOSHomePower键的测试(截屏键组合,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 *)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向上/向下弹出一个选择列表功能(参照实例FDTakeControllerNIDropDown.h)

使用独立类库NIDropDown.h来实现(QRCoderReader),其核心在于View的嵌套显示,大小调整以及动画的变化过程

1.在一个个的UIView的子类中如何实现动画显示效果的

在view由一个大小变更到另外一个大小的时候,已动画显示的设置如下:

[UIView beginAnimations:nil context:nil];//设置动画内容,档为nil/nil时,使用下文所设置内容

[UIView setAnimationDuration:0.5]; //设置动画时间,即要花费多长时间从现在的大小变化到目标大小

//设置目标大小,即变化后的大小

[UIView commitAnimations]; //开始动画

2.btnsuperview添加一个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 ios45,需要重写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及以后,UIAlertViewUIAlertController替代,其使用方法为

  • UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"My Alert"
  •                               message:@"This is an alert."
  •                               preferredStyle:UIAlertControllerStyleAlert];
  • UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
  •   handler:^(UIAlertAction * action) {}];
  • [alert addAction:defaultAction];
  • [self presentViewController:alert animated:YES completion:nil];



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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中国移动gsm46003中国电信)

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中,首先获取到

}

  • 应用程序开始跟踪用户的位置时,将在屏幕上显示一个是否允许定位的提示框。如果用户禁用定位服务,iOS不会禁止应用程序运行,但位置管理器将生成错 误。 
  • 第二个方法处理这种定位失败,该方法的参数指出了失败的原因。如果用户禁止应用程序定位,error参数将为kCLErrorDenied;如果Core Location经过努力 后无法确认位置,
  • error参数将为kCLErrorLocationUnknown;如果没有可供获取位置的源,error参数将为kCLErrorNetwork。 
  • 通常,Core Location将在发生错误后继续尝试确定位置,但如果是用户禁止定位,它就不会这样做;在这种情况下,应使用方法stopUpdatingLocation停 止位置管理器。 

-(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方法

  • -(BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager {
  •       return YES; 
  • }
  • -(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{

  • //第一个方法指定位置管理器是否向用户显示校准提示。该提示将自动旋转设备360°。由于指南针总是自我校准,因此这种提示仅在指南针读数剧烈波动时才 有帮助。当设置为YES后,提示可
  • //会分散用户的注意力,或影响用户的当前操作。 
  • //第二个方法的参数newHeading是一个CLHeading对象。CLHeading通过一组属性来提供航向读数:magneticHeading和trueHeading。这些值的单位为 度,类型为CLLocationDirection
  • //即双精度浮点数。这意味着: 
  • //如果航向为0.0,则前进方向为北; 
  • //如果航向为90.0,则前进方向为东; 
  • //如果航向为180.0,则前进方向为南; 
  • //如果航向为270.0,则前进方向为西。 
  • //CLHeading对象还包含属性headingAccuracy(精度)、timestamp(读数的测量时间)和description(这种描述更适合写入日志而不是显示给用户)。下面演 示了利用这个方法处理航向更新: 
  • //-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { 
  • //    if(newHeading.headingAccuracy >=0) { 
  • //        NSString *headingDesc = [NSString stringWithFormat:@"%.0f degrees (true), %.0f degrees (magnetic)",newHeading.trueHeading,newHeading.m
  • //        NSLog(@"%@",headingDesc); 
  • //    }
  • //}
  • //trueHeading和magneticHeading分别表示真实航向和磁性航向。如果位置服务被关闭了,GPS和wifi就只能获取magneticHeading(磁场航向)。只有打开 位置服务,才能获取
  • //trueHeading(真实航向)。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

在获取到指南方向后,需要控制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]){

      //耳机已插入

    }

}

iOS56使用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表示n1

    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{

    //播放完成

}


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

使用AVAudioRecorderAVAudioSession录音

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

#import

//常用加密方式有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

        [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

        [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上运行的时候,上下分别出现一个黑边,状态栏等也不是靠向最上边

需要创建一个名字为[email protected]的640x1136大小的图片来替代launch screen,从而达到自适配iphone 5s屏幕的目的



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

OC中判定某个object是否是某个class的实例

BOOL result [object isKindOfClass:[NSDictionary class]]



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

!@! ios电池各种参数的侦测方法实例

你可能感兴趣的:(Learn Mac os/iOS program)