• iOS 5设备下UINavigationbar的背景修改

    最近我突然发现UINavigationbar背景修改的方法不起作用了,代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @implementation UINavigationBar (CustomImage)

    -(void)drawRect:(CGRect)rect
    {
        UIImage *image = [UIImage imageNamed:@"navigationbar.png"];
        [image drawInRect:CGRectMake(0,0,self.frame.size.width,self.frame.size.height)];
    }

    @end

    发现原来是iOS 5的原因,如果运行在iOS 5以下的版本就没有问题了。经过实验以下方法适合iOS 5(放在ViewDidLoad中):

    1
    2
    3
        if ([self.navigationController.navigationBar respondsToSelector:@selector( setBackgroundImage:forBarMetrics:)]){
            [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"navigationbar.png"] forBarMetrics:UIBarMetricsDefault];
        }

    第一条if语句的作用是防止程序在iOS 5以下的版本中崩溃。

    这样,依靠这两段代码,我的UINavigationbar的背景问题在iOS 5及以下版本中得到了完美的解决。

     
  • 强迫UIView以某种方向显示的秘诀

    我有一个项目其中某些UIView必须以特定的方向(Portrait或者Landscape)显示。这个看似简单的问题,困惑了我很久,直到今天我才完全找到解决的方法。
    读文章 »

     
  • 无法正确加载@2x的解决办法

    为使用retina显示,我们一般把图片的高分辨率版本存为@2x的形式,但是iOS 4.1以前的版本,如果使用imageWithContentsOfFile是无法保证@2x文件正确加载的。我使用如下方法解决此问题:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    // UIImage+Extras.h
    @interface UIImage (Extras)

    - (id)initWithContentsOfResolutionIndependentFile:(NSString *)path;
    + (UIImage*)imageWithContentsOfResolutionIndependentFile:(NSString *)path;

    @end

    // UIImage+Extras.m
    - (id)initWithContentsOfResolutionIndependentFile:(NSString *)path {
        if ( [[[UIDevice currentDevice] systemVersion] intValue] >= 4 && [[UIScreen mainScreen] scale] == 2.0 ) {
            NSString *path2x = [[path stringByDeletingLastPathComponent]
                                stringByAppendingPathComponent:[NSString stringWithFormat:@"%@@2x.%@",
                                                                [[path lastPathComponent] stringByDeletingPathExtension],
                                                                [path pathExtension]]];
           
            if ( [[NSFileManager defaultManager] fileExistsAtPath:path2x] ) {
                return [self initWithCGImage:[[UIImage imageWithData:[NSData dataWithContentsOfFile:path2x]] CGImage] scale:2.0 orientation:UIImageOrientationUp];
            }
        }
       
        return [self initWithData:[NSData dataWithContentsOfFile:path]];
    }

    + (UIImage*)imageWithContentsOfResolutionIndependentFile:(NSString *)path {
        return [[[UIImage alloc] initWithContentsOfResolutionIndependentFile:path] autorelease];
    }
     
  • presentModalViewController显示半透明UIView

    很多时候我们需要使用presentModalViewController来显示Modal View。如果需要显示半透明的Modal View应该怎么办呢?当然可以自己创建一个半透明的UIView,然后模拟presentModalViewController的动画效果。

    不过iOS 4以后的版本再也不需要怎么麻烦了,有一个非常简单的方法,示例如下(这段代码运行于一个View Controller中):

    1
    2
    3
    4
    5
    6
        UIViewController* transparentView = [[UIViewController alloc] init];           

           UIViewController* controller = self.view.window.rootViewController;
           transparentView.view.backgroundColor = [UIColor clearColor];
           controller.modalPresentationStyle = UIModalPresentationCurrentContext;        
           [controller presentModalViewController:transparentView animated:YES];

    其要点就是使用iOS特有的rootViewController来显示Modal View。

     
  • 分享一小段代码

    我们经常会遇到这种情况,某个按钮太小很难按到,又不想把按钮图片做得太大。我把它作成了一个Class Method,放在了我的Utils类中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    +(void)resizeTouchableAreaForButton:(UIButton* )button withNewSize:(CGSize)size
    {
        // increase margin around button based on width
        const CGFloat margin_h = 0.5f * ( size.width - button.frame.size.width );
        const CGFloat margin_v = 0.5f * ( size.height - button.frame.size.height );
       
        // add margin on all four sides of the button
        CGRect newFrame = button.frame;
        newFrame.origin.x -= margin_h;
        newFrame.origin.y -= margin_v;
        newFrame.size.width  += 2.0f * margin_h;
        newFrame.size.height += 2.0f * margin_v;
       
        button.frame = newFrame;
    }

    这段代码把按钮的可按区域扩大到新的尺寸。不过有一个前提是使用UIButton的setImage而不是setBackgroundImage来设置按钮图片。

     
  • pdf渲染的小窍门

    我们都知道,在iPhone/iPad显示pdf的基本方法有两个,一个是使用UIWebView直接加载pdf文件,另一个是使用Core Graphics进行渲染(姑且称之为CGPDF方法)。UIWebView的方法是简单,只需加载pdf,其他诸如放大翻页等问题通通交给UIWebView去头痛吧。但其缺点是性能较慢,功能有限,比如要实现搜索,添加笔记等功能就比较难。而使用CGPDF方法,功能就没有限制(虽然pdf解析方面,苹果提供的文档实在有限),使用Core Graphics进行渲染,性能上也比UIWebView要提高许多,只不过翻页,放大缩小等功能都需要自己实现。

    读文章 »

     
  • 检测当前设备是否为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]);
     
  • 怎样使UISearchBar背景透明

    在使用UISearchBar时,将背景色设定为clearColor,或者将translucent设为YES,都不能使背景透明,经过一番研究,发现了一种超级简单和实用的方法:

    1
    [[searchbar.subviews objectAtIndex:0]removeFromSuperview];

    背景完全消除了,只剩下搜索框本身了。