using iOS delegates - ios

im new to iOS and its developing .there i have used iOS delegates to pass values in between view controllers
1. Essentialinfocontroller - its got TableView
2. detailcontroller -
i want to pass values of Essentialinfocontroller to detailcontroller
to do that i used delegates but nothing print on console please help me.
Essentialinfocontroller.h
#import <UIKit/UIKit.h>
#protocol sendTestData <NSObject>
-(void)sendDataToA:(NSArray *)array;
#end
#interface Essentialinfocontroller : UIViewController<UITableViewDataSource,UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *info;
#property (nonatomic,strong) NSDictionary * courses;
#property (nonatomic, strong)NSArray *coursekeys;
#property(nonatomic,strong) NSString* customeLink;
#property (nonatomic,retain)NSArray * array;
#property(nonatomic,assign)id delegate;
#end
Essentialinfocontroller.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row==0){
[self giveValuestoNSmutableArray];
[delegate sendDataToA:array];
}
}
-(void)giveValuestoNSmutableArray
{
array = [NSArray arrayWithObjects:#"Jill Valentine", #"Peter Griffin", #"Meg Griffin", #"Jack Lolwut",
#"Mike Roflcoptor", #"Cindy Woods", #"Jessica Windmill", #"Alexander The Great",
#"Sarah Peterson", #"Scott Scottland", #"Geoff Fanta", #"Amanda Pope", #"Michael Meyers",
#"Richard Biggus", #"Montey Python", #"Mike Wut", #"Fake Person", #"Chair",
nil];
}
detailcontroller.h
#import <UIKit/UIKit.h>
#import "Essentialinfocontroller.h"
#interface detailcontroller : UIViewController <sendTestData>
#end
detailcontroller.m
#import "detailcontroller.h"
#interface detailcontroller ()
#end
#implementation detailcontroller
- (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.
Essentialinfocontroller * acontollerobject=[[Essentialinfocontroller alloc] initWithNibName:#"Essentialinfocontroller" bundle:nil];
acontollerobject.delegate=self; // protocol listener
[self.navigationController pushViewController:acontollerobject animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)sendDataToA:(NSArray *)array
{
for (NSString *string in array) {
NSLog(#"%#", string);
}
}
#end

You've got the relationship between controllers and delegates a little backwards. A delegate is used to pass information back. Your tableViewController is the detailController's delegate, and detailController shouldn't be allocating an EssentialInfoController inside it. You're basically creating a whole new EssentialInfoController that's different from the first one.
The easiest way to pass data is just to set it when the detailController is allocated. Also, since you're using storyboards, you have to use (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender to allocate the detailController.
Here's what I would do:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row==0){
[self performSegueWithIdentifier:#"OpenDetailsController"];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
DetailController *controller = (DetailController *)[segue destinationViewController];
NSArray *array = <your array here>;
[controller setArray:array];
}
In your storyboard, set the Storyboard Segue Identifier for that segue to "OpenDetailsController".
A delegate function is defined through a protocol, and you would have the DetailController call its delegate like this:
[self.delegate doSomething];
And in the EssentialInfoViewController you have to define the delegate function
-(void)doSomething {
}

Related

Objective C-Custom Delegate not working

I am trying to get a string from a view controller to another using delegate method.But the delegate method is not getting called.Below is the code
#protocol CustomDelegate<NSObject>
-(void)didDataRecieved;
#end
#interface CustomController:UIViewController
#property id<CustomDelegate>delegate;
#property(retain,nonatomic)NSString *string;
#end
#implementaion CustomController
-(void)viewDidLoad
{
string=#"hello";
if([self.delegate respondsToSelector#selector(didDataRecived)]) {
[self.delegate didDataRecieved];
}
}
-(IBACTION)gotoViewController
{
ViewController *view=[self.storyboard instantiateViewController:#"View"];
[self.navigationController pushViewController:view aniamted:YES];
}
#end
#interface ViewController:UIViewController<CustomDelegate>
#property (nonatomic,retain)CustomController *cust;
#end
#implementation ViewController
-(void)viewDidLoad
{
self.cust=[[CustomController alloc]init];
self.cust.delegate=self;
}
-(void)didDataRecieved
{
NSLog(#"data %#",self.cust.string);
}
#end
Can anyone point out where am going wrong...plz help.
edited the code..tried this way too.
if([self.delegate respondsToSelector#selector(didDataRecived)]){
[self.delegate didDataRecieved];
}
I will give you the sample coding.Customize the below code.
Here we have two view controllers.
ViewController
and
SecondViewController
in SecondViewController
.h
#import <UIKit/UIKit.h>
#class SecondViewController;
#protocol SecondViewControllerDelegate <NSObject>
- (void)secondViewController:(SecondViewController *)secondViewController didEnterText:(NSString *)text;
#end
#interface SecondViewController : UIViewController
#property (nonatomic, assign)id<SecondViewControllerDelegate> delegate;
#property (nonatomic, strong) IBOutlet UITextField *nameTextField;//It must connect as outlet connection
- (IBAction)doneButtonTapped:(id)sender;
#end
.m
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (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.
}
//Either use NSNotification or Delegate
- (IBAction)doneButtonTapped:(id)sender;
{
//Use Notification
[[NSNotificationCenter defaultCenter] postNotificationName:#"passingDataFromSecondViewToFirstView" object:self.nameTextField.text];
//OR Custom Delegate
[self.delegate secondViewController:self didEnterText:self.nameTextField.text];
[self.navigationController popViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
in ViewController
.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface ViewController : UIViewController<SecondViewControllerDelegate>
#property (nonatomic, strong) IBOutlet UILabel *labelName; //You must connect the label with outlet connection
- (IBAction)gotoNextView:(id)sender;
#end
.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//addObserver here...
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textFromPreviousViewControllerNotificationReceived:) name:#"passingDataFromSecondViewToFirstView" object:nil];
// Do any additional setup after loading the view, typically from a nib.
}
//addObserver Method here....
- (void)textFromPreviousViewControllerNotificationReceived:(NSNotification *)notification
{
// set text to label...
NSString *string = [notification object];
self.labelName.text = string;
}
- (IBAction)gotoNextView:(id)sender;
{
//If you use storyboard
SecondViewController *secondViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
//OR If you use XIB
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
secondViewController.delegate = self;
[self.navigationController pushViewController:secondViewController animated:YES];
}
//Calling custom delegate method
- (void)secondViewController:(SecondViewController *)secondViewController didEnterText:(NSString *)text
{
self.labelName.text = text; //Getting the data and assign the data to label here.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
For your understanding the code I create a simple passing data from one second view controller to first view controller.
First we navigate the view from first view controller to second view controller.
After that we send the data from second view controller to first view controller.
NOTE : You can either use NSNotification or Custom Delegate method for sending data from One View Controller to Other View Controller
If you use NSNotification, you need to set the postNotificationName for getting data in button action method.
Next you need to write addObserver in (sending data to your required View Controller) ViewController and call the addObserver method in same View Controller.
If you use custom delegate,
Usually we go with Custom Protocol Delegate and also we need to Assign the delegate here.
Very importantly we have to set the Custom Delegate Method in the Second View Controller.Because where we send the data to first view controller once we click the done button in second view controller.
Finally we must call the Custom Delegate Method in First View Controller, where we get the data and assign that data to label.Now you can see the passed data using custom delegate.
Likewise you can send the data to other view controller using Custom Delegate Methods
how you pushing your second controller? i cant see.
but your code working for me.
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
ViewController1 *vc = [ViewController1 new];
vc.delegate = self;
[self presentViewController:vc animated:YES completion:nil];
}
-(void)didDataRecieved
{
NSLog(#"recieved");
}
#end

Delegate Method is not getting called

I am trying to pass selected cell text from CategoryViewController to DescribeViewController. But it does not call the method in the DescribeViewController method.
CategoryViewController.h
#import <UIKit/UIKit.h>
#protocol CategoryViewControllerDelegate <NSObject>
- (void)didSelectRow:(NSString *)cellDataString;
#end
#interface CategoryViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
#property (weak, nonatomic) id<CategoryViewControllerDelegate> delegate;
#end
CategoryViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [categoryTableView cellForRowAtIndexPath:indexPath];
NSString *cellText = cell.textLabel.text;
[self.delegate didSelectRow:cellText];
[[self navigationController] popViewControllerAnimated:YES];
}
DescribeViewController.h
#import <UIKit/UIKit.h>
#import "CategoryViewController.h"
#interface DescribeViewController : ProductAwareBaseViewController<UITextFieldDelegate, CategoryViewControllerDelegate>
The following didSelectRow method is not getting called. I could not able to find out the root of the problem.
DescribeViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
CategoryViewController *popoverTableViewController = [[CategoryViewController alloc] init];
popoverTableViewController.delegate = self;
}
- (void)didSelectRow:(NSString *)cellDataString
{
self.cellDataString = cellDataString;
}
ProductAwareBaseViewController.h
#import UIKit;
#class Product;
#interface ProductAwareBaseViewController : UIViewController
#property (nonatomic, strong) Product *product;
#end
ProductAwareBaseViewController.m
#import "ProductAwareBaseViewController.h"
#import "Product.h"
#interface ProductAwareBaseViewController ()
#end
#implementation ProductAwareBaseViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.destinationViewController isKindOfClass:[ProductAwareBaseViewController class]]) {
ProductAwareBaseViewController *vc = (ProductAwareBaseViewController *)segue.destinationViewController;
vc.product = self.product;
}
}
#end
Try setting the delegate object in didSelectRow. And call that delegate method after that. Because delegate is weak, may be it is released from the memory.
CategoryViewController *popoverTableViewController = [[CategoryViewController alloc] init];
popoverTableViewController.delegate = self;
UITableViewCell *cell = [categoryTableView cellForRowAtIndexPath:indexPath];
NSString *cellText = cell.textLabel.text;
[self.delegate didSelectRow:cellText];
[[self navigationController] popViewControllerAnimated:YES];
Most common reason for delegate method not being called is dealing with incorrect objects.
Ensure that CategoryViewController object created from
DescribeViewController is the same which you are presenting on
screen and that the delegate is being set on the same object. I truly believe you are creating a new CategoryViewController object and setting delegate on that.
In DescribeViewController, before calling delegate, check the
existence of delegate and that it implements the protocol method (if
its an optional method). This is a safety check, you can also put a NSLog statement to double check if your delegate exists or not. You are failing here.
->
if (delegate && [delegate respondsToSelector:(didSelectRow:)]) {
[self.delegate didSelectRow:cellText];
}
PS: If you are segueing from DescribeViewController to CategoryViewController then you set delegate in prepareForSegue:.
Follow these guidelines and I am sure you would be able to fix your issue!
try
#property (nonatomic, weak) id <CategoryViewControllerDelegate> delegate;
for declaring your delegate.
EDITED
try for checking the delegate is returning some value or not.
By this, whenever yo are setting the values.
if(self.delegate && [self.delegate respondsToSelector:#selector(didSelectRow:)])
{
[self.delegate didSelectRow:(NSString *) cellDataString];
}
and also if you are using the segue to transfer the data between two controllers then check there for the delegates.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
DescribeViewController *obj = (DescribeViewController *)segue.destinationViewController;
obj.delegate =self;
}
i think this will help you.

sending information back from detail view controller ios

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!
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.
You can use any one of the following methods
Delegation
Blocks
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

Delegate in Objective-C

I am new at Objective-C, and I'm trying to understand delegates. I have searched and read a lot, but nothing is really helping me understand. I think that best way to understand this might be asking a question with a sample app.
I'm trying to create a grade calculator application to test my skills. Here are my files:
mainTableViewController.h
#import <UIKit/UIKit.h>
#interface mainTableViewController : UITableViewController
#end
mainTableViewController.m
#import "mainTableViewController.h"
#import "addLectureViewController.h"
#interface mainTableViewController ()
#end
#implementation anaTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
[lectureName count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
}
#end
addLectureViewController.h
#import <UIKit/UIKit.h>
#interface addLectureViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *lectureNameTextField;
- (IBAction)addButtonPressed:(id)sender;
#property NSMutableArray *lectureName;
#property NSObject *lecture;
#end
addLectureViewController.m
#import "addLectureViewController.h"
#interface addLectureViewController ()
#end
#implementation addLectureViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_lectureName = [[NSMutableArray alloc] init];
_lecture = [[NSObject alloc] init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (IBAction)addButtonPressed:(id)sender {
_lecture = _lectureNameTextField.text;
[_lectureName addObject:_lecture];
NSLog(#"%#",_lectureName);
}
#end
Everything is okay so far. But when i try to use the _lectureName NSMutableArray at mainTableViewController.m, I can't see the array.
I know the codes for printing the array in tableView. I know they are not at there right now. I just don't understand implement delegate codes to my code.
If You want to display something on the rows of the table, You can take an NSArray and you have to return the count of the array in the delegate method:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return array.count;
}
Otherwise, table will not display any elements. And delegate method cellForRowAtIndexPath will only be called if you are returning a particular array count of number count in your numberOfRowsInSection method.
You can take reference from these links to understand delegates:
http://www.tutorialspoint.com/ios/ios_delegates.htm
How do I set up a simple delegate to communicate between two view controllers?
http://code.tutsplus.com/tutorials/ios-sdk-custom-delegates--mobile-10848
But in the case of tableView, the delegate methods are internally defined and triggered internally. We just need to set those delegates to the controller which acts as a listener.
The below code might have syntax errors but they can provide a summary of delegates for this code.
Make the following changes :-
mainTableViewController.h
#import <UIKit/UIKit.h>
#interface mainTableViewController : UITableViewController
#property(strong, nonatomic) NSMutableArray *lectureName
#end
Synthesize the property lectureName in mainTableViewController.m
Then make the following changes in addLectureViewController.h
#import <UIKit/UIKit.h>
#import "mainTableViewController.h"
#interface addLectureViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *lectureNameTextField;
- (IBAction)addButtonPressed:(id)sender;
#property(weak, nonatomic) id<mainTableViewController> delegate;
#property NSMutableArray *lectureName;
#property NSObject *lecture;
#end
Synthesize the property delegate in addLectureViewController.m
Then make the following change :-
- (IBAction)addButtonPressed:(id)sender {
_lecture = _lectureNameTextField.text;
[_lectureName addObject:_lecture];
NSLog(#"%#",_lectureName);
delegate.lectureName=_lectureName;
}
Assuming that you are pushing addLectureViewController from mainTableViewController, also include the following code in prepareForSegue of mainTableViewController (or whatever method in which you are pushing addLectureViewController). :-
addLectureViewController *vc=[[addLectureViewController alloc] init];
vc.delegate=self;
// Push vc
The above code actually creates a weak property of type id<mainTableViewController> called delegate (weak in order to prevent reference cycles). This way, addLectureViewController can update mainTableViewController's property.
Points:
Why is the class in mainTableViewController.m named anaTableViewController. It should be mainTableViewController (almost always, until you get more advanced).
mainTableViewController and addLectureViewController should start with capital letters.
The only way for mainTableViewController to access lecture is through a addLectureViewController object, e.g.
addLectureViewController *alvc = // *something* here
NSArray *localLecture = [alvc lecture];
Figure out how you have access to an addLectureViewController and you will have solved your problem.

NSInvalidArgumentException error occurs when calling setDelegate

I am trying to segue to another screen from a uitableview in iOS5. I have set up a delegate etc. which seems to work (the segue occurs) but I think I need to "set delegate to initialize the data I want to display in the new screen. I get a NSInvalidArgumentException error though when I call it is prepareforsegue.
Here is the code for the uitableview part...
#import "iTanksV2ListViewController.h"
#import "tank.h"
#import "tankDetailViewController.h"
#interface iTanksV2ListViewController ()
#property tank *selectedTank;
#end
#implementation iTanksV2ListViewController
#synthesize tanks = _tanks;
#synthesize tankTableView = _tankTableView;
#synthesize delegate = _delegate;
#synthesize selectedTank = _selectedTank;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.tankTableView.delegate = self;
self.tankTableView.dataSource = self;
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"Show Tank Details"])
{
UILabel *myLabel = [[UILabel alloc] init];
myLabel.text = self.selectedTank.tankNumber;
[segue.destinationViewController setTankNumberLabel:myLabel];
[segue.destinationViewController setDelegate:self]; ///this is where it fails!!!
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.selectedTank = [self.tanks objectAtIndex:indexPath.row];
[self.delegate iTanksListViewController:self choseTank:self.selectedTank];
}
and then in the detail view I use the following...
-(void)iTanksListViewController:(iTanksV2ListViewController *)sender choseTank:(id)tank
{
self.tankToShow = tank;
}
but this doesn't get called - presumably because i don't successfully call the setdelegate method?!
You must not have synthesized your delegate property. Also, make sure that your header file properly has the delegate protocol referenced like
#interface TankDetailViewController : UITableViewController <DELEGATEPROTOCOL>
I thought I had... this snippet is from the itanksv2listviewcontroller header:
#interface iTanksV2ListViewController : UITableViewController
#property (nonatomic, strong) NSArray *tanks;
#property (weak, nonatomic) IBOutlet UITableView *tankTableView;
#property (weak, nonatomic) id <iTanksV2ListViewControllerDelegate> delegate;
#end
and this from the m file :
#synthesize delegate = _delegate;
and this is what I have put in the detailview m file:
#interface tankDetailViewController () <iTanksV2ListViewControllerDelegate>
#end

Resources