• 怎样关闭后台运行

    iOS 4引进了所谓多任务,可以让程序运行于后台,不过对目前大部分程序而言这只是一个鸡肋。有没有办法直接在用户按下Home键后像iOS 4之前的程序一样直接退出呢?方法如下:

    1. 打开info.plist
    2. 加入 UIApplicationExitsOnSuspend 或者选择“Application does not run in background(程序不运行于后台)”
    3. 将其设为 YES
     
  • 检查UIWebView上touch的最简单的方法

    我有一个程序需要检测UIWebView是否有touch动作,不幸得很,UIWebView上的touchesBegan等事件无法被检测。在网上查了一下,有许多解决方法,比如在UIWebView上再加一个透明的UIView,重置UIWindow的sendEvent或重置UIWebView的hitest方法等等,要么就是方案不太完美,要么就是太过复杂,经过实验我使用的这种方法最为简单(否则我也没有时间写在这里了),当然我只要求检测UIWebView上有touch动作即可。我的方法是使用UITapGestureRecognizer。关键的地方有两点,请看我的代码(我的代码是在一个UIViewController中):

    1
    2
    3
    4
    5
        UITapGestureRecognizer* singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
        [self.view addGestureRecognizer:singleTap];
        singleTap.delegate = self;
        singleTap.cancelsTouchesInView = NO;
        [singleTap release];


    第三行是第一个关键的地方,就是必须设置UITapGuestureRecognizer的delegate(一般我们直接使用initWithTarget,无需设置其delegate)。

    第二个关键的地方是在下列delegate方法return YES。

    1
    2
    3
    4
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    {
        return YES;
    }


    做到这两点,你的UIWebView就可以响应touch事件了,你可以使用不同的UIGestureRecognizer来满足你不同的要求等。(handleSingleTap方法请自行补上)。

     
  • cocos2d-iphone 0.99.5 Xcode 静态库模板

    最近一个项目需要用到opengles,由于实在没有时间无法完成自己的引擎,因此开始对cocos2d-iphone引擎进行了研究。经过研究发现一个问题,其模板生成的项目每次都会把整个cocos2d的源代码拷贝进新项目中,这样每次cocos2d-iphone进行更新时都会带来麻烦,而且如果多个项目使用cocos2d-iphone,非常的不方便。我在网上搜索了一下,发现了了这个网站,介绍了怎样将cocos2d-iphone编译成静态库的方法,与我的想法不谋而合。不过该网站中的模板只适用于0.99.4,于是我修改了一下,让其可以运行于0.99.5。下面是主要步骤:

    1. 下载cocos2d-iphone 0.99.5 template模板。

    2. 解压到/$HOME/Library/Application Support/Developer/Shared/Xcode下

    3. 下载cocos2d-iphone 0.99.5,解压到你想要的地方。

    3. 在Xcode Preferences中找到Source Tree,输入新变量COCOS2D_SOURCE,让其指向cocos2d-iphone 0.99.5的源代码处。

    这样,下次你打开Xcode,你就可以使用我的模板创建cocos2d项目了(注意不要安装随cocos2d-iphone下载的模板),以后每次cocos2d-iphone进行更新,你仅仅需要修改COCOS2D_SOURCE变量(当然前提是cocos2d-iphone的编程接口没有改变)。

     
  • NSOperation和NSURLConnection

    最近一个客户向我汇报了一个程序的问题。经过分析发现问题是NSURLConnection没有正常工作。记得以前测试时没有问题啊。后来上网查到原来在iOS 4.0以后,NSURLConnection无法在NSOperation中正常运行,换句话说,NSURLConnection只能运行于主线程。解决方法其实倒是蛮简单(比如我的程序在download中):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    -(void)download
    {
        // NSURLConnectionn won't work if it's not in the main thread
        if (![NSThread isMainThread])
        {
            [self performSelectorOnMainThread:@selector(download) withObject:nil waitUntilDone:NO];
            return;
        }
       
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:_urlString]];
        _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];     
    }
     
  • Cocos 2d基本概念

    开发cocos2d程序前有必要对一些基本概念进行介绍:


    • 场景(Scenes)
    • 主控器(Director)
    • 层(Layers)
    • 精灵(Sprites)



    读文章 »

     
  • CALayer简单教程

    前一阵子读到一篇介绍CALayer(这里简单地称其为层)的教程,比较简单易懂,适合初学者,我在这里就不完全翻译了,只是把要点说明一下。

    读文章 »

     
  • 检测当前设备是否为iPad

    今天编写一个程序时需要检测当前设备是否为iPad,正好用到开源Cocos2d库,发现里面是使用下面代码段进行检测的:

     

    1
    2
    3
    4
    5
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
            [_pages addObject:@"page1-ipad.jpg"];
        } else {
            [_pages addObject:@"page2.jpg"];
        }

    &nbsp

     
  • 分享一段代码帮助进行调试

    有时程序崩溃根本不知错误发生在什么地方。比如程序出现EXEC_BAD_ACCESS的时候,虽然大部分情况使用设定NSZombieEnabled环境变量可以帮助你找到问题的所在,但少数情况下,即使设定了NSZombieEnabled环境变量,还是不知道程序崩溃在什么地方。那么就需要使用下列代码进行帮助了:

    1
    2
    3
    4
    5
    6
    #ifdef _FOR_DEBUG_
    -(BOOL) respondsToSelector:(SEL)aSelector {
        printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]);
        return [super respondsToSelector:aSelector];
    }
    #endif

    你需要在每个object的.m或者.mm文件中加入上面代码,并且在other c flags中加入-D _FOR_DEBUG_(记住请只在Debug Configuration下加入此标记)。这样当你程序崩溃时,Xcode的console上就会准确地记录了最后运行的object的方法。

     
  • 程序中读取可用内存

    iPhone/iPad的内存十分紧张,所以有时进行调试时可能需要读取当前可用内存。其实挺简单,见下列代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #import <mach/mach.h>
    #import <mach/mach_host.h>

    @implementation Utils

    + (double)getAvailableMemory
    {
        vm_statistics_data_t vmStats;
        mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
        kern_return_t kernReturn = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmStats, &infoCount);
       
        if (kernReturn != KERN_SUCCESS)
        {
            return NSNotFound;
        }
       
        return (vm_page_size * vmStats.free_count);
    }

    end

    使用方法更简单,比如:

    1
    NSLog(@"Available memory (KB) =  %f",[Utils getAvailableMemory]);
     
  • IAP transaction error

    这几天测试IAP时,总是出现下列错误:

    You’ve already purchased this but it hasn’t been downloaded…..

    然后就是,Transaction Failed,错误原因是:无法连接iTune Store。上网查了一下很多人说是iTunes Store的问题,等几天就好了,但我用另一个iDP的账户又没有问题。进过调试,最后发现问题出在iTune Store 的 test account上,原来我没有为新iDP账户创建test account,这原来是个低级错误,不过Apple的错误信息也太容易误导人了吧?