1.强制应用为横屏的方法。
在view contronller中的实现
(NSUInteger)supportedInterfaceOrientations {
//返回支持的方向为横屏
return UIInterfaceOrientationMaskLandscape;
}(BOOL) shouldAutorotate {
return YES;
}
2.在storyboard中以横屏方式编辑的方法。
选中某个View Contronller在右侧边栏中设置Orientation选项,默认为Inferred,设为Landscape。
3.摄像头预览图层显示的图像方向设置的方法。
获取AVCaptureVideoPreviewLayer的成员变量connection,调用它的setVideoOrientation函数。
4.设计单实例为什么要重写allocWithZone。
实践证明,使用alloc方法初始化一个类的实例的时候,默认是调用了 allocWithZone 的方法。于是覆盖allocWithZone方法的原因已经很明显了:为了保持单例类实例的唯一性,需要覆盖所有会生成新的实例的方法,如果有人初始化这个单例类的时候不走[[Class alloc] init] ,而是直接 allocWithZone, 那么这个单例就不再是单例了,所以必须把这个方法也堵上。allocWithZone这个方法之所以存在,是历史遗留原因。它的参数memory zone已经被弃用了,只是历史原因才保留这个接口。
5.计算GPS坐标,两点间相对方向。
IPHONE实景导航开发总结(二):
http://chenweihuacwh.iteye.com/blog/549381
http://bbs.9ria.com/thread-212032-1-1.html
6.有无状态栏时的屏幕大小。
//获取没有状态栏的屏幕大小
CGRect appRect = [ UIScreen mainScreen ].applicationFrame;
//获取屏幕大小
CGRect rx = [UIScreen mainScreen].bounds;
//获取状态栏的大小
CGRect rect = [[UIApplication sharedApplication] statusBarFrame];
注意:调试发现横屏的时候,获取的矩形坐标还是和竖屏的坐标系一样,但是View的坐标是横平的坐标系。
7.真机调试介绍。
http://my.oschina.net/joanfen/blog/167730
8.找不到libxml中的头文件时的处理方法。
在工程Build Settings的设置中,的Search Paths项中的Header Search Paths中添加如下路径:
/usr/include/libxml2
在用xmpp实现推送时,添加完xmpp代码后还需要在target属性设置中的Build Phases中的Link Binary With Libraries中添加这两个库:libresolv.dylib和libxml2.dylib
9.启动图片不能显示的问题。
iPhone只能添加竖屏的启动图片,所以在target的属性设置中的General中的Deployment Info中的Device Orientation属性必须有protrait这项。
xcode也有点bug,在不选protrait后运行,再次选择后再运行还是不能显示启动图片,要单独选这项运行后才可以显示。
10.状态栏的显示和隐藏。
当info.plist中的key值View controller-based status bar appearance的值为NO时有效。
在application:didFinishLaunchingWithOptions:中:
[application setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
11.ios发布证书申请过程。
http://my.oschina.net/joanfen/blog/133624
12.判断实例是不是某个类的。例子,判断reachability的实例。
- (void) reachabilityChanged:(NSNotification )note
{
Reachability curReach = [note object];
NSParameterAssert([curReach isKindOfClass:[Reachability class]]);
[self updateInterfaceWithReachability:curReach];
}
NSParameterAssert是debug版本才会运行的断言。release版本不会运行。
13.检测网络连结状态的方法。
http://www.cnblogs.com/mrhgw/archive/2012/08/01/2617760.html
使用之前请从Apple网站下载示例:点此下载
然后将Reachability.h 和 Reachability.m 加到自己的项目中,并引用 SystemConfiguration.framework,就可以使用了。
14.上传应用的二进制文件到apple。工程的info.plist设置
首要做的是在Target属性Build Settings中的Code Signing把Identity都设置为 IOS Distribution。还有菜单打开product->把Run和Archive的Build Configuration设置为Release。
可以有两种方法,一种是用菜单中Xcode->Open Developer Tool->Application loader,来上传.app的zip包。zip包生成方法:Build Release版的应用后,在xcode的Products文件下右键点应用的.app文件Show in Finder,把到拷贝出来打包成zip。就可以用Application loader上传了。
我用的是第二种方法,生成Archive,菜单Product->Archive。之后会自动打开Organizer,也可以通过菜单Window->Organizer打开。在Organizer中选Archive页面,在这里可以看到生成的Archive可以进行Validate和Distribute的操作,我在Validate时出现了问题,提示1.找不到nib file 2.info.plist文件中不能同时有nib file 和stroyboard file两个配置。我用的是stroybord所以删除nib file那一项就可以了。在哪删呢,原来info.plist配置文件指的就是target属性中info那页中的第一项Custom ios Target Properies。Validate(验证)通过后,就可以发布了Distribute。
15.自定义导航栏后退按钮的问题。
在有导航栏的controler中可以用self.navigationItem 的方法获取导航栏,navigationItem中的leftBarButtonItem和rightBarButtonItem是本级页面上的BarButtonItem,而backBarButtonItem是下一级页面上的BarButtonItem。并且这些都是custom的,就是是自定义的,所以默认情况下都是nil。要新建一个UIBarButtonItem 赋值给它。示例如下:
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@"back" style:UIBarButtonItemStyleBordered target:self action:nil];
[self.navigationItem setLeftBarButtonItem:backItem];
16.实现以下方法时要注意要调用[super viewWillAppear:animated]; 不然会出现一些系统方法无效的问题,比如这个设置无效:self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to preserve selection between presentations.
//self.clearsSelectionOnViewWillAppear = NO;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
简单来说,就是不调用父类的这个函数的话,界面就不会刷新了。
17.Navigation的一些用法。
http://ios.9tech.cn/news/2013/1104/38423.html
UINavigationController是UIViewController的子类,同时因为其他的view controller是嵌入在navigation controller中的,所以UIViewController中有navigationController 和navigationItem 这两个属性。而导航条属性navigationBar 则是在UINavigationController中的属性。在view controller中可以这样设置导航条的颜色:[self.navigationController.navigationBar setBarTintColor:[UIColor redColor]];也可以在AppDelegate.m文件中的方法didFinishLaunchingWithOptions:里面添加如下代码来修改颜色:
1
[[UINavigationBar appearance] setBarTintColor:[UIColor yellowColor]];
这个是设置所有的导航条的颜色。
导航条上返回按钮的颜色是设置UINavigationBar中的属性,[self.navigationController.navigationBar setTintColor:[UIColor lightGrayColor]];
以下是查看有什么字体和设置标题样式的代码。大部分是英文字体,只对英文有效。
//查找有什么字体
for(NSString *familyName in [UIFont familyNames])
{
NSLog(@"familyName = %@", familyName);
for(NSString *fontName in [UIFont fontNamesForFamilyName:familyName])
{
NSLog(@"\tfontName = %@", fontName);
}
}
{//设置所有导航条的标题的字体颜色,字体阴影,字体大小。
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8];
shadow.shadowOffset = CGSizeMake(0, 1);
[[UINavigationBar appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:245.0/255.0 green:245.0/255.0 blue:245.0/255.0 alpha:1.0], NSForegroundColorAttributeName, shadow, NSShadowAttributeName,[UIFont fontWithName:@"HelveticaNeue-CondensedBlack" size:18.0], NSFontAttributeName, nil]];
}
18.状态栏样式的设置。
可以设置为黑色或是白色也可以设置为隐藏。有两种方法来设置和info.plist中的key值View controller-based status bar appearance有关,这个值默认为YES,这时在每个view control中重载方法:
-(UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
第一个是设置黑白,但貌似没有效果,有可能是苹果的BUG吧。当这个值为NO时可以如下设置:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
19.ios开发之MPMoviePlayerController播放本地及网络视频方法
01
NSString *path=[[NSBundle mainBundle] pathForResource:@"stream0" ofType:@"mp4"];
02
NSURL *url=[[NSURL alloc] initFileURLWithPath:path];
03
self.rootPlayer=[[MPMoviePlayerController alloc] initWithContentURL:url];
04
self.rootPlayer.view.frame=CGRectMake(0, 0, 200, 200);
05
self.rootPlayer.movieSourceType=MPMovieSourceTypeFile;//本地文件播放要设置视频资源为文件类型资源,若设置为stream 则会错误
06
[self.rootPlayer prepareToPlay];
07
**if**(self.rootPlayer)
08
{
09
[self.rootPlayer play];
10
}
11
[self.view addSubview:self.rootPlayer.view];
1
self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:@"http://125.76.230.133/cast/mp4/50-screen.mp4"]];
2
self.moviePlayer.movieSourceType=MPMovieSourceTypeStreaming;//网络文件要设置为stream
3
[self.moviePlayer play];
4
self.moviePlayer.view.frame= CGRectMake(0, 0, 300, 300);
5
[self.view addSubview:self.moviePlayer.view];
PS:播放器的对象必须是self的一个属性 ,否则播放5秒左右就会中断。
20.iOS: FFmpeg编译和使用问题总结
http://www.cnblogs.com/smileEvday/p/ffmpeg.html
21.用c分配比较大的内存时的注意事项。
在栈上分配内存有大小限制,比如char rgbBuffer[230400]; 如果超过这个大小很多的话,就会挂掉,有内存访问错误,一般挂在函数开头,可能是函数开始分配内存的时候挂的。所以要在堆上动态分配内存像这样:
const int maxImageSize = 192010803/2;
unsigned char rgbBuffer = malloc(maxImageSize2);
……
free(rgbBuffer);
22.在工程中部分文件使用或不使用ARC的方法。
点击项目导航文件****--> ****选中****Targets--> ****选择**** Build Phases --> ****展开****Compile Sources ****这个时候,我们看到第二列的名称为:****Compiler Flags ****双击你所要使用****ARC****的文件,并输入**** ****-fobjc-arc****,那么现在这个文件就可以在编译时使用ARC机制进行编译了。同上,如果想让使用****ARC****机制的代码不使用****ARC****机制,只需要输入**** ****-fno-objc-arc
23.UITableViewCell中的UIImageView的大小位置变化问题。
在table view controller中设置了UIImageView的image([cell.imageView setImage:[UIImage imageNamed:@"camera_online"]];)后,UIImageView的大小和位置都发生了变化,和原来storyboard中的不一样了。旋转屏幕之后又变为storyboard中的样子。
解决方法是在UITableViewCell的子类中重写方法:
-(void)layoutSubviews
{
//[super layoutSubviews];
//[self.imageView setFrame:CGRectMake(50, 10,29, 29)];
//self.imageView.contentMode = UIViewContentModeScaleAspectFit;
}
1.像这样重写什么都不做就会保持在storybord中的样子。2.如果想在这里设置大小位置可以像第二句那样,setFrame,且不写第一句。3.奇怪的是如果写了第一句调用父类的方法的话,问题依旧,所以不能调用父类的layoutSubviews。
以上的方法也不太对,如果不调父类的函数,table view的分割线和箭头就会不见了。更好的解决方法是在调用父类的方法前,设置image view的frame和storyboard中的大小位置一样,如下:
[self.imageView setFrame:CGRectMake(38, 5,53, 53)];
[super layoutSubviews];
这样就可以了,奇怪的是在测试中发现这个frame的大小和位置只要随便的一个值就可以不用和storybord中的一样也可以。结果显示的是storyboard中的大小位置,不管怎么样问题解决了。
23.1.后来的补充说明。可能和view的生命周期中何时设置storyboard中的view的位置大小有关。
http://mikixiyou.iteye.com/blog/1774351
视图控制器类一共有四个方法可以重写来实现视图加载和展现,分别是ViewWillAppear:,viewDidAppear:,viewDidLoad:,viewDidLayoutSubviews。其中viewDidLayoutSubviews方法是在iOS5.0系统中才开始提供的。
在viewDidAppear:和viewDidLayoutSubviews中,得到的frame的值就是storyboard中设置的值了,所以设置storyboard中的值是在viewDidLoad和ViewWillAppear之后,viewDidAppear和viewDidLayoutSubviews之前,所以要自定义storyboard中的view的大小和位置要在viewDidAppear和viewDidLayoutSubviews中设置,如果在之前的两个方法中设置的话会被storyboard中的值重置,结束无效。
24.屏幕旋转问题。
http://blog.csdn.net/jaywon/article/details/8208991
一般大家都知道是在view controller中重写以下两个方法:
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
但系统调用的是根视图控制器(rootViewControler)里的这两个方法。当view controller嵌入在navigation controller中的时候,self.window.rootViewController = navCtrl; 根视图控制器就是navigation controller,所以我们要写一个它的子类,在其中重写这两个方法。实现时可以统一控制所有视图的旋转,也可以让子视图自己控制,像这样:
//让子视图来决定是否旋转
- (BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
//让子视图来决定旋转方向 - (NSUInteger)supportedInterfaceOrientations
{
return self.topViewController.supportedInterfaceOrientations;
}
25.主动要求屏幕旋转问题。
网上提供了两种方法:
1.设置设备的方向:(performSelector:withObject: 和直接执行的区别是这个是运时的,编译时不会检查)
//转为横屏
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
[[UIDevice currentDevice] performSelector:@selector(setOrientation:)
withObject:(id)UIInterfaceOrientationLandscapeRight];
}
2.旋转状态栏等。
//设置状态栏旋转
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeRight animated:YES];
CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;
//设置旋转动画
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:duration];
//设置导航栏旋转
self.navigationController.navigationBar.frame = CGRectMake(-204, 224, 480, 32);
self.navigationController.navigationBar.transform = CGAffineTransformMakeRotation(M_PI1.5);
//设置视图旋转
self.view.bounds = CGRectMake(0, -54, self.view.frame.size.width, self.view.frame.size.height);
self.view.transform = CGAffineTransformMakeRotation(M_PI1.5);
[UIView commitAnimations];
我用的是第1种,但有错误提示,在ARC的情况下不能把UIInterfaceOrientationLandscapeRight 这个参数(其实是long类型)转为id(对像类型)。我用的解决方法是把这个代码独立写在一个文件中,做为一个静态方法。在要用的地方调用。这个文件可以设置为不用ARC的方式来编译就可以通过了。
26.ios6.0之后的tableview下拉刷新。
原来试着在storyboard中添加,把table view control的refreshing属性改为enabled,并把出现的refresh control连接到代码中。但没有效果。
所以用以下代码添加refresh control
- (void)viewDidLoad
{
……
//添加下拉刷新
self.refreshControl = [[UIRefreshControl alloc]init];
//self.refreshControl.tintColor = [UIColor blueColor];
self.refreshControl.attributedTitle = [[NSAttributedString alloc]initWithString:@"下拉刷新"];
[self.refreshControl addTarget:self action:@selector(RefreshViewControlEventValueChanged) forControlEvents:UIControlEventValueChanged];
}
//下拉刷新响应
-(void)RefreshViewControlEventValueChanged
{
//开始下拉刷新的加载动画
[self.refreshControl beginRefreshing];
//网络请求列表数据
EyesHttpRequest *httpRequest = [EyesHttpRequest sharedHttpRequestInstance];
httpRequest.delegate = self;
[httpRequest sendRequestGetCameraList];
}
//获取到列表数据
- (void)gotCameraList:(NSString*)strXml
{
……
//更新tableview中的数据
[self.tableView reloadData];
//停止下拉刷新的加载动画
if(self.refreshControl.refreshing == YES)
[self.refreshControl endRefreshing];
}
27.让View响应点击。
如果想让storyboard上的view响应点击等事件,可以把view设置为UIControl类,它是view的子类,可以响应控件的各种事件。
比如,可以在事件响应中做关闭输入法的操作。
- (IBAction)touchDown:(UIControl *)sender
{
// 发送resignFirstResponder.用来收起输入法
[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
}
要响应输入法的return按钮,是通过添加textField的Did End OnExti响应来实现的,如下:
//响应输入法的return按钮 - (IBAction)accountDidEndOnExit:(UITextField *)sender
{
//移到下一个输入框进行输入
[self.textFieldPassword becomeFirstResponder];
}
//响应输入法的return按钮
- (IBAction)passwordDidEndOnExit:(UITextField *)sender
{
//关闭输入法
[sender resignFirstResponder];
//执行登录按钮
[self.buttonLogin sendActionsForControlEvents:UIControlEventTouchUpInside];
}
28.进入设置界面。
if (UIApplicationOpenSettingsURLString != NULL) {
NSURL *appSettings = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication] openURL:appSettings];
}