做OC编程基础练习:通讯录,在新建联系人时为了避免在没有保存就返回上一页,所以设计一个警告控件,但是却无法触发?错误提示是:
Warning: Attempt to present <UIAlertController: 0x7fae087eac40> on <NewPersonItemViewController: 0x7fae08569b90> whose view is not in the window hierarchy!
新建联系人类:
.h
请#import <UIKit/UIKit.h>
//创建一个协议注意:在该类里写这个协议并不意味着该类继承了协议
@protocol PassValue
-(void)addName:(NSString*)name andAddTel:(NSString*)tel;
@end
@interface NewPersonItemViewController : UIViewController
{
//创建一个布尔标记以确定是否已存入数据
BOOL flag;
}
@property(strong,nonatomic)UITextField *name;
@property(strong,nonatomic)UITextField *tel;
//这里这个属性继承了该协议
@property(weak,nonatomic)id<PassValue> delegate;
@end
.m:问题出现在:-(void)viewWillDisappear:(BOOL)animated方法执行上
#import "NewPersonItemViewController.h"
@interface NewPersonItemViewController ()
@end
@implementation NewPersonItemViewController
@synthesize name,tel;
-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
//标记一个标题
self.title=@"添加新联系人";
self.view.backgroundColor=[UIColor whiteColor];
//在导航栏上创建一个完成按钮,用于确定编辑结束
//注意:只能先创建一个特殊的按钮,然后赋值给导航视图控制器的右按钮;
UIBarButtonItem *BarButton=[[UIBarButtonItem alloc]initWithTitle:@"完成" style:UIBarButtonItemStyleDone target:self action:@selector(DoneTap:)];
self.navigationItem.rightBarButtonItem=BarButton;
//创建两个文本框:分别是姓名和电话 中间加一条线
name=[[UITextField alloc]initWithFrame:CGRectMake(10, 74, 300, 40)];
name.placeholder=@"姓名";
name.backgroundColor=[UIColor greenColor];
[self.view addSubview:name];
//加一条分割线
UIView * line1=[[UIView alloc]initWithFrame:CGRectMake(0, 124, 320, 2)];
line1.backgroundColor=[UIColor blackColor];
[self.view addSubview:line1];
//电话文本框
tel=[[UITextField alloc]initWithFrame:CGRectMake(10, 134, 300, 40)];
tel.placeholder=@"电话";
tel.backgroundColor=[UIColor greenColor];
[self.view addSubview:tel];
//加一条分割线
UIView * line2=[[UIView alloc]initWithFrame:CGRectMake(0, 184, 320, 2)];
line2.backgroundColor=[UIColor blackColor];
[self.view addSubview:line2];
//设计:当使用对应文本框时的return时关闭键盘:该方法并不需要使用resignFirstResponder
[name addTarget:self action:@selector(onExit:) forControlEvents:UIControlEventEditingDidEndOnExit];
[tel addTarget:self action:@selector(onExit:) forControlEvents:UIControlEventEditingDidEndOnExit];
//使两个文本框输入时,关闭自动首字母大写
name.autocapitalizationType=UITextAutocapitalizationTypeNone;
tel.autocapitalizationType=UITextAutocapitalizationTypeNone;
NSLog(@"1");
}
return self;
}
- (void)viewDidLoad {
//[super viewDidLoad];
NSLog(@"2");
}
//当视图即将载入时将flag设置为假;
-(void)viewWillAppear:(BOOL)animated{
flag=NO;
NSLog(@"3");
}
-(void)viewDidAppear:(BOOL)animated{
NSLog(@"4");
}
***//问题貌似出在这里:***
//当时图即将消失时也将flag设置为假
-(void)viewWillDisappear:(BOOL)animated{
//因为点击完成时
if(!flag){
// if (name.text!=nil||tel.text!=nil ) {
//当填写了内容时,退出当前视图时出现警告提示
UIAlertController * a=[UIAlertController alertControllerWithTitle:@"注意了!!" message:@"大爷的你还没保存!" preferredStyle: UIAlertControllerStyleActionSheet];
UIAlertAction *ac1=[UIAlertAction actionWithTitle:@"你知道到了么?" style:UIAlertActionStyleDefault handler:nil];
[a addAction:ac1];
[self presentViewController:a animated:YES completion:nil];
//}
NSLog(@"5");
return ;
}
}
//并不需要什么语句触摸return后就可以使键盘退出
-(void)onExit:(UITextField*)sender{
NSLog(@"6");
}
/*
当点击“完成”时:
1.验证数据;
*/
-(void)DoneTap:(UIBarButtonItem *)sender{
//获得文本框中的文本内容
NSString *strName=name.text;
NSString *strTel=tel.text;
//剔除文本两端空格
//从NSCharacterSet的集合中得到whitespaceCharacterSet;
strName=[strName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
strTel=[strTel stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
//判断文本框内是为空字符串
// strName==nil
if ([strName isEqualToString:@""]) {
//使用警报
UIAlertController * alert=[UIAlertController alertControllerWithTitle:@"你大爷的请注意!" message:@"你得整点内容啊!" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction * alertAction=[UIAlertAction actionWithTitle:@"你知道了么?" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:alertAction];
[self presentViewController:alert animated:YES completion:nil];
//为了使程序更加人性化,此时还应该将清空当前字符串,然后所的焦点(就是将光标自动点入当前文本框内)
//注意:这里包括你输入的空格,将光标指向最左端
name.text=@"";
[name becomeFirstResponder];
//因为这里如果是空字符串,就不用验证下一个,需要显示这里的警报,并退出
return;
}
if ([strTel isEqualToString:@""]) {
UIAlertController * alert=[UIAlertController alertControllerWithTitle:@"你娘的请注意" message:@"你得整点内容啊!" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction * alertAction1=[UIAlertAction actionWithTitle:@"你晓得了么?" style: UIAlertActionStyleDefault handler:nil];
[alert addAction:alertAction1];
[self presentViewController:alert animated:YES completion:nil];
//为了使程序更加人性化,此时还应该将清空当前字符串,然后所的焦点(就是将光标自动点入当前文本框内)
//注意:这里包括你输入的空格,将光标指向最左端
tel.text=@"";
[tel becomeFirstResponder];
//因为这里如果是空字符串,就不用验证下一个,需要显示这里的警报,并退出
return;
}
//执行协议方法:存入数据:由于将代理指向RootTableViewController类的对象,在这里发送消息
//就等于在RootTableViewController发送消息
[self.delegate addName:strName andAddTel:strTel];
//存入数据应该flag设置为真
flag=YES;
//存入数据后应该返回至上一层页面(实际上是退回根视图对象上):注意要使用导航的栈退出的方法
[self.navigationController popViewControllerAnimated:YES];
NSLog(@"7");
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
补充表格式图控制器代码(貌似没有出错)
.h:
请
#import "WKPerson.h"
#import <UIKit/UIKit.h>
#import "NewPersonItemViewController.h"
@interface RootTableViewController : UITableViewController<PassValue>
@property(strong,nonatomic)NSMutableArray * persons;
@end输入代码
.m:
@interface RootTableViewController ()
@end
@implementation RootTableViewController
-(instancetype)initWithStyle:(UITableViewStyle)style{
self=[super initWithStyle:style];
if (self) {
//在这里可以设置导航栏的颜色和样式
[[UINavigationBar appearance] setBarTintColor:[UIColor blueColor]];
//设置导航栏上的按钮的颜色;
[[UINavigationBar appearance] setTintColor:[UIColor redColor]];
//当使用导航视图时这里可以为导航视图设置标题
self.title=@"通讯录";
//为导航栏设计一个“+”按钮
UIBarButtonItem * BarButtonItem=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addTap:)];
//将设计的按钮指向导航栏的右按钮上;
self.navigationItem.rightBarButtonItem=BarButtonItem;
}
return self;
}
-(void)addTap:(UIBarButtonItem *)sender{
//使用导航栏的推栈的方式,展示“添加联系人”的页面
NewPersonItemViewController * new=[[NewPersonItemViewController alloc]init];
//将新增联系人视图的代理指向当前类的对象
new.delegate=self;
//注意:因为该视图是导航视图的根视图,且视图控制器是本身就含有导航视图控制器的属性
//所以,这里必须使用当前类中的导航视图属性,利用推栈的方式加入新视图
[self.navigationController pushViewController:new animated:YES];
}
//实现协议
-(void)addName:(NSString )name andAddTel:(NSString )tel{
//因为有两个参数所以,最好将这两个参数存入一个类中,再将该类的对象存入一个数组
//注意数据添加了就应该将视图重载数据,以此让数据和视图同步
WKPerson *p=[[WKPerson alloc]init];
p.name=name;
p.tel=tel;
//哪里增修改了数据哪里重载数据
[self.persons addObject:p];
[self.tableView reloadData];
}
(void)viewDidLoad {
[super viewDidLoad];
self.persons=[[NSMutableArray alloc]initWithCapacity:100];
}
(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.persons.count;
}
(UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * cellId=@"A";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId ];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];
}
WKPerson *p=self.persons[indexPath.row];
cell.textLabel.text=p.name;
cell.detailTextLabel.text=p.tel;
return cell;
}
在willdisapper里 self 将要销毁,所以你不能 present,如果你用的是导航的话,建议自定义返回按钮(leftButtonItem),在返回按钮的方法里,进行判断是弹出 alartView还是执行返回 效果