我一直在努力学习iOS应用程序开发,我从这个链接的Apple官方教程开始:https://developer.apple.com/library/ios/referencelibrary/GettingStarted/RoadMapiOS/ThirdTutorial.html
这是一个3步教程。我按照每个人的说明进行操作,但在第3个教程结束时,我无法从我的应用程序获得正确的输出。教程说它结束时应该是这样的:
但我的应用看起来像这样:
我无法添加新项目。下面你可以看到我的故事板和我的所有代码。但您也可以从这里下载整个项目:Link
如果有帮助,我正在使用Xcode 5.0.2
开发OS X 10.9.2我的故事板:
XYZAddToDoItemViewController.m文件的代码:
#import "XYZAddToDoItemViewController.h"
@interface XYZAddToDoItemViewController ()
@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *doneButton;
@end
@implementation XYZAddToDoItemViewController
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if (sender != self.doneButton) return;
if (self.textField.text.length > 0) {
self.toDoItem = [[XYZToDoItem alloc] init];
self.toDoItem.itemName = self.textField.text;
self.toDoItem.completed = NO;
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
XYZAddToDoItemViewController.h文件的代码:
#import <UIKit/UIKit.h>
#import "XYZToDoItem.h"
@interface XYZAddToDoItemViewController : UIViewController
@property XYZToDoItem *toDoItem;
@end
XYZToDoItem.m文件的代码:
#import "XYZToDoItem.h"
@implementation XYZToDoItem
@end
XYZToDoItem.h文件的代码:
// This class creates and stores the data for individual list items.
#import <Foundation/Foundation.h>
@interface XYZToDoItem : NSObject
@property NSString *itemName;
@property BOOL completed;
@property (readonly) NSDate *creationDate;
@end
XYZToDoListViewController.m文件的代码:
#import "XYZToDoListViewController.h"
#import "XYZAddToDoItemViewController.h"
@interface XYZToDoListViewController ()
@property NSMutableArray *toDoItems;
@end
@implementation XYZToDoListViewController
- (void)loadInitialData {
XYZToDoItem *item1 = [[XYZToDoItem alloc] init];
item1.itemName = @"Buy milk";
[self.toDoItems addObject:item1];
XYZToDoItem *item2 = [[XYZToDoItem alloc] init];
item2.itemName = @"Buy eggs";
[self.toDoItems addObject:item2];
XYZToDoItem *item3 = [[XYZToDoItem alloc] init];
item3.itemName = @"Read a book";
[self.toDoItems addObject:item3];
}
- (IBAction)unwindToList:(UIStoryboardSegue *)segue
{
XYZAddToDoItemViewController *source = [segue sourceViewController];
XYZToDoItem *item = source.toDoItem;
if (item != nil) {
[self.toDoItems addObject:item];
[self.tableView reloadData];
}
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.toDoItems = [[NSMutableArray alloc] init];
[self loadInitialData];
// Uncomment the following line to preserve selection between presentations.
self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// it changes when i comment following line!!
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.toDoItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"ListPrototypeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
XYZToDoItem *toDoItem = [self.toDoItems objectAtIndex:indexPath.row];
cell.textLabel.text = toDoItem.itemName;
if (toDoItem.completed) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
//
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
//
//
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
//
//
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
//
//
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
//
//
#pragma mark - Navigation
// In a story board-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
//
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
XYZToDoItem *tappedItem = [self.toDoItems objectAtIndex:indexPath.row];
tappedItem.completed = !tappedItem.completed;
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
@end
XYZToDoListViewController.h文件的代码:
#import <UIKit/UIKit.h>
#import "XYZToDoItem.h"
@interface XYZToDoListViewController : UITableViewController
- (IBAction)unwindToList:(UIStoryboardSegue *)segue;
@property XYZToDoItem *toDoItem;
@end
XYZAppDelegate.m文件的代码:
#import "XYZAppDelegate.h"
@implementation XYZAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
//self.window.backgroundColor = [UIColor whiteColor];
//[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end
XYZAppDelegate.h文件的代码:
#import <UIKit/UIKit.h>
@interface XYZAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
答案 0 :(得分:1)
我认为Apple在教程中忘了一步。要添加项目,您必须将完成按钮链接到方法unwindToList
。
您只需转到故事板并按住Ctrl键并单击“完成”并将其拖动到XYZAddToDoItemViewController上的“退出”图标。菜单“ActionSegue”应与您的unwindToDoList方法一起出现。 只需将该行拖过该方法,然后释放,就完成了!
答案 1 :(得分:0)
XYZToDoListViewController.m文件的代码:似乎缺少XYZToDoItem.h的导入 - 看起来它已被添加到XYZToDoListViewController.h中。
答案 2 :(得分:0)
您没有正确使用本教程。你犯了一个我也犯过的错误。
错误:
您已在条形项目的“标题”中使用了+
符号。
解决方案: 选择Add From Identifier的下拉列表,然后再次重新学习该教程。
它应该有用!