The Mobile Galaxy The New Mobile Era Has Come | Mobile – A Time To Remember

30Mar/110

Draw routes-draw a path between two points

UIBezierPath* path = [UIBezierPath bezierPath];
[aPath moveToPoint:CGPointMake(50.0, 50.0)];
[aPath addLineToPoint:CGPointMake(10.0, 10.0)];
[aPath addLineToPoint:CGPointMake(10.0, 50.0)];
[aPath closePath];
then
[aPath stroke]

Share
Filed under: iPhone, Other No Comments
30Mar/110

UTF8<->GB2312

字符串编码转换函数 unicode转换成utf8 

/*! Turn "wide characters" as returned by some system calls 
(especially on Windows) into UTF-8. 

Up to \a dstlen bytes are written to \a dst, including a null 
terminator. The return value is the number of bytes that would be 
written, not counting the null terminator. If greater or equal to 
\a dstlen then if you malloc a new array of size n+1 you will have 
the space needed for the entire string. If \a dstlen is zero then 
nothing is written and this call just measures the storage space 
needed. 

\a srclen is the number of words in \a src to convert. On Windows 
this is not necessairly the number of characters, due to there 
possibly being "surrogate pairs" in the UTF-16 encoding used. 
On Unix wchar_t is 32 bits and each location is a character. 

On Unix if a src word is greater than 0x10ffff then this is an 
illegal character according to RFC 3629. These are converted as 
though they are 0xFFFD (REPLACEMENT CHARACTER). Characters in the 
range 0xd800 to 0xdfff, or ending with 0xfffe or 0xffff are also 
illegal according to RFC 3629. However I encode these as though 
they are legal, so that utf8towc will return the original data. 

On Windows "surrogate pairs" are converted to a single character 
and UTF-8 encoded (as 4 bytes). Mismatched halves of surrogate 
pairs are converted as though they are individual characters. 
*/ 

typedef unsigned short wchar_t; 

unsigned utf8fromwc(char* dst, unsigned dstlen, const wchar_t* src, unsigned srclen) { 
unsigned i = 0; 
unsigned count = 0; 
if (dstlen) for (;;) { 
unsigned ucs; 
if (i >= srclen) {dst[count] = 0; return count;} 
ucs = src; 
if (ucs < 0x80U) { 
dst[count++] = ucs; 
if (count >= dstlen) {dst[count-1] = 0; break;} 
} else if (ucs < 0x800U) { // 2 bytes 
if (count+2 >= dstlen) {dst[count] = 0; count += 2; break;} 
dst[count++] = 0xc0 | (ucs >> 6); 
dst[count++] = 0x80 | (ucs & 0x3F); 
#ifdef _WIN32 
} else if (ucs >= 0xd800 && ucs <= 0xdbff && i < srclen && 
src <= 0xdfff) { 
// surrogate pair 
unsigned ucs2 = src; 
ucs = 0x10000U + ((ucs&0x3ff)<<10) + (ucs2&0x3ff); 
// all surrogate pairs turn into 4-byte utf8 
#else 
} else if (ucs >= 0x10000) { 
if (ucs > 0x10ffff) { 
ucs = 0xfffd; 
goto J1; 

#endif 
if (count+4 >= dstlen) {dst[count] = 0; count += 4; break;} 
dst[count++] = 0xf0 | (ucs >> 18); 
dst[count++] = 0x80 | ((ucs >> 12) & 0x3F); 
dst[count++] = 0x80 | ((ucs >> 6) & 0x3F); 
dst[count++] = 0x80 | (ucs & 0x3F); 
} else { 
#ifndef _WIN32 
J1: 
#endif 
// all others are 3 bytes: 
if (count+3 >= dstlen) {dst[count] = 0; count += 3; break;} 
dst[count++] = 0xe0 | (ucs >> 12); 
dst[count++] = 0x80 | ((ucs >> 6) & 0x3F); 
dst[count++] = 0x80 | (ucs & 0x3F); 


// we filled dst, measure the rest: 
while (i < srclen) { 
unsigned ucs = src; 
if (ucs < 0x80U) { 
count++; 
} else if (ucs < 0x800U) { // 2 bytes 
count += 2; 
#ifdef _WIN32 
} else if (ucs >= 0xd800 && ucs <= 0xdbff && i < srclen-1 && 
src >= 0xdc00 && src <= 0xdfff) { 
// surrogate pair 
++i; 
#else 
} else if (ucs >= 0x10000 && ucs <= 0x10ffff) { 
#endif 
count += 4; 
} else { 
count += 3; 


return count; 
}

UTF-8, Unicode, GB2312格式串转换之C语言版 

http://www.cnblogs.com/kangshifu/archive/2008/10/16/1312544.html
/* author: wu.jian (吴剑) English name: Sword
/* date: 2007-12-13
/* purpose: 知识共享 

这几天工作上碰到了UTF-8转GB2312的问题,而且是在嵌入式的环境下,没有API可用,查了很多网上的资料,大多调用VC或者linux下自带的接口。在这里我将这两天的工作做个总结。
总的来说分为两大步(这里就不介绍基础知识了):

一、UTF8 -> Unicode
由于UTF8和Unicode存在着联系,所以不需要任何库就可以直接进行转换。首先要看懂UTF8的编码格式:
U-00000000 - U-0000007F: 0xxxxxxx 
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx 
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx 
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
前面几个1就代表后面几个字节是属于一起的。如果要解析一长串UTF8格式的字符串,这点就很有用了。下面这个函数就是判断前面几个1的(这里有define APP_PRINT printf,这样当release的时候将这个宏定义为空就行了,不需要一个一个去改,又方便重新调试):
int GetUtf8ByteNumForWord(u8 firstCh)
{
u8 temp = 0x80;
int num = 0;

while (temp & firstCh)
{
num++;
temp = (temp >> 1);
}

APP_PRINT("the num is: %d", num);
return num;
}
利用这个函数可以得到字符串中那几个字节是一起的。因为UTF8最大只有6个字节,所以就根据返回值来处理这里我只处理了3个字节和1个字节的UTF8的编码,因为一般来说中文在UTF8中是3个字节。

//将len个字节的UTF8格式的转换成GB2312格式存放在temp预先申请好的缓冲区中
void Utf8ToGb2312(const char* utf8, int len, char *temp)
{
APP_PRINT("utf8->unicode: \n");
APP_PRINT("utf8: [");
for (int k = 0; k < len; k++)
{
APP_PRINT("%02x ", utf8[k]);
}
APP_PRINT("]\n");

int byteCount = 0;
int i = 0;
int j = 0;

u16 unicodeKey = 0;
u16 gbKey = 0;

//循环解析
while (i < len)

switch(GetUtf8ByteNumForWord((u8)utf8 = utf8 = utf8 = utf8;
byteCount = 2;
break;

case 3:
//这里就开始进行UTF8->Unicode
temp[j + 1] = ((utf8 >> 2) & 0x0F);
temp[j] = ((utf8 & 0x03) << 6) + (utf8 & 0x3F);

//取得Unicode的值
memcpy(&unicodeKey, (temp + j), 2);
APP_PRINT("unicode key is: 0x%04X\n", unicodeKey);

//根据这个值查表取得对应的GB2312的值
gbKey = SearchCodeTable(unicodeKey);
APP_PRINT("gb2312 key is: 0x%04X\n", gbKey);

if (gbKey != 0)
{
//here change the byte
//不为0表示搜索到,将高低两个字节调换调成我要的形式
gbKey = (gbKey >> 8) | (gbKey << 8);
APP_PRINT("after changing, gb2312 key is: 0x%04X\n", gbKey);
memcpy((temp + j), &gbKey, 2);
}

byteCount = 3;
break;

case 4:
byteCount = 4;
break;
case 5:
byteCount = 5;
break;
case 6:
byteCount = 6;
break;

default:
APP_PRINT("the len is more than 6\n");
break; 
}

i += byteCount;
if (byteCount == 1)
{
j++;
}
else
{
j += 2;
}

}
APP_PRINT("utf8: [");
for (k = 0; k < j; k++)
{
APP_PRINT("%02x ", temp[k]);
}
APP_PRINT("]\n");
}

二、下面主要谈谈利用查表法来进行Unicode->GB2312的转换,首先下载码表,一般码表都是将GB2312的放在前面,Unicode放在后面,这样对于我们来说不方便使用,所以我转换了下,将Unicode放在前面,而且按照从小到大排好序。(这里只需要考虑都为两个字节的情况,因为前面的UTF8->Unicode并没有将单字节的ASCII转换成Unicode)
(1)做表:
这个是原来的样子:
0x8140 0x4E02 #CJK UNIFIED IDEOGRAPH
0x8141 0x4E04 #CJK UNIFIED IDEOGRAPH
0x8142 0x4E05 #CJK UNIFIED IDEOGRAPH
先弄成(这个可以写个小程序来做,我就是在VC上做的,如果需要可以联系我):
{ 0x4E02 ,0x8140 }, //CJK UNIFIED IDEOGRAPH
{ 0x4E04 ,0x8141 }, //CJK UNIFIED IDEOGRAPH
{ 0x4E05 ,0x8142 }, //CJK UNIFIED IDEOGRAPH
这样就可以把这些放在.h文件中了,下面是我的定义:
typedef struct unicode_gb
{
unsigned short unicode;
unsigned short gb;
} UNICODE_GB;

UNICODE_GB code_table[] = 
{
{ 0x4E02, 0x8140 }, //CJK UNIFIED IDEOGRAPH
{ 0x4E04, 0x8141 }, //CJK UNIFIED IDEOGRAPH
{ 0x4E05, 0x8142 }, //CJK UNIFIED IDEOGRAPH
。。。。。。省略

下面这一步也很简单,在VC中用冒泡排序法对整个表进行排序,这里是按照unicode值进行排序,把排序后的最终结果打印出来,在cmd下运行name > 1.txt就输出到文件,这样就有了一个按照unicode排好序的unicode->gb2312码表。以下是源代码

int main(int argc, char *argv[])
{

int num = 0;
UNICODE_GB temp;
int i = 0;
int j = 0;

num = sizeof(code_table) / sizeof(UNICODE_GB);

printf("struct size: %d | total size: %d | num is: %d \n", 
sizeof(UNICODE_GB), sizeof(code_table), num);

for (i = 0; i < num; i++)
{
for (j = 1; j < num - i; j++)
{
if (code_table[j - 1].unicode > code_table[j].unicode)
{
temp.unicode = code_table[j - 1].unicode;
temp.gb = code_table[j - 1].gb;
code_table[j - 1].unicode = code_table[j].unicode;
code_table[j - 1].gb = code_table[j].gb;
code_table[j].unicode = temp.unicode;
code_table[j].gb = temp.gb;
}
}
}

printf("here is the code table sorted by unicode\n\n");

for (i = 0; i < num; i++)
{
printf("{\t0x%04X,\t0x%04X\t},\t\n", code_table.gb);
}

printf("\n\n print over!\n");

//以下注释掉的其实就是我用来对原来的码表添加,{,}等用的
/*
char buff[100];
char buff_1[100]; 

FILE* fp = NULL;
FILE *fp_1 = NULL;

memset(buff, 0, 100);
memset(buff_1, 0, 100);

fp = fopen("table.txt", "rw");
fp_1 = fopen("table_1.txt", "a+");

if ((fp == NULL) || (fp_1 == NULL))
{
printf("open file error!\n");
return 1;
}

while (fgets(buff, 100, fp) != NULL)
{
buff[8] = ',';

fputs(buff, fp_1);
}
*/

return 0;
}

最后就是搜索算法了,前面已经排好序了,现在我们把排好序的码表放在我们真正需要的.h文件中。大家应该猜我用什么算法搜索了吧,二分法。

#define CODE_TABLE_SIZE 21791
//这个表是死的,所以就直接用宏表示长度,不用每次都用size,不过这样可能对移植性不好。
u16 SearchCodeTable(u16 unicodeKey)
{
int first = 0;
int end = CODE_TABLE_SIZE - 1;
int mid = 0;

while (first <= end)
{
mid = (first + end) / 2;

if (code_table[mid].unicode == unicodeKey)
{
return code_table[mid].gb;
}
else if (code_table[mid].unicode > unicodeKey)
{
end = mid - 1;
}
else 
{
first = mid + 1;
}
}
return 0;
}
到此,已经能够将UTF8串转换成GB2312了。是一长串哦,而不是单个汉字的编码转换。

cdmalcl 发表于 2009-1-3 11:17

还有这个:
Unicode与UTF8互转源代码

int UTF2Uni(const char* src, std::wstring &t)
{
if (src == NULL) 
{
return -1;
}

int size_s = strlen(src);
int size_d = size_s + 10; //?

wchar_t *des = new wchar_t;
memset(des, 0, size_d * sizeof(wchar_t));

int s = 0, d = 0;
bool toomuchbyte = true; //set true to skip error prefix.

while (s < size_s && d < size_d)
{
unsigned char c = src[s];
if ((c & 0x80) == 0) 
{
des[d++] += src[s++];

else if((c & 0xE0) == 0xC0) ///< 110x-xxxx 10xx-xxxx
{
WCHAR &wideChar = des[d++];
wideChar = (src[s + 0] & 0x3F) << 6;
wideChar |= (src[s + 1] & 0x3F);

s += 2;
}
else if((c & 0xF0) == 0xE0) ///< 1110-xxxx 10xx-xxxx 10xx-xxxx
{
WCHAR &wideChar = des[d++];

wideChar = (src[s + 0] & 0x1F) << 12;
wideChar |= (src[s + 1] & 0x3F) << 6;
wideChar |= (src[s + 2] & 0x3F);

s += 3;

else if((c & 0xF8) == 0xF0) ///< 1111-0xxx 10xx-xxxx 10xx-xxxx 10xx-xxxx 
{
WCHAR &wideChar = des[d++];

wideChar = (src[s + 0] & 0x0F) << 18;
wideChar = (src[s + 1] & 0x3F) << 12;
wideChar |= (src[s + 2] & 0x3F) << 6;
wideChar |= (src[s + 3] & 0x3F);

s += 4;

else 
{
WCHAR &wideChar = des[d++]; ///< 1111-10xx 10xx-xxxx 10xx-xxxx 10xx-xxxx 10xx-xxxx 

wideChar = (src[s + 0] & 0x07) << 24;
wideChar = (src[s + 1] & 0x3F) << 18;
wideChar = (src[s + 2] & 0x3F) << 12;
wideChar |= (src[s + 3] & 0x3F) << 6;
wideChar |= (src[s + 4] & 0x3F);

s += 5;
}
}

t = des;
delete[] des;
des = NULL;

return 0;
}

int Uni2UTF(wchar_t wchar, char *utf8)
{
if (utf8 == NULL) {
return -1;
}
int len = 0;
int size_d = 8;

if (wchar < 0x80)
{ //
//length = 1;
utf8[len++] = (char)wchar;
}
else if(wchar < 0x800)
{
//length = 2;

if (len + 1 >= size_d)
return -1;

utf8[len++] = 0xc0 | ( wchar >> 6 );
utf8[len++] = 0x80 | ( wchar & 0x3f );
}
else if(wchar < 0x10000 )
{
//length = 3;
if (len + 2 >= size_d)
return -1;

utf8[len++] = 0xe0 | ( wchar >> 12 );
utf8[len++] = 0x80 | ( (wchar >> 6) & 0x3f );
utf8[len++] = 0x80 | ( wchar & 0x3f );
}
else if( wchar < 0x200000 ) 
{
//length = 4;
if (len + 3 >= size_d)
return -1;

utf8[len++] = 0xf0 | ( (int)wchar >> 18 );
utf8[len++] = 0x80 | ( (wchar >> 12) & 0x3f );
utf8[len++] = 0x80 | ( (wchar >> 6) & 0x3f );
utf8[len++] = 0x80 | ( wchar & 0x3f );
}
return len;
}

 

Share
Filed under: iPhone, Other No Comments
30Mar/110

汉字编码

一、汉字编码的种类

    汉字编码中现在主要用到的有三类,包括GBKGB2312Big5

    1GB2312又称国标码,由国家标准总局发布,198151日实施,通行于大陆。新加坡等地也使用此编码。它是一个简化字的编码规范,当然也包括其他的符号、字母、日文假名等,共7445个图形字符,其中汉字占6763个。我们平时说6768个汉字,实际上里边有5个编码为空白,所以总共有6763个汉字。

      GB2312规定“对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示”,习惯上称第一个字节为“高字节”,第二个字节为“低字节”。GB2312中汉字的编码范围为,第一字节0xB0-0xF7(对应十进制为176-247),第二个字节0xA0-0xFE(对应十进制为160-254)。

    GB2312将代码表分为94个区,对应第一字节(0xa1-0xfe);每个区94个位(0xa1-0xfe),对应第二字节,两个字节的值分别为区号值和位号值加322OH),因此也称为区位码。01-09区为符号、数字区,16-87区为汉字区(0xb0-0xf7),10-15区、88-94区是有待进一步标准化的空白区。

       2Big5又称大五码,主要为香港与台湾使用,即是一个繁体字编码。每个汉字由两个字节构成,第一个字节的范围从0X810XFE(即129-255),共126种。第二个字节的范围不连续,分别为0X400X7E(即64-126),0XA10XFE(即161-254),共157种。

    3GBKGB2312的扩展,是向上兼容的,因此GB2312中的汉字的编码与GBK中汉字的相同。另外,GBK中还包含繁体字的编码,它与Big5编码之间的关系我还没有弄明白,好像是不一致的。GBK中每个汉字仍然包含两个字节,第一个字节的范围是0x81-0xFE(即129-254),第二个字节的范围是0x40-0xFE(即64-254)。GBK中有码位23940个,包含汉字21003个。

                                    

                                   汉字编码范围

二、对汉字进行hash

    为了处理汉字的方便,在查找汉字的时候,我们通常会用到hash的方法,那怎么来确定一个汉字位置呢?这就和每种编码的排列有关了,这里主要给出一种hash函数的策略。

    对于GB2312编码,设输入的汉字为GBword,我们可以采用公式(C1-176)*94 + (C2-161)确定GBindex。其中,C1表示第一字节,C2表示第二字节。具体如下:

    GBindex = ((unsigned char)GBword.at(0)-176)*94 + (unsigned char)GBword.at(1) - 161;

    之所以用unsigned char类型,是因为char是一个字节,如果用unsigend int,因为int4个字节的,所以会造成扩展,导致错误。

       对于GBK编码,设输入的汉字为GBKword,则可以采用公式   index=(ch1-0x81)*190+(ch2-0x40)-(ch2/128),其中ch1是第一字节,ch2是第二字节。

    具体的,

    GBKindex = ((unsigned char)GBKword[0]-129)*190 +

               ((unsigned char)GBKword[1]-64) - (unsigned char)GBKword[1]/128;

三、怎样判断一个汉字的是什么编码

直接根据汉字的编码范围判断,对于GB2312GBK可用下面两个程序实现。

1、判断是否是GB2312

bool isGBCode(const string& strIn)

{

    unsigned char ch1;

    unsigned char ch2;

   

    if (strIn.size() >= 2)

    {

        ch1 = (unsigned char)strIn.at(0);

        ch2 = (unsigned char)strIn.at(1);

        if (ch1>=176 && ch1<=247 && ch2>=160 && ch2<=254)

            return true;

        else return false;

    }

    else return false;

}

2、判断是否是GBK编码

bool isGBKCode(const string& strIn)

{

    unsigned char ch1;

    unsigned char ch2;

   

    if (strIn.size() >= 2)

    {

        ch1 = (unsigned char)strIn.at(0);

        ch2 = (unsigned char)strIn.at(1);

        if (ch1>=129 && ch1<=254 && ch2>=64 && ch2<=254)

            return true;

        else return false;

    }

    else return false;

}

3、对于Big5

    它的范围为:高字节从0xA00xFE,低字节从0x400x7E,和0xA10xFE两部分。判断一个汉字是否是BIG5编码,可以如上对字符的编码范围判断即可。如何定位呢?那么也想象所有编码排列为一个二维坐标,纵坐标是高字节,横坐标是低字节。这样一行上的汉字个数:(0x7E-0x40+1)+(0xFE-0xA1+1)157。那么定位算法分两块,为:  

    if 0x40<=ch2<=0x7E: #is big5 char

index=((ch1-0xA1)*157+(ch2-0x40))*2

    elif 0xA1<=ch2<=0xFE: #is big5 char

index=((ch1-0xA1)*157+(ch2-0xA1+63))*2

对于第二块,计算偏移量时因为有两块数值,所以在计算后面一段值时,不要忘了前面还有一段值。0x7E-0x40+1=63

四、如果判断一个字符是西文字符还是中文字符

    大家知道西文字符主要是指ASCII码,它用一个字节表示。且这个字符转换成数字之后,该数字是大于0的,而汉字是两个字节的,第一个字节的转化为数字之后应该是小于0的,因此可以根据每个字节转化为数字之后是否小于0,判断它是否是汉字。

    例如,设输入字为strin,则,

     If (strin.at(0) < 0)

       cout << ”是汉字” << endl;

     else cout << ”不是汉字” << endl;

五、编码表下载
    见附件

六、编码对照表
http://www.herongyang.com/gb2312/

名称

第一字节

第二字节

GB2312

0xB0-0xF7(176-247)

0xA0-0xFE160-254

GBK

0x81-0xFE129-254

0x40-0xFE64-254

Big5

0x81-0xFE129-255

0x40-0x7E64-126

0xA10xFE161-254

Share
Filed under: iPhone, Other No Comments
26Mar/110

Some iPhone codes

 

Logging
In Xcode, click Run > Console to see NSLog statements.

NSLog(@"log: %@ ", myString);
NSLog(@"log: %f ", myFloat);
NSLog(@"log: %i ", myInt);

Display Images
Display an image anywhere on the screen, without using UI Builder. You can use this for other types of views as well.

CGRect myImageRect = CGRectMake(0.0f, 0.0f, 320.0f, 109.0f);
UIImageView *myImage = [[UIImageView alloc] initWithFrame:myImageRect];
[myImage setImage:[UIImage imageNamed:@"myImage.png"]];
myImage.opaque = YES;
// explicitly opaque for performance
[self.view addSubview:myImage];
[myImage release];

Web view
A basic UIWebView.

CGRect webFrame = CGRectMake(0.0, 0.0, 320.0, 460.0);
UIWebView *webView = [[UIWebView alloc] initWithFrame:webFrame];
[webView setBackgroundColor:[UIColor whiteColor]];
NSString *urlAddress = @"http://www.google.com";
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];
[self addSubview:webView];
[webView release]

isplay the Network Activity Status Indicator
This is the rotating icon displayed on the iPhone status bar in the upper left to indicate there is background network activity taking place.

UIApplication* app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = YES; // to stop it, set this to NO

Animation: Series of images
Show a series of images in succession

NSArray *myImages = [NSArray arrayWithObjects: [UIImage imageNamed:@"myImage1.png"], [UIImage imageNamed:@"myImage2.png"], [UIImage imageNamed:@"myImage3.png"], [UIImage imageNamed:@"myImage4.gif"], nil];
UIImageView *myAnimatedView = [UIImageView alloc];
[myAnimatedView initWithFrame:[self bounds]];
myAnimatedView.animationImages = myImages;
myAnimatedView.animationDuration = 0.25; // seconds
myAnimatedView.animationRepeatCount = 0; // 0 = loops forever
[myAnimatedView startAnimating];
[self addSubview:myAnimatedView];
[myAnimatedView release];

Animation: Move an object
Show something moving across the screen. Note: this type of animation is "fire and forget" -- you cannot obtain any information about the objects during animation (such as current position). If you need this information, you will want to animate manually using a Timer and adjusting the x&y coordinates as necessary.

这个需要导入QuartzCore.framework
CABasicAnimation *theAnimation;
theAnimation=[CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
theAnimation.duration=1;
theAnimation.repeatCount=2;
theAnimation.autoreverses=YES;
theAnimation.fromValue=[NSNumber numberWithFloat:0];
theAnimation.toValue=[NSNumber numberWithFloat:-60];
[view.layer addAnimation:theAnimation forKey:@"animateLayer"];

Draggable items
Here's how to create a simple draggable image.
1. Create a new class that inherits from UIImageView

@interface myDraggableImage : UIImageView { }

2. In the implementation for this new class, add the 2 methods:

- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{ // Retrieve the touch point
CGPoint pt = [[touches anyObject] locationInView:self];
startLocation = pt;
[[self superview] bringSubviewToFront:self];
}

- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{ // Move relative to the original touch point
CGPoint pt = [[touches anyObject] locationInView:self];
CGRect frame = [self frame];
frame.origin.x += pt.x - startLocation.x;
frame.origin.y += pt.y - startLocation.y;
[self setFrame:frame];
}

3. Now instantiate the new class as you would any other new image and add it to your view

dragger = [[myDraggableImage alloc] initWithFrame:myDragRect];
[dragger setImage:[UIImage imageNamed:@"myImage.png"]];
[dragger setUserInteractionEnabled:YES];

Vibration and Sound
Here is how to make the phone vibrate (Note: Vibration does not work in the Simulator, it only works on the device.)

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

Sound will work in the Simulator, however some sound (such as looped) has been reported as not working in Simulator or even altogether depending on the audio format. Note there are specific filetypes that must be used (.wav in this example).

SystemSoundID pmph;
id sndpath = [[NSBundle mainBundle] pathForResource:@"mySound" ofType:@"wav" inDirectory:@"/"];
CFURLRef baseURL = (CFURLRef) [[NSURL alloc] initFileURLWithPath:sndpath];
AudioServicesCreateSystemSoundID (baseURL, &pmph);
AudioServicesPlaySystemSound(pmph);
[baseURL release];

Threading
1. Create the new thread:

[NSThread detachNewThreadSelector:@selector(myMethod) toTarget:self withObject:nil];

2. Create the method that is called by the new thread:

- (void)myMethod
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
*** code that should be run in the new thread goes here ***
[pool release];
}

What if you need to do something to the main thread from inside your new thread (for example, show a loading symbol)? Use performSelectorOnMainThread.

[self performSelectorOnMainThread:@selector(myMethod) withObject:nil waitUntilDone:false];

Timers
This timer will call myMethod every 1 second.

[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(myMethod) userInfo:nil repeats:YES];

2. Then pass the NSTimer object to your method:

-(void)myMethod:(NSTimer*)timer
{
// Now I can access all the properties and methods of myObject
[[timer userInfo] myObjectMethod];
}

3.To stop a timer, use "invalidate":
[myTimer invalidate]; myTimer = nil; // ensures we never invalidate an already invalid Timer

Plist files
Application-specific plist files can be stored in the Resources folder of the app bundle. When the app first launches, it should check if there is an existing plist in the user's Documents folder, and if not it should copy the plist from the app bundle.

// Look in Documents for an existing plist file
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
myPlistPath = [documentsDirectory stringByAppendingPathComponent:
[NSString stringWithFormat: @"%@.plist", plistName] ];
[myPlistPath retain];

// If it's not there, copy it from the bundle
NSFileManager *fileManger = [NSFileManager defaultManager];
if ( ![fileManger fileExistsAtPath:myPlistPath] )
{
NSString *pathToSettingsInBundle = [[NSBundle mainBundle] pathForResource:plistName ofType:@"plist"];
}

Now read the plist file from Documents

NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *path = [documentsDirectoryPath stringByAppendingPathComponent:@"myApp.plist"];
NSMutableDictionary *plist = [NSDictionary dictionaryWithContentsOfFile: path];

Now read and set key/values

myKey = (int)[[plist valueForKey:@"myKey"] intValue];
myKey2 = (bool)[[plist valueForKey:@"myKey2"] boolValue];
[plist setValue:myKey forKey:@"myKey"];
[plist writeToFile:path atomically:YES];

Alerts
Show a simple alert with OK button.

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:
@"An Alert!" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];

Info button
Increase the touchable area on the Info button, so it's easier to press.

CGRect newInfoButtonRect = CGRectMake(infoButton.frame.origin.x-25, infoButton.frame.origin.y-25, infoButton.frame.size.width+50, infoButton.frame.size.height+50);

[infoButton setFrame:newInfoButtonRect];

Detecting Subviews
You can loop through subviews of an existing view. This works especially well if you use the "tag" property on your views.

for (UIImageView *anImage in [self.view subviews])
{
if (anImage.tag == 1)
{ // do something }
}

 

Share
Filed under: iPhone, Other No Comments
25Mar/110

UIIMage Mask

CGImageRef myMaskedImage = [myImage CGImage];
const float whiteMask[6] = { 255,255,255, 255,255,255 };
CGImageRef myColorMaskedImage = CGImageCreateWithMaskingColors(image, whiteMask);

CGDataProviderRef provider;
CGImageRef myPngImage = CGImageCreateWithPNGDataProvider(provider, NULL, true, kCGRenderingIntentDefault);

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt: 72], kCGImagePropertyDPIHeight, [NSNumber numberWithInt: 72], kCGImagePropertyDPIWidth, nil];
CGImageDestinationRef destRef = CGImageDestinationCreateWithURL ((CFURLRef)outPath, (CFStringRef)@"image.png" , 1, NULL);
CGImageDestinationAddImage(destRef, myPngImage, (CFDictionaryRef)options);
CGImageDestinationFinalize(destRef);
CGRelease(destRef);

CGImageRelease(myColorMaskedImage);
CGImageRelease(myPngImage);

Share
Filed under: iPhone, Other No Comments
23Mar/110

objective-c invoke javascript object and function

>.先设置委托:WebFrameLoadDelegate

   设置Javascript  foo 对象的值。

  1. - (void)webView:(WebView *)sender windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject
  2.     NSString *myFoo = @"zczhustring";
  3.     [windowScriptObject setValue:myFoo forKey:@"foo"]; //foo is javascript varible

2.调用Javascript函数function addImage(string){}

  1. 调用javascript函数
  2. -(void)callJavaScriptFun
  3. {
  4.     WebView *myWebView;
  5.     WebScriptObject * win = [myWebView windowScriptObject];
  6.     NSArray *args = [NSArray arrayWithObjects:@"zzczzc",nil]; //arguments,参数
  7.     //函数调用不返回
  8.     [win callWebScriptMethod:@"addImage" withArguments:args];
  9.     //函数调用后返回
  10.     id rvalue= [win evaluateWebScript:@"addImage('zzczzc')"];
  11.     NSLog(@"%@", rvalue);
  12. }

3>.JavaScript invoke objectiove-c method

javascript调用自己的一个函数:-(id)setJSvalue:(NSString *)str;

 

  1. a)
  2. - (void)webView:(WebView *)sender windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject
  3. {
  4.       //set method key 
  5.      [windowScriptObject setValue:self forKey:@"setJSvalue"];
  6. }

    1. b)在主线程类中重载如下函数
    2. ///重载 
    3. + (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
    4.     return NO; 
    5. }
    6. + (BOOL)isKeyExcludedFromWebScript:(const char *)property {
    7.     if (strcmp(property, "name") == 0) {
    8.         return NO;
    9.     }
    10.     return YES;
    11. }
    12. + (NSString *)webScriptNameForSelector:(SEL)sel
    13. {
    14.     if (sel == @selector(bar:))
    15.         return @"bar";
    16.     if (sel == @selector(setJSvalue:))
    17.         return @"setJSvalue";
    18.     return nil;
    19. }

    2>.javascript中如此调用:

  1. document.write("call  objective-c function<br>");
  2. var myjs = window.setJSvalue;
  3. string = "argument";
  4. var name = myjs.setJSvalue_(string);
  5. document.write("call  objective-c function<br>");

最后:objective-c 与 javascript 函数对应规则:

Objective –C 函数                    javascript 调用函数名应该为

Objective-C selector

Default script name for selector

setFlag:

setFlag_

setFlag:forKey:withAttributes:

setFlag_forKey_withAttributes_

propertiesForExample_Object:

propertiesForExample$_Object_

set_$_forKey:withDictionary:

set$_$$_$_forKey_withDictionary_


Share
Filed under: iPhone, Other No Comments
23Mar/110

iPhone/iPad code

1 随机数的使用

        头文件的引用
        #import <time.h>
        #import <mach/mach_time.h>

        srandom()的使用
        srandom((unsigned)(mach_absolute_time() & 0xFFFFFFFF));

        
直接使用 random() 来调用随机数

2 在UIImageView 中旋转图像

        float rotateAngle = M_PI;
        CGAffineTransform transform =CGAffineTransformMakeRotation(rotateAngle);
        imageView.transform = transform;
       
        
以上代码旋转imageView, 角度为rotateAngle, 方向可以自己测试哦!


3 在Quartz中如何设置旋转点

        UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bg.png"]];
        imageView.layer.anchorPoint = CGPointMake(0.5, 1.0);


        这个是把旋转点设置为底部中间。记住是在QuartzCore.framework中才得到支持。

4 创建.plist文件并存储

        NSString *errorDesc;  //用来存放错误信息
        NSMutableDictionary *rootObj = [NSMutableDictionary dictionaryWithCapacity:4]; //NSDictionary, NSData等文件可以直接转化为plist文件

        NSDictionary *innerDict;
        NSString *name;
        Player *player;
        NSInteger saveIndex;
    
        for(int i = 0; i < [playerArray count]; i++) {
              player = nil;
              player = [playerArray objectAtIndex:i];
              if(player == nil)
                     break; 
              name = player.playerName;// This "Player1" denotes the player name could also be the computer name
              innerDict = [self getAllNodeInfoToDictionary:player];
              [rootObj setObject:innerDict forKey:name]; // This "Player1" denotes the person who start this game
        }
        player = nil;

        NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:(id)rootObj format:NSPropertyListXMLFormat_v1_0 errorDescription:&errorDesc];

        红色部分可以忽略,只是给rootObj添加一点内容。这个plistData为创建好的plist文件,用其writeToFile方法就可以写成文件。下面是代码
        
        /*得到移动设备上的文件存放位置*/
        NSString *documentsPath = [self getDocumentsDirectory]; 
        NSString *savePath = [documentsPath stringByAppendingPathComponent:@"save.plist"];
    
        /*存文件*/
        if (plistData) {
                [plistData writeToFile:savePath atomically:YES];
         }
         else {
                NSLog(errorDesc);
                [errorDesc release];
        }


        - (NSString *)getDocumentsDirectory {  
                NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
                return [paths objectAtIndex:0];  
        } 


4 读取plist文件并转化为NSDictionary

        NSString *documentsPath = [self getDocumentsDirectory];
        NSString *fullPath = [documentsPath stringByAppendingPathComponent:@"save.plist"];
        NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:fullPath];


5 读取一般性文档文件

        NSString *tmp;
        NSArray *lines;
 /*将文件转化为一行一行的*/
        lines = [[NSString    stringWithContentsOfFile:@"testFileReadLines.txt"] 
                       componentsSeparatedByString:@"\n"];
    
         NSEnumerator *nse = [lines objectEnumerator];
    
         // 读取<>里的内容
         while(tmp = [nse nextObject]) {
                  NSString *stringBetweenBrackets = nil;
                  NSScanner *scanner = [NSScanner scannerWithString:tmp];
                  [scanner scanUpToString:@"<" intoString:nil];
                  [scanner scanString:@"<" intoString:nil];
                  [scanner scanUpToString:@">" intoString:&stringBetweenBrackets];

                  NSLog([stringBetweenBrackets description]);
          }


对于读写文件,还有补充,暂时到此。随机数和文件读写在游戏开发中经常用到。所以把部分内容放在这,以便和大家分享,也当记录,便于查找。

6 隐藏NavigationBar
[self.navigationController setNavigationBarHidden:YES animated:YES];

在想隐藏的ViewController中使用就可以了。

Share
Filed under: iPhone, Other No Comments
20Mar/110

Submited the Application to Apple Store

Just submitted the application to Apple store today. waiting to review. One month before, same day I bought the MacBook Pro. :)

 

孙子兵法(竹简收藏版)

Share
Filed under: iPhone, Other No Comments
12Mar/110

JavaScripts

页面定位

  1. document.body.scrollTop = 100;

复制代码

或者

  1. document.getElementById('location').scrollIntoView();

复制代码

背景图片

  1. document.body.style.backgroundImage = "url(image.png)";

复制代码

字体大小

  1. document.body.style.fontSize = "20px";

复制代码

字体颜色

  1. document.body.style.color = "black";

复制代码

获得当前位置

  1. window.pageYOffset

复制代码

获得页面全文长度

  1. document.body.scrollHeight;

复制代码

获得页面全文宽度

  1. document.body.scrollWidth;

复制代码

Share
Filed under: iPhone, Other No Comments
8Mar/110

Show iPhone Fonts

   NSArray *fontFamily=[UIFont familyNames];

 

     for (NSString* fontsname in fontFamily) {

     NSLog(@"%@",fontsname);

     }


 

Share
Filed under: iPhone, Other No Comments