1.从ControllerA跳往照相UIImagePickerController,只能用presentViewController形式,因为定义UIImagePickerController时,
UIImagePickerController *pickerController = [[UIImagePickerController alloc]init];
pickerController.allowsEditing = NO;
pickerController.delegate = self;
pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
设置delegate时,若只引入UIImagePickerControllerDelegate,那么会报以下警告:
Assigning to ‘id<UINavigationControllerDelegate,UIImagePickerControllerDelegate>’ from incompatible type ‘AddSightingViewController *const __strong’
解决方法是再添加UINavigationControllerDelegate。如下
@interface ControllerA()<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
@end
所以当跳转界面时用
[self.navigationController pushViewController:pickerController animated:YES];
会报Pushing a navigation controller is not supported错误
引以为戒
2.解决A valid provisioning profile for this executable was not found 问题
当导入签名和证书后,真机调试仍出现这种问题,那么可以按照以下步骤排查
①先检查provisioning profile是否导入成功
我用的Xcode版本是7.3.1,在Window——>Devices——>选中运行的真机——>provisioning profiles查看
②检查 Project 和 Target 中的 Code Signing Identity 是否设置一样,必须一样
3.当往NSArray中存入基本数据类型时,可以用NSNumber,也可以用简写
//NSNumber形式
_signTypesArr = [NSArray arrayWithObjects:[NSNumber numberWithInteger:3],[NSNumber numberWithInteger:2], nil];
//简写形式
_signTypesArr = [NSArray arrayWithObjects:@(2),@(2),@(2),@(1),@(3),@(3),@(3), nil];
但从数组中往外读取时,下面这种写法虽然不报错,但取的值不对,会取到意想不到的值
NSInteger typeDef = self.signTypesArr[i];
正确的是
NSInteger typeDef = [self.signTypesArr[i] integerValue];
4.NSError转换为NSString
NSError *error= [NSError errorWithDomain:@"" code:0 userInfo:errInfo];
NSString *errorStr = [error localizedDescription];
5.在有tabbarcontroller的程序中,手动触发跳往指定页面。
虽然tabbarcontroller的代理方法中,有
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {}
这样的方法,但都不能手动调用。这些是由系统调用。
如若在选项卡A界面有个按钮,点击想跳往选项卡B界面。此时不能用用普通的push和present方法,得用类似于
self.tabBarController.selectedIndex = 0;
这样的写法。这也是手动触发跳往指定页面的方法。
若有这样的场景,如在如下的仿微信tabbar中,
点击前三个tabbar,都能展示相应的页面,在点击第四个tabbar“我”时,若没有登录就需要弹出登录界面,关闭登录界面就跳回到之前点击的选项卡。如在没登录的情况下,先点第二个“通讯录”,再点第四个“我”,在取消登录,那么此时界面应跳往第二个的“通讯录”,而不是其它界面。
刚开始的想法是记录点击位置,再传回到第四个tabbar中进行处理,但那样比较麻烦,现在有个简单方法。
在tabbarcontroller中,
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{
NSInteger numIndex = [tabBar.items indexOfObject:item];
NSNumber *num = [NSNumber numberWithInteger:numIndex];
if (numIndex < 3) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"lastSelectedIndex" object:@{@"numIndex":num}];
}
}
将选择的下标通过通知传出去。然后在第四个“我”中controller的init中接收通知。
// 记录点击该选项卡之前最后选择的下标
@property(nonatomic,assign) NSInteger numIndex;
-(instancetype)init{
__weak typeof(self) weakSelf = self;
[[NSNotificationCenter defaultCenter] addObserverForName:@"lastSelectedIndex" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
NSNumber *temp = note.object[@"numIndex"];
weakSelf.numIndex = [temp integerValue];
}];
return self;
}
然后在点击关闭登录界面的方法中执行
-(void)clickTheCloseBtn{
self.tabBarController.selectedIndex = self.numIndex;
}
即可实现该需求。效果如下
6.当controller的view添加UITapGestureRecognizer后,tableview点击事件不响应的处理
在controller中,有
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapWholeView)];
tap.delegate = self;
[self.view addGestureRecognizer:tap];
然后就发现,didSelectRowAtIndexPath方法就不执行。因为手势覆盖了cell的点击方法,此时应
实现UIGestureRecognizerDelegate的代理方法,在手势点击tableview时不处理
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
if ([touch.view isDescendantOfView:_historyTableView]) {
return NO;
}
return YES;
}
7.改变pushViewController的push方向
可以实现类似present的效果。如
SearchGoodsViewController *search = [[SearchGoodsViewController alloc] init];
[self presentViewController:search animated:YES completion:nil];
效果是从下到上present
若用push,则可以用动画来解决
CATransition* transition = [CATransition animation];
transition.type = kCATransitionMoveIn;//可更改为其他方式
transition.subtype = kCATransitionFromTop;//可更改为其他方式
[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController pushViewController:search animated:YES];
8.uitableview,uicollectionview,uiscrollview回到顶部
UITableView, UICollectionView都继承自UIScrollView,所以可以使用UIScrollView的方法,设置显示内容的偏移量。有两种写法
[_myTableView setContentOffset:CGPointZero animated:YES];
[_myTableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
若想让tableview,collectionview随着cell的点击而移动,而不是手动移动,那么可以在点击方法里设置
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
[_collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
********************************** 2016-07-15更新 **********************************
上述被删除的部分是有问题的,假如animated为YES的话,有时候tableview不会返回到正确的位置。因此需要设置animated为NO。更准确的写法为
[_myTableView setContentOffset:CGPointZero animated:NO];
[_myTableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
关于这部分的讨论地址
http://stackoverflow.com/questions/724892/uitableview-scroll-to-the-top