----webView中加载的地址格式:必须为加上http://的格式;
----NSTimer开启定时方法:recordTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(recordTiming:) userInfo:nil repeats:YES];
若在方法recordTiming:(NSTimer *)timer里面用参数timer停止定时器,[timer invalidate]; timer = nil; 则在其他地方用到recordTimer 判断(外部终止定时器),[recordTimer invalidate]则程序会crash,解决办法:1.在timer参数停止完定时器之后加一句,recordTimer = nil;2.在recordTiming:(NSTimer *)timer方法里面用recordTimer去停止定时器。
-----button的text不显示:UILabel的text默认是黑色的,UIButton的label中text默认是白色的,所有如果背景是白色的,可能会导致相关内容看不到。
-----label背景为白:ios8以后,UILabel默认背景色不在是透明的了,而是白色。
-----使用UItextField的时候,如果想让控制器响应textFieldShouldBeginEditing等方法,需要控制器实现UItextField的代理,给UItextField的delegate赋值等。
-----使用tableview的时候,想要分段显示,如果tableview的style时plain,设置heightForHeaderInSection,虽可以达到分段效果,但是section的header滑动的时候滑到头了就会停靠tableview上;要想达到正常的分段效果,使用group的style。注意俩个分段的间距 = 上个header + 下个footer高度。默认是10pt,如果第一个想顶格,heightForHeaderInSection返回0.1即可。
-----关于NSRange成员的说明:表示范围(location,length),其中loc表示从哪个位置开始(包含该位置),位置的开始位置从0开始,len表示个数。例如,[@"012345679" substringWithRange:NSMakeRange(1, 2)] 表示“12”。
-----关于 substringToIndex + substringFromIndex 方法参数的说明:例如,toIndex:3 表示从开始到位置3之间(不包括3),FromIndex:3表示从位置3(包括3)开始。位置几的计算都是从0开始算。
-----关于方法textField:shouldChangeCharactersInRange:replacementString说明:例如做一个手机格式139 8888 8888格式输入优化:
if (textField == self.displayTel) {
if (0 < [string length]) { // 添加字符串
// 139 1122 3344 格式
if (3 == [self.displayTel.text length]) {
self.displayTel.text = [self.displayTel.text stringByAppendingString:@" "];
return YES;
}else if (8 == [self.displayTel.text length]){
self.displayTel.text = [self.displayTel.text stringByAppendingString:@" "];
return YES;
}else if (13 == [self.displayTel.text length]){
return NO;
}
}else if(0 == [string length]){ // 删除字符串
// 139 1122 3344 格式 0,3 4,4
if (5 == [self.displayTel.text length]) {
self.displayTel.text = [self.displayTel.text substringToIndex:4]; // return yes 还会删除一个字符,下同
return YES;
}else if (10 == [self.displayTel.text length]){
self.displayTel.text = [self.displayTel.text substringToIndex:9];
return YES;
}
}
}
return YES;
总结:1.replacementString(上面string)表示当前修改的字符串,可以有一定内容(新增字符操作),也可能是空串(删除字符操作);
2.range:表示当前发生改变的位置,如果在n位置处新增一个字符串是(n,0),在n位置处删除一个字符串是(n,1),n也是从0开始,表示后者对比前者改变的range,所以新增长度是0(新增串替换原来位置,原来位置空,所以长度0),删除长度是1(空串替换了长度为1的字符串);
3.注意方法的返回值,return YES,会允许该改变,所以上面例子substringToIndex参数是4,因为之后还会删除一个字符串。
-----[tableview cellForRowAtIndexPath:indexPath]方法,有时为了获取cell上面的一些子视图(textfield),来赋值、弹下键盘等,用来它获取tableview的特定cell。但该方法有隐患,如果indexpath不在屏幕显示区域,方法返回nil,所以用的时候,要做好它为nil的准备。从indexPathsForVisibleRows方法也可以看出来,并不是所有的indexPaths都有用
-----label的attributedText和text属性是“共存”的,不要以为是相互独立的。如果将text属性置为nil,attributedText也显示不出来;
-----关于UIButton中setTitle:forState 和btn.titleLabel.text的区别:(1)前者是Sets the title to use for the specified state.为不同btn的state,赋予字符串;(2)后者是A view that displays the value of the currentTitle property for a button. (read-only),即展示currentTitle的label。
注意currentTitle的说明:The current title that is displayed on the button.The value for this property is set automatically whenever the button state changes.因为button有不同状态,所以currentTitle值可能在不同状态下不同。
所以,前者是为btn不同状态下的显示字符串赋值。而后者是显示不同状态下title用的label。所以为btn赋予字符显示必须用前者,测试发现后者不好使。同理
// 这些可以
button.titleLabel.font = [UIFont systemFontOfSize: 12];
button.titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
// text color or shadow color 必须用 setTitleColor:forState: and setTitleShadowColor:forState:
-------遍历+删除:报错NSGenericException was mutated while being enumerated。但你在遍历一个数组的时候,不能在里面同时做删除操作!
解决办法:1.换成2个数组操作,一个用于遍历,一个实际删除; 2.拆成俩个过程,新找出来,之后再删除。
NSArray *tempArray = [yourArray copy];
for(id obj in tempArray) {
//It's safe to remove objects from yourArray here.
}
[tempArray release];
NSMutableArray *toDestroy = [NSMutableArray arrayWithCapacity:_contactor.count];
for(Man *sprite in self.contactor)
{
if (sprite.hp<=0 && sprite.stat == stat_attack)
{
[sprite stopAllActions];
[sprite animDead];
[toDestroy addObject:sprite];
}
}
[self.contactor removeObjectsInArray:toDestroy];
-----关于浮点数显示技巧:例如2.100 /2.1统一显示为2.1;将基本浮点类型转换为对象即可;
float a = 0.1;
float b = 0.100;
float c = 2;
NSLog(@"%@",[NSString stringWithFormat:@"%f",a]); // 0.100000
NSLog(@"%@",[NSString stringWithFormat:@"%f",b]); // 0.100000
NSLog(@"%@",[NSString stringWithFormat:@"%f",c]); // 2.000000
NSLog(@"%@",@(a)); //相当[NSNumber numberWithFloat:a]) 下同 // 0.1
NSLog(@"%@",@(b)); // 0.1
NSLog(@"%@",@(c)); // 2
[self.window addsubview:MyVC.view];
[self.window.rootviewcontroller=MyVC];
// 两个方法的区别:
方法(1)存在一些问题,比如说控制器上面可能由按钮,需要监听按钮的点击事件,如果是1,那么按钮的事件应该由控制器来进行管理。但如果控制器是一个局部变量,控制器此时就已经不存在了,但是控制器的view还在,此时有可能会报错。
问题1:当view发生一些事件的时候,通知控制器,如果控制器已经销毁了,所以可能出现未知的错误。
问题2:添加一个开关按钮,让屏幕360度旋转(两者的效果不一样)。当发生屏幕旋转事件的时候,UIapplication对象会将旋转事件传递给uiwindow,uiwindow又会将旋转事件传递给它的根控制器,由根控制器决定是否需要旋转,UIapplication->uiwindow->根控制器(第一种方式没有根控制器,所以不能跟着旋转)。
提示:第一种只是添加了一个视图,对比第二种,对根控制器掌控更多,生命周期等。