信仰

猛图www.omeng.org

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

IOS开发总结

By mhmwadm 转自 http://www.cocoachina.com/bbs/read.php?tid=105689

(一)关于UITableView

1.任意设置Cell选中状态的背景色:

UIView *bgView = [[UIView alloc] init];

bgView.backgroundColor = [UIColor orangeColor];

self.selectedBackgroundView = bgView;

[bgView release];

该方法设置的是纯色, 也可以使用任何图片,把selectedBackgroundView设成UIImageView。

 

除了上面的方法,前几天发现了一个新方法:重写UITableViewCell 的 setSelected:animated:方法

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];
   if (selected) {
      self.backgroundColor= RGB(224, 152, 40);
   }
   else{
      self.backgroundColor= [UIColorclearColor];
   }
}

 

2.如果Table中有控件,这里以switch为例(适合其它可修改值的各种控件),要在switch的UIControlEventValueChanged事件的处理方法里把值记录下来。以下方法是不可取的:在执行的最后把所有cell遍历一遍,处理各控件的值。因为没显示出来的cell,是取不到的,当然也就取不到该cell里的控件。所以正确的做法是,在控件可见时,如果值变了,立即处理。当然,如果你的Cell少,不会出现隐藏的情况就随便了。

  

3.方法flashScrollIndicators:这个很有用,闪一下滚动条,暗示是否有可滚动的内容。可以在ViewDidAppear或[table reload]之后调用。

 

4.点击Cell中的按钮时,如何取所在的Cell:

-(void)OnTouchBtnInCell:(UIButton *)btn
{
CGPoint point = btn.center;
point = [table convertPoint:point fromView:btn.superview];
NSIndexPath* indexpath = [table indexPathForRowAtPoint:point];
UITableViewCell *cell = [table cellForRowAtIndexPath:indexpath];
...
//也可以通过一路取btn的父窗口取到cell,但如果cell下通过好几层subview才到btn,就要取好几次 superview,所以我用上面的方法,比较通用。这种方法也适用于其它控件。
}

(二)设置线宽,如果是retina屏,lineWidth设为1,实际显示的宽度是2个像素,这里进行一下处理: 

#define SETLINEWIDTH(ctx,w) CGContextSetLineWidth(ctx, w/[UIScreen mainScreen].scale)

(三)_cmd:表示该方法的selector,可以赋值给SEL类型的变量,可以做为参数传递。

例如一个显示消息的方法:

-(void)ShowNotifyWithString:(NSString *)notifyString fromMethod:(SEL) originalMethod;

originalMethod就是调用这个方法的selector。

 

调用:

NSString *stmp = @"test";

[self ShowNotifyWithString:stmp fromMethod:_cmd];

 

如何记录当前方法名称:

NSLog(NSStringFromSelector(_cmd));

 

(四)在CGContext中输出汉字:CGContextShowTextAtPoint是不支持汉字的,需要用NSString的drawAtPoint或drawInRect方法

 

(五)一个不停震动的方法:

// 定义一个回调函数,震动结束时再次发出震动

void MyAudioServicesSystemSoundCompletionProc (SystemSoundID  ssID,void *clientData)

{

      BOOL* iShouldKeepBuzzing = clientData;

      if (*iShouldKeepBuzzing) {        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

      } else {

           //Unregister, so we don't get called again...

           AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate);

      } 

}

 

以下为调用的代码:

BOOL iShouldKeepBuzzing = YES;

AudioServicesAddSystemSoundCompletion ( 

  kSystemSoundID_Vibrate,                                                                       

  NULL,                                                                                                    

  NULL,                                                                                                              

  MyAudioServicesSystemSoundCompletionProc,                                                 

&iShouldKeepBuzzing );

AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);

(六)关于更新,iPhone自动保存document中的内容,如果你把文件放在document中,以后开发又改了这个文件的内容或格式,那更新之后运行很可能出错。解决的办法是,配置文件放bundle里,或者改个文件名。每次更新前都要从App store 下载旧版本,运行一段一时间后,再此基础上编译新版,运行不出错才能上传

 

(七)初学者或者不小心容易犯的错误:在dealloc里要调用[super dealloc],千万不要调用[super release]

(八)需要调试的类最好重写description,输出重要变量的值,因为调试窗口variableView有时候变量值显示不出来。

(九)去掉app图标的发光效果:info.plist里增加Icon already includes gloss effects,值设为YES

(十)写代码时字符串太长 怎么换行:NSString *string = @"ABCDEFGHIJKL" \
                                        "MNOPQRSTUVsWXYZ";

(十一)UIImage:stretchableImageWithLeftCapWidth:topCapHeight: 有时图片模糊(blur)的原因:像素没有和device pixel对齐.使用instrument 的Core Animation可以检测这个,勾选"color misaligned images",如果图片显示为红紫色,就是没有对齐

(十二)UIPopoverController如果是用presentPopoverFromBarButtonItem显示的,设备旋转时,popover可以自动调整位置;如果是用presentPopoverFromRect显示的, 需要present again

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation

{

[aPopover presentPopoverFromRect:targetRect.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

}

(十三)UIColor colorWithRed:green:blue:alpha:这个方法的参数必须用浮点型。

假如使用Xcode自带的取颜色的工具,取到的RGB值分别为:25,25,25,

传给上述方法的参数应为25/255.0或25.0/255。如果用整型25/255,经过取整,小数部分没有了,显示出来的颜色和取到的是不一样的。可以定义一个宏:

#define RGB(A,B,C) [UIColor colorWithRed:A/255.0 green:B/255.0 blue:C/255.0 alpha:1.0]

然后用RGB(25,25,25)就可以了

 

(十四)禁止textField和textView的复制粘贴菜单:

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender

{

     if ([UIMenuController sharedMenuController]) {

       [UIMenuController sharedMenuController].menuVisible = NO;

     }

     return NO;

}

(十五)时间相关

NSDate需要设置calendar,使用不方便也因为服务器传过来的是time_t格式,所以我在客户端对时间的操作主要用的C语言的方法。

需要注意的是,有的函数不是线程安全的,也就是说在同一个范围内调用多次时,需要调用线程安全的版本,这样的函数有:

localtime_r

asctime_r

ctime_r

gmtime_r

localtime_r

另外,可以直接给struct tm各成员变量赋值,例如(注意顺序)

struct tm tmStart = {second,minute,hour,day, mon, year};

struct tm的各成员是不能的加减的,因为超过了各变量的范围,可能出错,需要先转成time_t,再加减相应的时间

 

(十六) 如果重载loadView,一定要在这个方法里产生一个self.view。可以调用[super loadView],也可以使用alloc+init。

错误情况举例:loadView 直接调用self.view.alpha = 0.5; 因为self.view为nil,self.view.alpha这句又会调用loadView,也就是loadView不断调用loadView,进入了死循环

 
(十七)GestureRecognizer相关

1.一个View有GestureRecognizer又有按钮(或其它需要处理action event的控件)时,有时按钮不灵敏,解决办法:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch

{

     CGPoint pt      = [touch locationInView:baseView];

     UIView *btn     = [baseView viewWithTag:TAG_MYBTN];

     CGPoint ptInbtn = [baseView convertPoint:pt toView:btn];

     return ![btn pointInside:ptInbtn withEvent:nil];

}

2.实现某个view点一下就移除时,要防止移除两次。(此方法适用于希望GestureRecognizer只执行一次的情况)

-(void)OnTapViewTobeRemoved:(UITapGestureRecognizer *)sender

{

     if (!sender.enabled) {

           return;

     }

     sender.enabled = NO;

     [sender.view removeFromSuperview];

}

(十八)如何进入软件在app store 的页面:

先用iTunes Link Maker找到软件在访问地址,格式为itms-apps://ax.itunes.apple.com/...,然后

#define  ITUNESLINK   @"itms-apps://ax.itunes.apple.com/..."

NSURL *url = [NSURL URLWithString:ITUNESLINK];

if([[UIApplication sharedApplication] canOpenURL:url]){

     [[UIApplication sharedApplication] openURL:url];

}

如果把上述地址中itms-apps改为http就可以在浏览器中打开了。可以把这个地址放在自己的网站里,链接到app store。

iTunes Link Maker地址:http://itunes.apple.com/linkmaker

 

(十九)someview显示一断时间后自动消失

[self performSelector:@selector(dismissView:) withObject:someview afterDelay:2];

这么写比用NSTimer代码少,不过哪种都行的,这里只是提供一种不同的方法

(二十)使提示窗口在任何界面都能显示:

[self.navigationController.view addSubview:(自定义的提示窗口)]

或用UIAlertView

(二十一)禁止程序运行时自动锁屏

[[UIApplication sharedApplication] setIdleTimerDisabled:YES];

(二十二)判断一个字符串是否包含另一个字符串:

[str1 rangeOfString:str2].length != 0 ? @"包含" : @"不包含"

 

(二十三)没有用到类的成员变量的,都写成类方法

 

(二十四)navigationItem的backBarButtonItem的action是不会执行的.无论怎么改,除了popViewController什么都不执行。
例如:
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:self action:@selector(onComingback)];
self.navigationItem.backBarButtonItem= backButton;
在下一级视图中点“返回”,onComingback也是不会执行的。target和action都被忽略了,所以参数用nil就行了
要想在点“返回”时执行某段代码,只能自己做一个像返回按钮那样的UIBarButtonItem,图片是需要自己做的。self.navigationItem.leftBarButtonItem= custombackButton; // custombackButton的方法中包含popViewController和你想加的其它代码

(二十五)category可以用来调试。除了隐藏私有方法外,我主要用它截住函数。
例1:测试时我想知道TableViewCell有没有释放,就可以这样写

@implementation UITableViewCell(dealloc)
-(void)dealloc
{
    NSLog(@"%@",NSStringFromSelector(_cmd));
    // allSubviews是cookBook里的函数,可以取一个view的所有subView
     NSArray *array = allSubviews(self);
     NSLog(@"%@",array);

    [super dealloc];
}
@end

其它的类也可以这样写,你随便输出什么
例2:我调试程序,觉得table的大小变了,想找到在哪改变的,这样做:

@implementation UITableView(setframe)
-(void)setFrame:(CGRect)frame
{
    NSLog(%"%@",self);
     [super setFrame: frame];
}
@end


(二十六)改变UIAlertView背景UIAlertView默认是半透明的,会透出背景的内容,有时看着有些混乱。可以写个改变背景的方法changeBackground。

@interface UIAlertView (changeBK)
- (void)changeBackground;
@end

@implementation UIAlertView (changeBK)
- (void)changeBackground
{
    for(UIView * v in [self subviews]){
        if ([v isKindOfClass:[UIImageViewclass]]) {
            UIImage *theImage = [UIImage imageNamed:@"AlertView.png"];
            ((UIImageView*)v).image = theImage;
            break;
        }
    }
}
@end



在[alertView show]之后或willPresentAlertView:中调用即可。

// UIAlertView *alertView = [UIAlertView alloc] init ...
...
[alertView show];
[alertView changeBackground];

(二十七)浮动提示
有时需要显示一个视图,几秒后再消失的功能,这个功能也可以写成category

@interface UIView (AutoRemove)
- (void)removeAfterDelay:(NSTimeInterval)time;
- (void)removeImediatly;
@end

 

@implementation UIView (AutoRemove)
- (void)removeAfterDelay:(NSTimeInterval)time
{
    [self performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:time];
}

- (void)removeImediatly
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self     selector:@selector(removeFromSuperview) object:nil];
    [selfremoveFromSuperview];
}
@end

(二十八)改变UITextField的背景
可以给textField加好看的边框等

@interface UITextField (changeBK)
-(void)orangeBackground;
@end

 

@implementation UITextField (changeBK)
-(void)orangeBackground
{
    self.background= [[UIImageimageNamed:@"fieldBK.png"] stretchableImageWithLeftCapWidth:5topCapHeight:5];
}
@end

(二十九)判断版本号的简便方法

NSString *currSysVer = [[UIDevice currentDevice] systemVersion];

  if ([currSysVer compare:minRequirement options:NSNumericSearch] != NSOrderedAscending)

  {

    return YES;

  }else{

    return NO;

  }

(三十)CALayer高清显示

if ([myLayer respondsToSelector:@selector(setContentsScale:)]) {

    myLayer.contentsScale = [[UIScreen mainScreen] scale];

}

(三十一)CGLayer高清显示

这个复杂一些,但对非Retina和Retina屏是通用的。

  1. 在context上创建一个图层,大小为要画区域的scale倍。scale为1或2,从UIScreen可以取到:

int width = 25;

int height = 25;

float scale = [self contentScaleFactor];

CGRect bounds = CGRectMake(0, 0, width * scale, height * scale);

CGLayer layer = CGLayerCreateWithContext(context, bounds.size, NULL);

CGContextRef layerContext = CGLayerGetContext(layer);

  1. 设置layer context的放大倍数:

CGContextScaleCTM(layerContext, scale, scale);

  1. 如果当前设备是retina屏,在layerContext上的画的图都被放大了
  2. 画完后,用CGContextDrawLayerInRect 把layerContext 画到未放大的区域。此处不能用CGContextDrawLayerAtPoint。

CGRect bounds = CGRectMake(0, 0, width, height);

CGContextDrawLayerInRect(context, bounds, layerContext);

 

posted on 2013-03-21 16:08  信仰123  阅读(373)  评论(0编辑  收藏  举报

猛图