unrecognized selector at popover segue - ios

I'm using this code in my app to pass data with the corresponding seque:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"readMoreDetail"]) {
MoreViewController *destinationViewController = segue.destinationViewController;
destinationViewController.openSubject = [self.detailItem description];
} else if ([segue.identifier isEqualToString:#"notesSegue"]) {
NSLog(#"segue");
NotesTableViewController *destinationViewController = segue.destinationViewController;
destinationViewController.openSubject = [self.detailItem description];
} else {
// Do nothing
}
}
I've embedded a UIViewController in a NavigationController and created a popover segue from another UIViewController to the NavigationController - but when I navigate I get this error:
-[UINavigationController setOpenSubject:]: unrecognized selector sent to instance 0x15e532a0
Any ideas why?
Thanks!
NotesTableViewController.h
#import <UIKit/UIKit.h>
#interface NotesTableViewController : UITableViewController <UINavigationControllerDelegate>
#property(nonatomic, strong)NSString *openSubject;
#end
NotesTableViewController.m
#import "NotesTableViewController.h"
#interface NotesTableViewController ()
{
NSMutableArray *_objects;
}
#end
#implementation NotesTableViewController
#synthesize openSubject;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
if (openSubject.length == 0) {
// There's currently no subject open, write it in the navigationbar
// Prompt = open subject
// Title = notes header
self.navigationItem.prompt = #"No subject selected";
self.navigationItem.title = #"My Notes";
} else {
// Open the subject
// Prompt = notes header
// Title = open subject
self.navigationItem.prompt = openSubject;
self.navigationItem.title = #"My notes";
// Load the notes data
// Create the key
NSString *partOfKey = #"-notes";
NSString *notesKey = [NSString stringWithFormat:#"%#%#", openSubject, partOfKey];
// Load the _objects from NSUserdefaults
_objects = [[NSUserDefaults standardUserDefaults] objectForKey:notesKey];
}
// 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.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
// Register a class or nib file using registerNib:forCellReuseIdentifier
// o registerClass:forCellReuiseIdentifier: method before calling this method
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
}
- (void)awakeFromNib
{
self.clearsSelectionOnViewWillAppear = NO;
self.preferredContentSize = CGSizeMake(320.0, 600.0);
[super awakeFromNib];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)addNote:(id)sender {
// Create a new note
if (openSubject.length == 0) {
// The openSubject is nil, can't add a subject - tell the user
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: #"No subject" message: #"Please select a subject prior to adding a note" delegate: nil cancelButtonTitle:#"OK" otherButtonTitles:nil]; [alert show];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"New note" message:#"Enter a note" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Add", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
// The user created a new subject, add it
if (buttonIndex == 1) {
// Get the input text
NSString *newNote = [[alertView textFieldAtIndex:0] text];
// Initialize objects
if (!_objects) {
_objects = [[NSMutableArray alloc] init];
}
// Check if the note already exist
if ([_objects containsObject:newNote]) {
// Tell the user this note already exists
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: #"Already exists" message: #"This note already exist, sorry" delegate: nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
} else {
// The note doesn't exist, add it
[_objects insertObject:newNote atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
// Save the new _objects
[self saveObjects];
}
}
}
-(void)saveObjects {
// Create the key
NSString *partOfKey = #"-notes";
// Save the new objects
NSString *notesKey = [NSString stringWithFormat:#"%#%#", openSubject, partOfKey];
[[NSUserDefaults standardUserDefaults] setObject:_objects forKey:notesKey];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return _objects.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSString *object = _objects[indexPath.row];
cell.textLabel.text = [object description];
return cell;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_objects removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
// Save the new objects
[self saveObjects];
} 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 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 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 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
(I trust everyone to not steal this code)

If you trigger a segue to a UINavigationController the segue.destinationViewController will be the navigation controller and not the view controller contained in the navigation controller.
You can however get a reference to your NotesTableViewController:
UINavigationController *navController = segue.destinationViewController;
NotesTableViewController *notesTableVC = (NotesTableViewController *)[navController topViewController];
and then you can use
notesTableVC.openSubject = [self.detailItem description];
etc. to set the properties in your NotesTableViewController.

make sure your segue Identifiers are identified correctly as "notesSegue" and "readMoreDetail" , sometime you have to clean the project and run it again.

Related

AppDelegate function is not loading Table view controller

I created the simple Master Detail application for login.I deleted the MasterViewController, DetailViewController and Main.storyboard according to this tutorial:
Login app to mysql DB [part 1]
In AppDelegate didFinishLaunchingWithOptions function i made the following change
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window=[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen]bounds] ];
/*UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
navigationController.topViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem;*/
LoginTableViewController *loginTableViewController=[[LoginTableViewController alloc]initWithNibName:#"LoginTableViewController" bundle:nil ];
self.navigationController =[[UINavigationController alloc]initWithRootViewController:loginTableViewController];
self.window.rootViewController=self.navigationController;
[self.window makeKeyWindow];
return YES;
}
I commented this function from App Delegate function
/*
- (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController {
.............................
}*/
I created LoginTableTableViewController with xib of subclass UITableViewController.
I created LoginTableTableViewController.h
#import "LoginTableViewController.h"
#interface LoginTableViewController ()
#end
#implementation LoginTableViewController
#synthesize arraylogin,userNameTextField,passwordTextField;
bool isKeyboardVisible=FALSE;
- (void)viewDidLoad {
[super viewDidLoad];
arraylogin=[[NSArray alloc] initWithObjects:#"user name",#"password",nil];
//set title
self.navigationItem.title=#"Best App";
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardAppeared) name:UIKeyboardDidShowNotification object:nil];
// 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.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
-(void) loginAction
{
if([userNameTextField.text isEqualToString:#""] || [passwordTextField.text isEqualToString:#""])
{
// UIAlertView #alert=[[UIAlertView alloc] intitWithTitle:#"alert" messge:#"Please fill in all //the fields" delegate:self cancel]
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"alert" message:#"Please fill in all the fields" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
//i will use a code to connect to DB turorial
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)keyboardAppeared
{
if(isKeyboardVisible==false)
{
isKeyboardVisible=true;
UIBarButtonItem *btnGo=[[UIBarButtonItem alloc] initWithTitle:#"Go" style:UIBarButtonItemStyleBordered target:self action:#selector(loginAction)];
self.navigationItem.rightBarButtonItem=btnGo;
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
#warning Incomplete implementation, return the number of sections
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
#warning Incomplete implementation, return the number of rows
return [arraylogin count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifer=#"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifer];
if (cell==nil)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifer];
}
//cell are not selectable
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
CGRect frame;
frame.origin.x=10;
frame.origin.y=10;
frame.size.height=30 ;
frame.size.width= 200;
UILabel *label=[[UILabel alloc]initWithFrame:frame];
label.font=[UIFont boldSystemFontOfSize:16.0];
label.text=[arraylogin objectAtIndex:indexPath.row];
[cell.contentView addSubview:label];
frame.origin.x=110;
frame.size.height=90 ;
frame.size.width= 180;
// Configure the cell
if(indexPath.row==0)
{//username part
userNameTextField=[[UITextField alloc] initWithFrame:frame];
userNameTextField.returnKeyType=UIReturnKeyDefault;
[cell.contentView addSubview:userNameTextField];
}
else{//password part
passwordTextField=[[UITextField alloc] initWithFrame:frame];
passwordTextField.returnKeyType=UIReturnKeyDefault;
passwordTextField.secureTextEntry=YES;
[cell.contentView addSubview:passwordTextField];
}
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 - Table view delegate
// In a xib-based application, navigation from a table can be handled in -tableView:didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here, for example:
// Create the next view controller.
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:<##"Nib name"#> bundle:nil];
// Pass the selected object to the new view controller.
// Push the view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
}
*/
-(void) viewDidUnload
{
[super viewDidUnload];
self.arraylogin=nil;
self.userNameTextField=nil;
self.passwordTextField=nil;
}
/*
#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
This program should be executing and show out like in this image
.
Execution stops program on some thread of main class function how i can remove this error and get the required output?You can download sample code from this link for correction.https://drive.google.com/file/d/0B5pNDpbvZ8SnV3Zab3VPM1B0a0k/view?usp=sharing
Your project is still specifying that a "Main" storyboard should be loaded. Edit your Info.plist file to remove the storyboard entry and it will get you past the current error.
(If you include error messages from your debug console when asking a question, it makes it easier on anyone trying to help. For example: "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Could not find a storyboard named 'Main' in bundle".)

How to implement searchbar in iOS 7 tableView?

I'm new to programming. I am building a program that scans barcodes and puts the UPC number in the search box in my table view. Now all i want to do is create a search for the UPC scanned. the viewTable is displaying an inventory from a sqlite database.
The search bar is built all i need to do is program it to search, and I have not found any good tutorials on how to do this. How can I implement this?
#import "MasterViewController.h"
#import "DetailViewController.h"
#import "ScanViewController.h"
#import <sqlite3.h>
#interface MasterViewController ()
{
NSMutableArray *_objects;
}
#end
#implementation MasterViewController
{
}
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Get the DBAccess object;
DBAccess *dbAccess = [[DBAccess alloc] init];
// Get the products array from the database
self.products = [dbAccess getAllProducts];
// Close the database because we are finished with it
[dbAccess closeDatabase];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)insertNewObject:(id)sender
{
if (!_objects) {
_objects = [[NSMutableArray alloc] init];
}
[_objects insertObject:[NSDate date] atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [self.products count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell.
cell.accessoryType = UITableViewCellAccessoryNone;
Product* product = [self.products objectAtIndex:[indexPath row]];
cell.textLabel.text = product.serial;
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return NO;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_objects 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.
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Product *theProduct = _products[indexPath.row];
[[segue destinationViewController] setDetailItem:theProduct];
NSLog(#"this is prepare for segue");
}
}
- (void)scanditSDKOverlayController: (ScanditSDKOverlayController *)scanditSDKOverlayController
didScanBarcode:(NSDictionary *)barcodeResult
{
// add your own code to handle the barcode result e.g.
scanResult = [barcodeResult valueForKey:#"barcode"];
//barcodelabel.text = [NSString stringWithFormat:#"The barcode is: %#", scanResult];
searchLabel.text = [NSString stringWithFormat:#"%#", scanResult];
[self dismissViewControllerAnimated:YES completion:nil];
self.tableView.contentOffset = CGPointMake(0, 0 - self.tableView.contentInset.top);
[searchLabel becomeFirstResponder];
[super viewDidAppear:YES];
}
- (void)scanditSDKOverlayController: (ScanditSDKOverlayController *)scanditSDKOverlayController
didCancelWithStatus:(NSDictionary *)status
{
// add your own code to handle the user canceling the barcode scan process
}
- (void)scanditSDKOverlayController: (ScanditSDKOverlayController *)scanditSDKOverlayController
didManualSearch:(NSString *)input
{
// add your own code to handle user input in the search bar
// (only required if you use the search bar provided by the Scandit SDK
}
-(IBAction)scanClick:(id)sender;
{
ScanditSDKBarcodePicker *picker = [[ScanditSDKBarcodePicker alloc] initWithAppKey:#"oK1ckH/7EeOPhaseNDXmvNVu+pCX2y6UHZWZ/VYw0hE"];
picker.overlayController.delegate = self;
[picker startScanning];
[self presentViewController:picker animated:YES completion:nil];
//[[self navigationController]pushViewController:picker animated:YES];
[searchLabel becomeFirstResponder];
}
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
searchBar.text = nil;
[searchBar resignFirstResponder];
}
#end
I figured out my own question. for anyone who stumbles across this question, i used NSPredicate. i assumed that if there is a sqlite database then you cannot use NSPredicate, but i made it work. As long as the data is in an array..

After adding new cell, how to get the UITableViewControler to save the new entry, so when app is closed and re opened the new cell is there

Ok, so I'm new to iOS Development. I have just created a master view application for note taking. Every thing works fine except for one thing, after a new cell is created and i stop the app and reopen the app the new cell is not there!
Thanks in advance!
Master View Controller.m
#import "MasterViewController.h"
#import "DetailViewController.h"
#interface MasterViewController () {
NSMutableArray *_objects;
}
#end
#implementation MasterViewController
#synthesize myTableView, numbers;
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
//NSMT arry
numbers = [[NSMutableArray alloc]initWithObjects:#"One",#"Two",#"Three",#"Four", nil];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
}
- (void)viewWillAppear:(BOOL)animated {
}
-(void)viewWillDisappear:(BOOL)animated{
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)insertNewObject:(id)sender
{
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Enter" message:#"" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
/*
if (!numbers) {
numbers = [[NSMutableArray alloc] init];
}
[numbers insertObject:[NSDate date] atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
*/
}
-(void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
[myTableView setEditing:editing animated:animated];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return numbers.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = [numbers objectAtIndex:indexPath.row];
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) {
[numbers 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.
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
//if user hits OK
if (buttonIndex == 1) {
NSString * tempTextField = [alertView textFieldAtIndex:0].text;
if (!numbers) {
numbers = [[NSMutableArray alloc] init];
}
[numbers insertObject:tempTextField atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.myTableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
/*
// 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;
}
*/
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDate *object = _objects[indexPath.row];
[[segue destinationViewController] setDetailItem:object];
}
}
#end
MasterViewController.h
#import <UIKit/UIKit.h>
#interface MasterViewController : UITableViewController
<UITableViewDataSource, UITableViewDelegate, UIAlertViewDelegate>
#property (strong, nonatomic) IBOutlet UITableView *myTableView;
#property (strong, nonatomic) NSMutableArray * numbers;
#end
Perhaps tell us how you're storing the data used to populate the tableview. As this is what you need to save.
You could save it using CoreData or just use NSUserDefaults, there are plenty of options open to you. However, without knowing how you data is currently structured it's hard to give you a specific example.
Show some code and you'll get a better answer.

Creating a view controller

I'm creating an iphone app using storyboard. I'm basically new on objective c and Xcode.
I have a list of categories, every time I click on a category it should open a tableView, so I can add an item in that category. But instead of getting a different tableView for each category, its the same table for all the categories and the added items are copied.
How can I create a new table for each label?
Thanks in advance!
Here's what I have for adding a category
#interface ListViewController ()
#end
#implementation ListViewController{
NSMutableArray *items;
}
#synthesize lists;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
items = [NSMutableArray arrayWithCapacity:20];
List *item = [[List alloc] init];
item.title = #"Grocery List";
[items addObject:item];
item = [[List alloc]init];
item.title = #"Project List";
[items addObject:item];
item = [[List alloc] init];
item.title = #"Events List";
[items addObject:item];
self.lists = items;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return [self.lists count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Configure the cell...
/*UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ListsCell"];
List *list = [self.lists objectAtIndex:indexPath.row];
cell.textLabel.text = list.title;*/
ListCell *cell = (ListCell *)[tableView dequeueReusableCellWithIdentifier:#"ListsCell"];
List *list = [self.lists objectAtIndex:indexPath.row];
cell.titleLabel.text = list.title;
return cell;
}
//Add new list, new row will be added on the bottom and its data source must always be sync
-(void)addViewControllerSave:(AddViewController *)controller addList:(List *)list{
[self.lists addObject:list];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[self.lists count] - 1 inSection:0];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self dismissViewControllerAnimated:YES completion:nil];
}
/*
// 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) {
if(editingStyle == UITableViewCellEditingStyleDelete){
[self.lists removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject: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.
if([segue.identifier isEqualToString:#"AddList"]){
UINavigationController *navigationController = segue.destinationViewController;
AddViewController *addViewController = [[navigationController viewControllers] objectAtIndex:0];
addViewController.delegate = self;
}
else if([segue.identifier isEqualToString:#"ViewItem"]){
UINavigationController *nav = segue.destinationViewController;
ItemViewController *itemViewController = [[nav viewControllers] objectAtIndex:0];
itemViewController.delegate = self;
}
}
#pragma mark - AddViewControllerDelegate
-(void)addViewControllerCancel:(AddViewController *)controller{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)addViewControllerSave:(AddViewController *)controller{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)itemViewControllerBack:(ItemViewController *)controller{
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
Here's what I have for adding an item:
#interface ItemViewController ()
#end
#implementation ItemViewController{
NSMutableArray *newItems;
}
#synthesize items;
#synthesize delegate;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
newItems = [NSMutableArray arrayWithCapacity:20];
Item *i = [[Item alloc]init];
i.listItem = #"a";
[newItems addObject:i];
self.items = newItems;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return [self.items count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Configure the cell...
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ItemsCell"];
Item *item = [self.items objectAtIndex:indexPath.row];
cell.textLabel.text = item.listItem;
return cell;
}
-(void)addIteViewControllerSave:(AddItemViewController *)controller addItem:(Item *)item{
[self.items addObject:item];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[self.items count] -1 inSection:0];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self dismissViewControllerAnimated:YES completion:nil];
}
#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.
if([segue.identifier isEqualToString:#"AddItem"]){
UINavigationController *navigationController = segue.destinationViewController;
AddItemViewController *addItemViewController = [[navigationController viewControllers]objectAtIndex:0];
addItemViewController.itemDelegate = self;
}
}
#pragma mark - AddItemViewControllerDelegate
-(void)addItemviewControllerCancel:(AddItemViewController *)controller{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)addIteViewControllerSave:(AddItemViewController *)controller{
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - ItemViewControllerDelegate
-(IBAction)back:(id)sender{
[self.delegate itemViewControllerBack:self];
}
#end
AddItemViewController
#import "AddItemViewController.h"
#import "Item.h"
#interface AddItemViewController ()
#end
#implementation AddItemViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)cancel:(id)sender{
[self.itemDelegate addItemviewControllerCancel:self];
}
-(IBAction)save:(id)sender{
Item *item = [[Item alloc] init];
item.listItem = self.listItemTextField.text;
[self.itemDelegate addIteViewControllerSave:self addItem:item];
}
#end
Don't create a new table view for each label, instead populate it with different data for each label, you will need to change the object you are storing your data in and call
[tableView reloadData];
If all the added items you may need to clear out your array you are using to store the objects before adding the additional content.
[self.items removeAllObjects];

Crashing On TableView insertRowsAtIndexPath

My app was running fine, I've not modified it to have a dedicated data controller class rather than the data being handled in the main UI class as it was during initial testing. However since the change it keeps crashing when adding a new item to the tableview.
The line of code and error it's crashing on are;
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
2012-07-22 07:17:44.772 speecher[1897:707] * Terminating app due to
uncaught exception 'NSInternalInconsistencyException', reason:
'attempt to insert row 0 into section 0, but there are only 0 rows in
section 0 after the update'
The full code for that class, (the main MasterViewController class) is as follows.
//
// SpeecherMasterViewController.m
// speecher
//
//
#import "SpeecherMasterViewController.h"
#import "SpeecherDataController.h"
#import "SpeecherDetailViewController.h"
#interface SpeecherMasterViewController () {
NSString *newTitle;
NSMutableArray *_speeches;
NSMutableArray *_content;
SpeecherDataController *object;
}
#end
#implementation SpeecherMasterViewController
#synthesize detailViewController = _detailViewController;
- (void)awakeFromNib
{
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
self.detailViewController = (SpeecherDetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
object = [[SpeecherDataController alloc] init];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [object returnNoObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
cell.textLabel.text = [object returnTitle:indexPath.row];
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) {
[_speeches removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject: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;
}
*/
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *titleobj = [object returnTitle:indexPath.row];
NSString *contentobj = [object returnContent:indexPath.row];
self.detailViewController.detailItem = titleobj;
self.detailViewController.detaitContent = contentobj;
}
- (void)insertNewObject:(id)sender
{
//Make sure clear before we start, also make sure initalized (double redundancy with clear statement at end)
newTitle = #"";
//New Title pop up UIAlert View
UIAlertView * alert = [[UIAlertView alloc]
initWithTitle:#"New Speech"
message:#"Please enter a name for speech"
delegate:self
cancelButtonTitle:#"Create"
otherButtonTitles:nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField * alertTextField = [alert textFieldAtIndex:0];
alertTextField.keyboardType = UIKeyboardTypeDefault;
alertTextField.placeholder = #"Enter a new title";
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
newTitle = [[alertView textFieldAtIndex:0] text];
[object addNewContent:newTitle :#"IT REALLY WORKS!" :#"Nothing"];
//create new speech title, add to array and add to tableview
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
//Clear newTitle for use next time
newTitle = #"";
}
#end
EDIT:
Amended to add [object addNewContent] method & class as per comments,
//
// SpeecherDataController.m
// speecher
//
//
#import "SpeecherDataController.h"
#interface SpeecherDataController ()
{
NSMutableArray *titles;
NSMutableArray *content;
NSMutableArray *timer;
}
#end
#implementation SpeecherDataController
-(void) addNewContent:(NSString*)sTitle : (NSString*)sContent :(NSString*)sTimer
{
[titles insertObject:sTitle atIndex:0];
[content insertObject:sContent atIndex:0];
[timer insertObject:sTimer atIndex:0];
}
//Methods to return data
-(NSString*) returnTitle:(NSUInteger)row
{
return [titles objectAtIndex:row];
}
-(NSString*) returnContent:(NSUInteger)row
{
return [content objectAtIndex:row];
}
-(NSString*) returnTimer:(NSUInteger)row
{
return [timer objectAtIndex:row];
}
-(NSInteger) returnNoObjects
{
return titles.count;
}
#end
The problem is the NSMutableArrays hadn't been alloc and init. Had to add a check to see if they had a init and alloc if not. New check looks like this,
-(void) addNewContent:(NSString*)sTitle : (NSString*)sContent :(NSString*)sTimer
{
if(!titles)
{
titles = [[NSMutableArray alloc] init];
}
if(!content)
{
content = [[NSMutableArray alloc] init];
}
if(!timer)
{
timer = [[NSMutableArray alloc] init];
}
[titles insertObject:sTitle atIndex:0];
[content insertObject:sContent atIndex:0];
[timer insertObject:sTimer atIndex:0];
}

Resources