2010年4月29日星期四

用nib文件创建自定义uiview uitableviewcell 等


有好多同学习惯于在uiview的initwithfram方法中添加自定义的控件,如果要添加的控件较多,位置调整就会很麻烦。
我更习惯于使用interface builder来创建nib文件,在nib文件上拖动控件,可以方便迅速的构建自定义的新view等。
步骤:
1。添加新文件 cocoa touch class, 创建一个新类继承自UIVIEW ,命名位UIMyView
2。添加新文件 user interface, 创建Empty xib文件 ,命名MyView.xib
3.打开MyView.xib ,从library中选择view,拖动到Myview.xib 中。
4。双击添加的view,此时可以修改view的大小等属性 。在第四个窗口中修改view的Class为UImyView,这样,用nib创建的view就会和自己定义的新类相关联
5。使用UIMyView
NSArray *array = [[NSBundle mainBundle] loadNibNamed:@”MyView” owner:self options:nil];
UIMyView *view = [array objectAtIndex:0];
Share:

2010年4月28日星期三

iPhone-屏幕截取

一、从View生成图片
-(void)captureScreen{
  // Begin
  UIGraphicsBeginImageContext(CGSizeMake(320,480));
  // Render
  CGContextRef ref = UIGraphicsGetCurrentContext(); 
  [self.view.layer renderInContext:ref];
  // Capture
  UIImage *tmpImage = UIGraphicsGetImageFromCurrentImageContext();
  // Display test
  //imgView.image = tmpImage;
  // nil test
  if (tmpImage == nil) {
    NSLog(@"nil returned");
  }
  // Size test
  //NSLog(@"size %f,%f",imgView.image.size.width,imgView.image.size.height);
  // Save
  //NSData *dataObj = UIImagePNGRepresentation(tmpImage);
  //[dataObj writeToFile:@"/Users/kiichi/Desktop/test1.png" atomically:NO];
  // Save 2
  //UIImageWriteToSavedPhotosAlbum(tmpImage,nil,nil,nil);
  UIImageWriteToSavedPhotosAlbum(tmpImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
  // End
  UIGraphicsEndImageContext();
}


- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
 //mSpining.hidden = true;
 if (error == nil) {
  UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Image has been saved"
                delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
  [alert show];
  [alert release];
 }
 else {
  UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" 
                                                  message:[NSString stringWithFormat:@"ERROR: %@", [error localizedDescription]]
                                                 delegate:self 
                                        cancelButtonTitle:@"OK" 
                                        otherButtonTitles: nil];
  [alert show];
  [alert release];

 }
}
二、Screen Capture from the top level
(可以截取最顶层的屏幕图片,甚至可以截取摄像头的缓冲屏幕图片) To capture entire screen from the top level, even including the camera buffer:
1. Change file name to .mm from .m
2. Add extern

extern "C" CGImageRef UIGetScreenImage(); //私有api (官方已经允许使用,官方论坛声明地址:https://devforums.apple.com/message/149553)

3. Call UIGetScreenImage

  CGImageRef iref =  UIGetScreenImage();
  UIImage *tmpImage = [[UIImage alloc] initWithCGImage:iref];

Share:

2010年4月22日星期四

iphone 开发小技巧


1。给iPhone程序创建Splash欢迎界面

最简单的方法就是做一个全屏的欢迎页的图片,把它命名为Default.png,然后放在Xcode工程的Resource里面。 执行就可以看到你的这个默认图像在程序完全加载之前显示在屏幕上。

Default.png是一张480*320的png图片用于在程序启动时显示。启动时,系统会用这张图片作为临时背景,直到程序载入了他的窗口和用户界面。

Icon.png是一张57*57的png图片,用于在iPhone的主界面上作为程序图标代表你的程序。这张图片不需要有其他附加特效,系统会自动添加这些效果。

Icon-Setting.png是一张29*29的png图片,用于在设置程序中作为图标代表你的程序。如果你的程序有Settings.bundle,这个图标将会显示在程序名的旁边。如果你没有设置这张图片,系统会将Icon.png缩放来代替。

2。 怎样才能让程序在运行过程中不锁屏呢?

[UIApplication sharedApplication].idleTimerDisabled=YES;//not let iphone go to sleep

3。显示被view 或 control遮盖的背景内容

xx.backgroundColor=[UIColor clearColor];

4。url编码

NSString *strURL = @”http://www.google.com/search?hl=en&newwindow=1&q=如何对url编码&aq=f&oq=&aqi=”;

strURL = [strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //使用utf8

strURL=[strURLstringByAddingPercentEscapesUsingEncoding: CFStringConvertEncodingToNSStringEncoding( kCFStringEncodingGB_18030_2000)] ;////使用 gb2312

5。转换网页编码gb2312 -> utf

//编码转换 gb2313 to UTF
NSData * myResponseData = [myRequest responseData];
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding (kCFStringEncodingGB_18030_2000);
NSString * myResponseStr = [[NSString alloc] initWithData:myResponseData encoding:enc];
6。获取界面语言设置

NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSArray* languages = [defs objectForKey:@"AppleLanguages"];
NSString* preferredLang = [languages objectAtIndex:0];

7.对于做为数据Model的类来说,让其实现NSCoding协议是个好习惯

it’s just good habit to conform data model classes to NSCoding.

8

It’s okay to redefine properties to be more permissive than the

same property as declared in a protocol to which you’ve conformed, or as declared in

your superclass. You can always redefine a readonly or writeonly property to be

readwrite, but you have to explicitly use the readwrite keyword. Most of the time, that

keyword isn’t used because it’s the default value and unnecessary.
Share:

iPhone开发中内存的合理使用(转)

iPhone 开发过程中,内存的使用至关重要。不但要合理分配使用内存,还要注意内存泄露的问题, 因为内存泄露会导致程序由于内存不足而崩溃。根据个人开发的经验来看,在开发iPhone程序的过程中,关于内存的问题需要注意以下几点:

  1. 内存分配、释放成对出现
    使用 alloc 分配的内存对象需要在用完后 调用release释放

  2. 注意copy,retain,assign操作符的区别
    copy, retain操作符赋值的对象和alloc一样,需要release释放,否则会导致内存泄露
    assign 操作符的含义是将对象指向另一对象, 两者指向的是同一内存对象,无需调用release释放 

  3. NSArray, NSDictionary, NSMutableArray, NSMutableDictionary等容器类, 在使用这些容器类的时候要注意, 在添加对象到这些类对象时,容器类会自动调用一次retain,比如
    NSString* string  = [[NSString alloc] initWithString:@”test string”];  // refCount = 1
    NSArray* array = [NSArray array];
    [array addObject:string]; // refCount = 2
    [string release]; // refCount = 1
    这种情况, 即便string已经调用release,但是在加入 array中时已经调用了一次retain,注意refCount的变化 简单介绍一下iPhone 或者说Objective C对对象的管理机制。 OC中采用一种引用计数refCount的方式来管理内存对象,当refCount等于0的时候就会释放对象所占的内存, 操作符alloc,copy, retain都会将refCount加1表示引用计数增加, 而调用release使 refCount自动减1, 当refCount=0时表示该对象已经没有被引用,可以将其释放, 之后该对象便不可用

  4. 连续重复分配内存的过程最好创建自己的自动释放池 NSAutoreleasePool,通常是在for、while等循环操作过程中,比如
    for( int i=0; i < 100; i++ )
    {
    NSString* str = [[NSString alloc] initWithString:@”some string”];
    // 针对str的操作
    [str release];
    }
    在这种情况下,有2点需要注意,首先如果可能,就把str的分配、释放放在for循环外面, 从而减少内存的分配、释放导致程序效率低下,也利于内存回收,如上例应该为
    NSString* str = [[NSString alloc] initWithString:@”some string”];
    for( int i=0; i < 100; i++ )
    {
    // 针对str的操作
    }
    [str release];
    如果实际情况复杂,不能像例子中那样抽离出循环外,需要创建自己的内存管理池, 同样适用于需要大量autorelease对象的过程
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    for(int i=0; i < 100; i++ )
    {
    // actions
    }
    [pool release];
    之所以要这样做,是因为apple处理iPhone的内存管理机制问题, 通常情况下,系统会在需要的时候释放整理所有的autorelease对象,这就是为什么有时候autorelease对象在作用域范围外还有可能是有效的

  5. 避免不常用对象驻留内存, 桌面开发的tx很多喜欢在程序初始化的时候将某些资源比如小图片加载进内存,从而提高程序运行效率。 但这种方式在iPhone以及其它mobile移动设备开发时需要避免,因为对于这些设备来说,内存永远显得不足(当然普通pc内存也是越大越好:) )。 按照apple的官方说法, Load resources lazily . 就是在需要的时候再从硬盘上读取,而避免常驻内存。


原文链接:http://www.flyblog.info/catprogramming/168.html
Share:

2010年4月17日星期六

xcode中object-c c++混编出现的问题

error: expected unqualified-id before'@' ,出现一大堆的错误

出现这种情况的原因是xcode无法分辨出,要编译的文件类型 是c++ 还是 object-c++ ,所以默认使用object-c 或是 c++进行编译。这样就会导致类型错误,很多东西未定义

错误情况: object-c代码中使用c++代码

或者c++代码中使用object-c 代码

解决情况

如果是在object-c中使用c++代码,则将.m 文件名改为.mm ,另外在文件名上右键-Get info-》将文件类型改为 sourcecode.cpp.objcpp

如果是在c++类中引用object-c代码,则在文件名上右键-Get info-》将文件类型改为 sourcecode.cpp.objcpp

--------------

XCode Error ".objc_class_name_XXX", referenced from: 错误解决

某源文件在主target里面没有加进来,引用这个文件就会出现标题所示的错误,解决方法是找到这个文件,把后面的勾打上(加入到这个target里面来).

在文件上右键 -getinfo-》targets-》将属于的target打上勾

Linking Error: Symbol Not Found


错误的几种原因:

1。 文件类型错误 xocde无法分辨除要编译的文件是objc 还是 objcpp (解决方法见上)

2。 文件未包含在target中 (解决方法见上)

3。源代码文件中使用的framework未包含在程序中 ,在target名称上右键getinfo -》 general -》linked libraries -》+号添加 。或在Frameworks目录上右键 添加exsting frameworks
Share:

xcode object-c c c++混编时出现的错误

error: expected unqualified-id before'@'  ,出现一大堆的错误。

出现这种情况的原因是xcode无法分辨出,要编译的文件类型 是c++ 还是 object-c++ ,所以默认使用object-c

错误情况: object-c代码中使用c++代码

                    或者c++代码中使用object-c 代码

解决情况

如果是在object-c中使用c++代码,则将.m 文件名改为.mm ,另外在文件名上右键-Get info-》将文件类型改为 sourcecode.cpp.objcpp

如果是在c++类中引用object-c代码,则在文件名上右键-Get info-》将文件类型改为 sourcecode.cpp.objcpp
Share: