0

I am very new to IOS programming and I started with a list application. I used the default Master Detail View template in Xcode, and I am trying to edit that to do a to do list or grocery list.

The idea is to be able to tap the + button on the MasterViewController and it seque to the Add screen, input the information there, tap the Save button and it go back to the MasterViewController with the information input in the add screen populating the Table in the MasterViewController. Then if you tap on the table cell that has been added it will seque to the detailViewController and just show the information.

I have spent a lot of hours searching and reading and I am just not getting what to do. I thought this would be an easy application, but I am getting beat! Any tips or help would be appreciated!

I have three view controllers and an Item Class:

the Master controller that is my table of items;

the detail View controller that will just show details of the table row;

and an add view controller, which I am trying to put all the information in to save to my master controller table.

The seque that goes to my Add view controller is called add

The seque that goes to my Detail view controller is called showDetail

I then have the MasterViewController.h :

#import <UIKit/UIKit.h>
#import "Items.h"
#import "AddViewController.h"
@interface MasterViewController : UITableViewController
@property NSMutableArray *items;
@end

MasterViewController.m

#import "MasterViewController.h"
#import "DetailViewController.h"
#import "Items.h"
@interface MasterViewController ()
@property NSMutableArray *itemsarray;
//@property NSMutableArray *stores;
//@property NSMutableArray *prices;
@end

@implementation MasterViewController
- (void)awakeFromNib {
    [super awakeFromNib];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.navigationItem.leftBarButtonItem = self.editButtonItem;//this is the edit button on the             master controller, top left
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
#pragma mark - Segues
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([[segue identifier] isEqualToString:@"add"]) {

    }
    if ([segue.identifier isEqualToString:@"showDetail"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        DetailViewController *destViewController = segue.destinationViewController;
        destViewController.item = [_itemsarray objectAtIndex:indexPath.row];
        destViewController.quantity = [_itemsarray objectAtIndex:indexPath.row];
        destViewController.store = [_itemsarray objectAtIndex:indexPath.row];
    }
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.itemsarray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"         forIndexPath:indexPath];
    Items  *toDo = _itemsarray[indexPath.row];
    cell.textLabel.text = toDo.name;
    return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:    (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [self.itemsarray removeObjectAtIndex:indexPath.row];
        [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.
    }
}
@end

DetailViewController.h

#import <UIKit/UIKit.h>
#include "Items.h"
@interface DetailViewController : UIViewController
@property (strong, nonatomic) id detailItem;
@property (weak, nonatomic) IBOutlet UILabel *item;
@property (weak, nonatomic) IBOutlet UILabel *quantity;
@property (weak, nonatomic) IBOutlet UILabel *store;
@end

DetailViewController.h

#import "DetailViewController.h"
#import "Items.h"
@interface DetailViewController ()
@end
@implementation DetailViewController
#pragma mark - Managing the detail item
- (void)setDetailItem:(id)newDetailItem {
    if (_detailItem != newDetailItem) {
        _detailItem = newDetailItem;
        [self configureView];
    }
}
- (void)configureView {
    // Update the user interface for the detail item.
    if (self.detailItem) {
        //this is what the text box for name of item will show. it updates
        self.item.text= [self.detailItem name] ;
        //self.quantity.text= [self.detailItem quantity] ;
       //self.store.text= [self.detailItem store] ;
    }
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self configureView];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

AddViewController.h

#import <UIKit/UIKit.h>
#include "Items.h"
#import "MasterViewController.h"
@interface AddViewController : UIViewController
@property (strong, nonatomic) id detailItem;
@property (weak, nonatomic) IBOutlet UITextField *item_text_box;
@property (weak, nonatomic) IBOutlet UITextField *quantity_text_box;
@property (weak, nonatomic) IBOutlet UITextField *store_text_box;
@end

AddViewController.m - This is where I am not sure what to do. I am using the save button to call the insertNewObject function, which is where I don't know how to send this information back to the MasterView Controller (at least this is where I think I have the problem, Im very new, so not sure)

#import "AddViewController.h"
#import "MasterViewController.h"
@interface AddViewController ()
@end
@implementation AddViewController
- (void)viewDidLoad {
    UIBarButtonItem *saveButton = [[UIBarButtonItem alloc]     initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(insertNewObject:)];
    //this is the add button at the top right of master controller
    self.navigationItem.rightBarButtonItem = saveButton;   
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (void)insertNewObject:(id)sender {
    //this is what happens when we press our save button
    //this is what happens when the add button is pushed
    if (!self.itemsarray) {        
        self.itemsarray = [[NSMutableArray alloc] init];
    }
    [self.itemsarray insertObject:[NSDate date] atIndex:0];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath]     withRowAnimation:UITableViewRowAnimationAutomatic];
}
#pragma mark - Navigation
// In a storyboard-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.
}
@end

Items.h

#import <Foundation/Foundation.h>
@interface Items : NSObject
@property NSString *name;
@property NSString *store;
@property NSString *section;
@property float price;
+ (Items *)createItemWithName:(NSString *)name andPrice:(float)price andStore: (NSString *)store     andSection: (NSString*)section;
@end

Items.m

#import "Items.h"
@implementation Items
@synthesize name = _name;
@synthesize store = _store;
@synthesize price = _price;
@synthesize section = _section;
+ (Items *)createItemWithName:(NSString *)name andPrice:(float)price andStore:(NSString *)store     andSection:(NSString*)section{
    // Initialize Item
    Items *item = [[Items alloc] init];
    // Configure Item
    [item setName:name];
    [item setPrice:price];
    [item setStore:store];
    [item setStore:section];
    return item;
}
@end

This is not homework, I have an app idea and wanted to get some of the basics - this app will resemble a part of what I want to do. Thanks!

user3746000
  • 15
  • 1
  • 7

2 Answers2

1

I suggest creating a class that will act as your data model instead of juggling data in your controller properties. One way of doing this is to create a singleton object and have the controllers talk to it when they want to add or retrieve items.

Using this strategy, a showDetail segue would only need to tell the data model which item number had been selected and the detail controller would call a selectedItem (or some name) method to retrieve it.

Similarly, the add controller would just update the data model and the master controller would get the new information by referencing the model inside its table delegate/datasource methods.

There are ways to do what you're trying to do by using delegates or notifications, but I think having a class/object that's responsible for the application's data is easier to understand and easier to work with when the app becomes more complex.

Phillip Mills
  • 30,888
  • 4
  • 42
  • 57
0

You can use any one of the following methods

  1. Delegation

  2. Blocks

  3. Notification

    Since you are new to iOS,i suggest you to go with delegation. It's easy and simple


Please go though following links
Using Delegation to Communicate With Other View Controllers
Simple Stackoverflow answer

Community
  • 1
  • 1
Deekshith Bellare
  • 725
  • 2
  • 6
  • 19