iOS工作笔记(十二)

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

原文地址:https://www.cnblogs.com/Apologize/p/5584890.html