1、点击UIButton 无法产生触摸事件
如果在UIImageView中添加了一个按钮,你会发现在默认情况下这个按钮是无法被点击的,需要设置UIImageView的userInteractionEnabled为YES:
imageView.userInteractionEnabled = YES;
设置为YES后,UIImageView内部的按钮就可以被点击了
大部分app在启动过程中全屏显示一张背景图片,比如新浪微博会显示这张:
要想在iOS中实现这种效果,毫无压力,非常地简单,把需要全屏显示的图片命名为Default.png即可,在iOS app启动时默认会去加载并全屏显示Default.png。
也可以用其他名称来命名图片,在Info.plist配置一下即可:
配置过后,app启动时就会去加载并全屏显示lufy.png
在默认情况下,app显示Default.png时并非真正的"全屏显示",因为顶部的状态栏并没有被隐藏,比如下面的效果:
大部分情况下,我们都想隐藏状态栏,让Default.png真正全屏显示。
说到这里,可能有人马上就想到了一种办法:在AppDelegate的application:didFinishLaunchingWithOptions:方法中添加如下代码:
[UIApplication sharedApplication].statusBarHidden = YES;
我只能说你的思路是对的,但实际上达不到想要的效果,你会发现显示Default.png时状态栏还是存在的,等Default.png显示完毕后,状态栏才被隐藏。
我先解释下为什么这种方法不可行,其实原因很简单:
1> Default.png是在app启动过程中加载的,并不是在app启动完毕后再加载的
2> AppDelegate的application:didFinishLaunchingWithOptions:方法是在app启动完毕后才调用的
下面说一下解决方案,在Info.plist中增加一个配置即可:
这里的YES表示在app初始化(启动)的时候就隐藏状态栏。
当然,在Default.png显示完毕后状态栏还是隐藏的。如果想重新显示状态栏,补上下面代码即可:
[UIApplication sharedApplication].statusBarHidden = NO;
假如我的APP,第一次启动请求了登录接口并得到了Cookie,然后我把APP关了,下次启动APP,我不请求登录接口了,那上次得到的Cookie就不存在了。如果需要,那么2种方法,下次启动app,自动登入,这样能得到服务器分配给你的cookier(这一种是最好的,因为session也会过期),还有一种是你把上次登入的时候,拿到的cookier存起来,然后下次启动app的时候,手动给请求(ASIHTTP)添加cookie。
所以当第一次登录成功后,可以把cookie保存到CoreData,SQLite,UserDefault等,等到下次网络请求时,读取:
1 ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:UserInfoURL]; 2 [request setRequestMethod:@"POST"]; 3 [request addRequestHeader:@"Cookie" value:[NSString stringWithFormat:@"cookie=%@",[[NSUserDefaults standardUserDefaults] objectForKey:@"cookie"]]]; 4 //把cookie的值放进Header里,这个cookie的值是一串很长的字符串。
TextField设置这个属性为YES就可以了,默认为NO
searchField.enablesReturnKeyAutomatically =YES;
其实是一个小气泡png,然后拉伸中间部分,四个角不拉动,就是局部拉伸。ios自带方法,四个角可以不拉伸的,如下:
首先要实现TextField的delegate,在方法:
1 - (void)textFieldDidBeginEditing:(UITextField *)textField { 2 [self.tableView setContentOffset:CGPointMake(0, 70) animated:YES]; 4 }
这说明当开始输入时,tableview在原来的基础上向上抬起70个距离。多个UITextFiled可以通过判断来使用CGPoint的调整高度,我这写的是70.
tableview的scrollEnabled属性一定要是YES;要不然滚动不了了。
记得在return时复原tableview的位置:
1 - (BOOL)textFieldShouldReturn:(UITextField *)sender { 2 [self.tableView setContentOffset:CGPointMake(0, 0) animated:YES]; 3 return YES; 4 }
我们给自己的工程添加一个全局的断点:
一步步按上面图完成操作。
再运行程序
自动就断点到这里来了,
log信息是:
2013-05-20 11:14:19.635 GestureRecognizer[1491:c07] -[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0x7a88df0 2013-05-20 11:15:21.148 GestureRecognizer[1491:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0x7a88df0'
这样很简单就能发现程序崩溃是因为value没有 isEqualToString方法。如果没加上面这个通用的断点,那程序会直接断点到main函数去。
从UImageView上找ContentMode或clipToBounds是都不管用的,正确的办法是,不用UImageView,使用UIView,然后设置backgroundColor属性为我们的图片,这样的话自动会以屏幕的方式显示。
1 UIView *gridView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 195)]; 2 gridView.backgroundColor = [UIColor colorWithPatternImage:BUNDLE_IMAGE(@"blue_grid")]; 3 [self.view addSubview:gridView]; 4 [gridView release];
下图所示:(原图是一个6X6的方格)
在开发时,想要在tableview中的某一个Cell设置选中状态,并且Cell的背景颜色是一个自定义颜色。
1 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 2 3 <span style="white-space:pre"> </span>//省略.... 5 cell.textLabel.font = [UIFont systemFontOfSize:6.0]; 6 cell.textLabel.text = @"13832207020"; 7 8 if (indexPath.row==0) { 10 [cell setBackgroundColor:[UIColor colorWithRed:100.0f/255.0f green:176.0f/255.0f blue:0.0f/255.0f alpha:1.0f]]; 11 } 12 else{ 13 [cell setBackgroundColor:[UIColor whiteColor]]; 14 } 15 16 return cell; 17 }
这样的话,第1行cell就应该是我们设置好的颜色,不过请注意,此方法在UITableViewStylePlain的风格下有效,在 UITableViewStyleGrouped的样式下是无效的!这个跟tableview的backgroundView和backgroundColor是没有关系的,个人猜想应该是在Grouped风格下,cell选中的颜色有系统的view遮罩,导致我们设置的无法显示出来。
【补充】如果想在reload或init时设置tableview的某一cell为 selected状态,千万不要使用cell setSelected:YESanimated:YES,使用tableview的方法:
1 NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0]; 2 terminalTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
使用系统或简单自定义的UITableViewCell时,当选中某一行Cell后,除了背景颜色改变外,Cell上所有的组件(数据)比如UILabel,UIbutton等都被自动显示成了其
Highlighted(高亮)状态下的效果,(如果想显示出效果,你的那些自定义的组件必须要设置高亮状态,比如highlightedTextColor,UIControlStateHighlighted等),所以这一点需要特别注意,如果不想要系统的这个自动特效,有两个解决办法:
1,组件不设置highlighted下的属性
2,如果自定义的Cell:
1 - (void)setSelected:(BOOL)selected animated:(BOOL)animated 2 { 4 [super setSelected:selected animated:animated]; 6 if (selected) { 7 //强制系统在UITableViewCell选中时SettingButton组件的高亮状态为NO 8 [(UIButton *)[self.contentView.subviews objectAtIndex:1] setHighlighted:NO]; 9 [settingBtn setImage:BUNDLE_IMAGE(@"accessory_sel") forState:UIControlStateNormal]; 10 } 11 else{ 12 [settingBtn setImage:BUNDLE_IMAGE(@"accessory_nor") forState:UIControlStateNormal]; 13 } 16 }
atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。
atomic
设置成员变量的@property属性时,默认为atomic,提供多线程安全。
在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。加了atomic,setter函数会变成下面这样:
{lock}
if (property != newValue) {
[property release];
property = [newValue retain];
}
{unlock}
nonatomic
禁止多线程,变量保护,提高性能。
atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。
指出访问器不是原子操作,而默认地,访问器是原子操作。这也就是说,在多线程环境下,解析的访问器提供一个对属性的安全访问,从获取器得到的返回值或者通过设置器设置的值可以一次完成,即便是别的线程也正在对其进行访问。如果你不指定 nonatomic ,在自己管理内存的环境中,解析的访问器保留并自动释放返回的值,如果指定了 nonatomic ,那么访问器只是简单地返回这个值。
assign
对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char)等等。
此标记说明设置器直接进行赋值,这也是默认值。在使用垃圾收集的应用程序中,如果你要一个属性使用assign,且这个类符合NSCopying协 议,你就要明确指出这个标记,而不是简单地使用默认值,否则的话,你将得到一个编译警告。这再次向编译器说明你确实需要赋值,即使它是 可拷贝的。
retain
对其他NSObject和其子类对参数进行release旧值,再retain新值
指定retain会在赋值时唤醒传入值的retain消息。此属性只能用于Objective-C对象类型,而不能用于Core Foundation对象。(原因很明显,retain会增加对象的引用计数,而基本数据类型或者Core Foundation对象都没有引用计数——译者注)。
注意: 把对象添加到数组中时,引用计数将增加对象的引用次数+1。
copy
对NSString 它指出,在赋值时使用传入值的一份拷贝。拷贝工作由copy方法执行,此属性只对那些实行了NSCopying协议的对象类型有效。更深入的讨论,请参考“复制”部分。
copy与retain:
Copy其实是建立了一个相同的对象,而retain不是:
1.比如一个NSString 对象,地址为0×1111 ,内容为@”STR”,Copy 到另外一个NSString 之后,地址为0×2222 ,内容相同。
2.新的对象retain为1 ,旧有对象没有变化retain 到另外一个NSString 之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1。
总结:retain 是指针拷贝,copy 是内容拷贝。
assign与retain:
1. 接触过C,那么假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b。此时a和b指向同一块内存,请问当a不再需要这块内存,能否直接释放它?答案是否定的,因为a并不知道b是否还在使用这块内存,如果a释放了,那么b在使用这块内存的时候会引起程序crash掉。
2. 了解到1中assign的问题,那么如何解决?最简单的一个方法就是使用引用计数(reference counting),还是上面的那个例子,我们给那块内存设一个引用计数,当内存被分配并且赋值给a时,引用计数是1。当把a赋值给b时引用计数增加到2。这时如果a不再使用这块内存,它只需要把引用计数减1,表明自己不再拥有这块内存。b不再使用这块内存时也把引用计数减1。当引用计数变为0的时候,代表该内存不再被任何指针所引用,系统可以把它直接释放掉。
总结:上面两点其实就是assign和retain的区别,assign就是直接赋值,从而可能引起1中的问题,当数据为int, float等原生类型时,可以使用assign。retain就如2中所述,使用了引用计数,retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收。
它们告诉Xcode编译器,要在编辑器窗格顶部的方法和函数弹出菜单中将代码分隔开;注意 #pragma mark – 的“-”后面不能有空格。如果你的标志没有出现在弹出菜单中,比如没有分隔线出现,请在Xcode菜单 “Preferences..”中的 “Code Sense”选项取消选中”Sort listalphabetically”即可。
我们通过发送消息给对象出发特定动作;对象发送某些变化的时候通过回调函数(callback)通知我们。对象在特定事件发生的时候,就会调用对应的回调函数,触发业务逻辑。回调函数通过所谓的代理(Delegation)来实现.
delegate使用方法:
@property (assign) <id>xxxDelegate delegate;
正确的使用方法是使用assign属性而不是retain。之所以对于delegate这类对象使用assign而不是用retain是为了防止循环retain(retain loop)
使用@property和@synthesize声明一个成员变量,给其赋值是时要在前面加上"self.",以便调用成员变量的setmember方法。直接调用成员变量并且给其赋值:member=[NSString stringWithFormat:@””];将不执行setmember 方法。
使用self调用成员变量并且给其赋值:self.member=[NSString stringWithFormat:@””];将执行setmember方法。
1 startRangeButton = [UIButton buttonWithType:UIButtonTypeCustom]; 2 startRangeButton.frame = CGRectMake(85,componentOriginY, regionImage.size.width, 16); 3 [startRangeButton setBackgroundImage:regionImage forState:UIControlStateNormal]; 4 //还可以设置其高亮状态startRangeButton setBackgroundImage:regionImage forState:UIControlStateHighlighted]; 5 startRangeButton.titleLabel.font = [UIFont systemFontOfSize:7.0]; 6 [startRangeButton setTitle:@"2013-08-01 07:00" forState:UIControlStateNormal]; 7 [startRangeButton setTitleColor:COLOR(101, 199, 240, 1) forState:UIControlStateNormal]; 8 [startRangeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
代码中我设置button背景图片为自己定义的一个regionImage,并设置了button的title = “2013-08-01 07:00”【注意,设置了背景图片后,title只能这样添加,以button.titleLabel.text方式添加会无法显示的】,并且设置了tiitle正常和高亮下文字颜色。
所以看到这里,应该明白button.setBackgroundImage 和 set Image 的区别了吧,前者是可以同时设置文字,后者是一旦设置了image,无法再显示文字。
普通:高亮:
[formatter setDateFormat:@"yyyy-MM-dd HH:mm"]; 这种格式得到的数值是精确到秒的,也就是说少1000,
但是尝试[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];或SS大写,或[formattersetDateFormat:@"yyyy-MM-dd HH:mm.ss.SSS"];都不起作用,最后才发现,原来是这样
NSTimeInterval本身是个秒级别的double类型数值,小数点后面即毫秒数,*1000.0f即可得到毫秒级别的时间差
1 //为了兼容java版本,事件是从1970/1/1开始 2 3 -(NSDate *)getDateTimeFromMilliSeconds:(long long) miliSeconds 5 { 7 NSTimeInterval tempMilli = miliSeconds; 8 9 NSTimeInterval seconds = tempMilli/1000.0; 10 11 NSLog(@"seconds=%f",seconds); 12 13 return [NSDate dateWithTimeIntervalSince1970:seconds]; 15 } 16 17 18 19 //将NSDate类型的时间转换为NSInteger类型,从1970/1/1开始 20 21 -(long long)getDateTimeTOMilliSeconds:(NSDate *)datetime 23 { 25 NSTimeInterval interval = [datetime timeIntervalSince1970]; 26 27 NSLog(@"interval=%f",interval); 28 29 long long totalMilliseconds = interval*1000 ; 30 31 NSLog(@"totalMilliseconds=%llu",totalMilliseconds); 32 33 return totalMilliseconds; 35 }
也就是说,计算结果再自己乘以1000就可以了
1 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 2 [formatter setDateFormat:@"yyyy-MM-dd HH:mm"]; 3 4 NSDate *sDate = [formatter dateFromString:startRangeButton.titleLabel.text]; 5 NSDate *eDate = [formatter dateFromString:endRangeButton.titleLabel.text]; 6 NSTimeInterval sinterval = [sDate timeIntervalSince1970]; 7 long long start = sinterval*1000; 8 NSTimeInterval einterval = [eDate timeIntervalSince1970]; 9 long long end = einterval*1000; 10 [mConnectionHelper doTrack:mobile startTime:start endTime:end];
Objective-C 支持全局变量
主要有两种实现方式:
(1)第一种和C/C++中的一样, 使用"extern"关键词;
(2)另外一种就是使用单例实现。
(比如我们经常会把一个变量放在AppDelegate里面作为全局变量来访问, 其中AppDelegate就是一个单例类)
在Objective-C中如何实现像C++中那样的静态成员变量呢?
你需要做的是在一个类A的implementation(.m或者.mm)文件中定义一个static变量,然后为A类定义静态成员函数(class method,也就是类方法)来操作该变量。
1 //example.h 2 @interface Example : NSObject { 3 4 } 5 - (id)init; 6 +(int)instanceCount; 7 @end
1 //example.m 2 #import "example.h" 3 static int count; 4 @implementation Example 5 -(id)init{ 6 self = [super init]; 7 if(nil!=self){ 8 count+=1; 9 } 10 return self; 11 } 12 +(int)instanceCount{ 13 return count; 14 } 15 @end
上面的例子中你就可以通过[Example instanceCount]对静态变量count进行访问,无须创建实例。
警告: static 写在interface外面编译是没有错误的,但是编译器会报警告,这么说这样的写法是不被编辑器认可的。
错误:static 写在interface里面会直接报错,显然这样的语法是不被认可的。
static关键字声明的变量必须放在implementation外面,或者方法中,如果不为它赋值默认为0,
它只在程序开机初始化一次。
简单点的来,两个界面间传值,直接上代码了:
sendViewcontroller.m
1 //SettingViewController :接受值的viewcontroller 2 SettingViewController *setting = [[SettingViewController alloc] init]; 3 [[NSNotificationCenter defaultCenter] addObserver:setting selector:@selector(received:) name:@"msetting" object:nil]; 4 NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:@"user",@"type", nil]; 5 6 [[NSNotificationCenter defaultCenter] postNotificationName:@"msetting" object:dict]; 7 [self.navigationController pushViewController:setting animated:YES]; 8 9 [setting release]; 10 SettingViewController.m(接收值的viewcontroller)
1 -(void)received:(NSNotification *)notification{ 2 3 id data = [notification object]; 4 NSLog(@"received data: %@",data); 5 }
这样就实现了基本的使用,跟delegate类似,注意 addObserver时,需要写目标viewcontroller的实例,而不是self。
如上图所示,遇到这个错误,从字面的意思我们大致能猜到,是有属性已经被release掉了,但是我们又使用它了,所以,一部一部排查把,一定有某个地方的属性提前被release掉了,自己手动管理内存就会有这样的困恼,代码很多,不想去找,一定要有耐心,找的过程还可以学到很多知识。
如上图,这个就是我找到的原因所在,unarchiver release掉了,而我们在其它的类中想使用location的属性。
在mac os 10.8中,svn Command line tools是没有自动安装的,这样的话,svn 命令行就会失效,解决办法:
1.打开xcode偏好设置(comand+,)-->"Download" -->Components:
2.点击“Command line tools”下载,下载完成之后安装。
3.安装完成之后,打开终端,输入“svn help”,如果出现如下所示,说明命令行工具安装好了。
1 CLLocationDegrees leftDegrees = mapView.region.center.longitude –(mapView.region.span.longitudeDelta / 2.0); 2 CLLocationDegrees rightDegrees = mapView.region.center.longitude +(mapView.region.span.longitudeDelta / 2.0); 3 CLLocationDegrees bottomDegrees = mapView.region.center.latitude –(mapView.region.span.latitudeDelta / 2.0); 4 CLLocationDegrees topDegrees = self.region.center.latitude +(mapView.region.span.latitudeDelta / 2.0); 5 if (leftDegrees > rightDegrees) { // Int'l Date Line in View 6 leftDegrees = -180.0 - leftDegrees; 7 if (coords.longitude > 0) // coords to West of Date Line 8 coords.longitude = -180.0 - coords.longitude; 9 } 10 If (leftDegrees <= coords.longitude && coords.longitude <= rightDegrees && bottomDegrees <= coords.latitude && coords.latitude <= topDegrees) { 11 // 坐标在范围内 12 }
IOS7 :
1 UIApplication *app = [UIApplication sharedApplication]; 2 3 // 应用程序右上角数字 4 app.applicationIconBadgeNumber = 99;
上面的代码可以搞定
IOS8:
iOS8中设置application badge value 会抛错:Attempting to badge the application icon but haven't received permission from the user to badge the
原因是因为在ios8中,设置应用的application badge value需要得到用户的许可。使用如下方法咨询用户是否许可应用设置application badge value
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
在这之前要判断系统是否为iOS8的系统,否则8之前的系统会报错。
1 UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil]; 2 3 [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; 4 5 UIApplication *app = [UIApplication sharedApplication]; 6 // 应用程序右上角数字 7 app.applicationIconBadgeNumber = 10;
注意:清除数字请将数字设置为 0
1-2设置标签栏按钮显示数字图标
1 UIViewController *second=[SecondViewController new]; 2 UITabBarItem *item=[[UITabBarItem alloc]initWithTitle:@"支付" image:[UIImage imageNamed:@"008"] selectedImage:[UIImage imageNamed:@"002"]]; 3 second.tabBarItem=item; 4 item.badgeValue=@"20";
效果如图
通过使用UIDevice:
[[UIDevice currentDevice] systemName];
[[UIDevice currentDevice] systemVersion];//os version
[[UIDevice currentDevice] uniqueIdentifier];
[[UIDevice currentDevice] model];
[[UIDevice currentDevice] name];
真机上结果:
System Name: iPhone OS
System Version: 4.2.1
Unique ID: 9b5ded78d5fa0ac96250f8b4af0e46f40b96ea6d
Model: iPhone
Name: “wwk”的 iPhone
模拟器上结果:
System Name: iPhone OS
System Version: 4.2
Unique ID: 21FFE0FF-429B-5D0B-96D2-EADCA3203260
Model: iPhone Simulator
Name: iPhone Simulator
uniqueIdentifier:iPhone通过,向几个硬件标识符和设备序列号应用内部散列算法,而生成这一标识符。
http://blog.csdn.net/qiwancong/article/details/7914923 参考
1-1 设置状态 如图
1-2添加代码:
1 //隐藏状态栏 2 [[UIApplication sharedApplication]setStatusBarHidden:YES];
实现效果 如图
#define __kFirstVersion @"kFirstVersion"
1 //根据App版本号来判断App开启时是否进入引导页 2 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 3 4 //1.获取一个状态:是否已经进入过主界面 5 // BOOL b = [[[NSUserDefaults standardUserDefaults]valueForKey:__kFirst] boolValue]; 6 7 //获取到当前的版本 8 NSString *key = (NSString *)kCFBundleVersionKey; 9 NSString *version = [NSBundle mainBundle].infoDictionary[key]; 10 11 //获取到之前的版本 12 NSString *lastVersion = [[NSUserDefaults standardUserDefaults]valueForKey:__kFirstVersion]; 13 14 //2.如果没有进入过主界面,则进入引导页 15 //如果两个版本号相同,则进入主界面,否则进入引导页 16 if (![lastVersion isEqualToString:version]) { 18 ViewController *vc = [[ViewController alloc]init]; 20 [vc setCallback:^{ 21 [self startApp]; 22 [[NSUserDefaults standardUserDefaults]setValue:version forKey:__kFirstVersion]; 23 [[NSUserDefaults standardUserDefaults]synchronize]; 24 }]; 26 self.window.rootViewController = vc; 27 } 28 //3.如果已经进入过主界面,则直接进入主界面 29 else 30 { 31 [self startApp]; 32 } 33 return YES; 34 } 35 36 37 -(void)startApp 38 { 39 self.window.rootViewController = [[UINavigationController alloc]initWithRootViewController:[RootViewController new]]; 40 }
1)对于单行文本数据的显示调用- (CGSize)sizeWithAttributes:(NSDictionary *)attrs;方法来得到文本宽度和高度。
例如:
//根据文本内容取得文本占用空间大小 CGSize textSize=[@"Hello World" sizeWithAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:15]}];
2)对于多行文本数据的显示调用- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context ;方法来得到文本宽度和高度;同时注意在此之前需要设置文本控件的numberOfLines属性为0。
//计算多行文本所占空间大小 CGSize textSize=[@"Hello WorldHello WorldHello WorldHello WorldHello WorldHello WorldHello World" boundingRectWithSize:CGSizeMake(100, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:15]} context:nil].size;
self.layer.allowsEdgeAntialiasing = YES;
解决方法有两种:
方法一:使用Enable Bitcode的第三方库
方法二:将工程中的Enable Bitcode设置为NO 如图:
打开终端(实用工具 -->终端),在终端中输入如下命令:
svn ls https://xxxxxxxx/svn/xxxxxx SVN的路径
然后直接输入 “ p ” 确认,再分别输入电脑密码、svn用户名以及密码;就可以重新连接了。
1 textField.placeholder = @"username is in here!"; 2 [textField setValue:[UIColor redColor]forKeyPath:@"_placeholderLabel.textColor"]; 3 [textField setValue:[UIFont boldSystemFontOfSize:16]forKeyPath:@"_placeholderLabel.font"];
1 - (UIViewController*)topViewController 2 { 3 return [self topViewControllerWithRootViewController:self.window.rootViewController]; 4 } 5 6 - (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController 7 { 8 if ([rootViewController isKindOfClass:[UITabBarController class]]) { 9 UITabBarController *tabBarController = (UITabBarController *)rootViewController; 10 return [self topViewControllerWithRootViewController:tabBarController.selectedViewController]; 11 } else if ([rootViewController isKindOfClass:[UINavigationController class]]) { 12 UINavigationController* navigationController = (UINavigationController*)rootViewController; 13 return [self topViewControllerWithRootViewController:navigationController.visibleViewController]; 14 } else if (rootViewController.presentedViewController) { 15 UIViewController* presentedViewController = rootViewController.presentedViewController; 16 return [self topViewControllerWithRootViewController:presentedViewController]; 17 } else { 18 return rootViewController; 19 } 20 } 21 22 //调用 23 [[self topViewController] presentViewController:[[TransViewController alloc] init] animated:YES completion:nil];
1 #define APPDELEGATE ((AppDelegate *)[UIApplication sharedApplication].delegate)
2 //用法:在AppDelegate.h中定义变量 通过 APPDELEGATE对象实现全局调用 3 4 //AppDelegate.h 代码 5 #import <UIKit/UIKit.h> 6 @interface AppDelegate : UIResponder <UIApplicationDelegate> 7 @property (strong, nonatomic) UIWindow *window; 8 @property (strong,nonatomic) NSString *systemName; 9 @end 10 11 //调用方法 (注意得引用头文件 AppDelegate.h) 12 APPDELEGATE.systemName=@"KingKong";
#import "HGProductModel.h" #import "MJExtension.h" @implementation HGProductModel //重写 replacedKeyFromPropertyName 方法将id替换为我们定义的字段名 + (NSDictionary *)replacedKeyFromPropertyName { return @{@"productID" : @"id"}; } @end
类似这种按钮:
-(void)btnClicked:(id)sender event:(id)event { NSSet *touches =[event allTouches]; UITouch *touch =[touches anyObject]; CGPoint currentTouchPosition =[touch locationInView:self.tableView]; NSIndexPath *indexPath =[self.tableView indexPathForRowAtPoint:currentTouchPosition];
UITableViewCell *cell=[self tableView:tableView cellForRowAtIndexPath:indexPath]; }
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
NSString *bottomStr=[NSString stringWithFormat:@"原价%@",model.standardPrice]; NSMutableAttributedString *attrString=[[NSMutableAttributedString alloc]initWithString:bottomStr]; [attrString addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlinePatternSolid | NSUnderlineStyleSingle] range:NSMakeRange(0, bottomStr.length)]; self.bottomLb.attributedText=attrString;
解决方案:
1.打开终端
2.cd 到警告所提示的文件夹下
3.执行命令svn rm --force 丢失文件的名称
4.回车
5. find . -type d -name .svn | xargs rm -rf //该命令为直接删除指定文件夹下所有SVN相关
6. sudo find /Users/KingKong/Desktop/Scitel_Project/iOS-BigEvent/ -name ".svn" -exec rm -r {} \;//红色字体为项目路径
1. //让当前页的所有控件从导航栏左下开始 self.edgesForExtendedLayout=UIRectEdgeNone; self.automaticallyAdjustsScrollViewInsets=YES; 2.//下方显示不全 _tableView.contentInset=UIEdgeInsetsMake(0, 0, -20, 0);
- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section { view.tintColor = HGTableViewBackColor; }
CGAffineTransform transform = CGAffineTransformMakeScale(1.0f, 5.0f); self.progressView.transform = transform;
需要导入CoreGraphics.framework包
1 NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0]; 2 UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
错误代码:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_QQApiInterface", referenced from:
objc-class-ref in AppDelegate.o
"_OBJC_CLASS_$_ShareSDK", referenced from:
objc-class-ref in AppDelegate.o
objc-class-ref in RecipeDetailViewController.o
objc-class-ref in showViewController.o
objc-class-ref in video_show.o
"_OBJC_CLASS_$_TencentOAuth", referenced from:
objc-class-ref in AppDelegate.o
"_OBJC_CLASS_$_WXApi", referenced from:
objc-class-ref in AppDelegate.o
"_OBJC_CLASS_$_WeiboApi", referenced from:
objc-class-ref in AppDelegate.o
"_OBJC_CLASS_$_YXApi", referenced from:
objc-class-ref in AppDelegate.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
原因:
Xcode升级到6.1.1或以上版本后 默认让所有App都通过64位编译器编译。原来在Xcode6.1.1以下版本的时候默认的
Architectures只有(arm7,armv7s),到6.1.1或以上版本默认就带上arm64的参数了。
方法:
1.把1.选中Targets—>Build Settings—>Combined--->Architectures。
把build active architectures only 改为 NO。
2. 把最下面的Valid Architectures中的arm64参数删掉就可以了
或者:
双击Architectures,选择other,删除$(ARCH_STANDARD),然后增加armv7和armv7s(写上:$(ARCHS_STANDARD_32_BIT))。
3.clean 再build。
设置好后效果图:
解决的办法:
在Build Settings---->Aplle LLVM7.1 - Language - Objectibe-C
---->Weak Reference In Manual Retain Release 设置为YES
即此处显示的证书
进入此目录 ~/Library/MobileDevice/Provisioning Profiles 删除对应的证书即可。
问题原因是:我用nib自定义了一个cell。作为我的tableHeaderView.当然在我执行下面的这段代码的时候,tableHeaderView
的显示没有任何问题。
headCell = [[NSBundle mainBundle] loadNibNamed:@"RRTableHeadBtnCell" owner:self options:nil][0]; self.tableView.tableHeaderView = headCell;
但是:当我有数据需要更新cell的时候,当我要执行下面的代码的时候,标题的error就出现了。而且我的tableFootView 也同时消失了。
[self.tableview reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationFade];
问题是由于将cell作为section headerView 导致的题目所述错误。
解决方案其实很简单:
self.tableView.tableHeaderView = headCell.contentView;