IOS开发总结.rar (29 K) 下载次数:172 暂时总结出这些,后续会慢慢增加
有点乱,实在是文笔不好,请见谅
九十九条啊,我慢慢积累,一年估计还是能写到的吧
(一)关于 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
= [UIColor
clearColor
];
}
}
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);
2.
设置
layer context
的放大倍数
:
CGContextScaleCTM
(layerContext, scale, scale);
3.
如果当前设备是
retina
屏,在
layerContext
上的画的图都被放大了
4.
画完后,用
CGContextDrawLayerInRect
把
layerContext
画到未放大的区域。此处不能用
CGContextDrawLayerAtPoint
。
CGRect
bounds =
CGRectMake
(
0
,
0
, width, height);
CGContextDrawLayerInRect
(context, bounds, layerContext);
[ 此帖被mhmwadm在2013-03-01 15:33重新编辑 ]