my protocol isn't working - ios

i've been trying to implement this protocol for several hours and it doesn't seem to work for some reason. Basically i have a split view which has a view controller and a table controller, one class holds these two together. The main class creates an instance of the table and runs perfectly, but if i select a cell i want the view controller to react. So i wanted to create a protocol for when a table cell is selected it will do something in the main class.
TableSplitViewController, this is the main class:
#interface TableSplitViewController : UIViewController <updateView>
{
ChildrenTableViewController *firstController;
IBOutlet UITableView *firstTable;
IBOutlet UITableViewCell *tablecell;
NSString *name;
}
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) IBOutlet UILabel *childnamelabel;
#end
THis is the TableSplitViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
if (firstController == nil) {
firstController = [[ChildrenTableViewController alloc] initWithStyle:UITableViewStyleGrouped];
}
[firstTable setDataSource:firstController];
[firstTable setDelegate:firstController];
firstController.view = firstController.tableView;
// Do any additional setup after loading the view.
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowChildrenDetails"]) {
ChildrenDetailViewController *detailViewController = [segue destinationViewController];
NSIndexPath *myIndexPath = [firstController.tableView indexPathForSelectedRow];
detailViewController.childrenDetailModel = [[NSArray alloc]
initWithObjects: [firstController.childname objectAtIndex:[firstController.index row]], nil];
}
}
- (void) setNameLabel:(NSString *)sender
{
// self.name = sender;
NSLog(#"ran");
}
This is the ChildrenTableViewController.h:
#protocol updateView <NSObject>
#required
- (void) setNameLabel:(NSString *)sender;
#end
#interface ChildrenTableViewController : UITableViewController
{
NSIndexPath *index;
id <updateView> delegate1;
}
#property (nonatomic, strong) NSMutableArray *childname;
#property (nonatomic, strong) NSIndexPath *index;
#property (retain) id delegate1;
#end
This is the critical part of ChildrenTableViewController.m:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[[self delegate1] setNameLabel:[self.childname objectAtIndex:[indexPath row]]];
NSLog(#"rannn");
As you can see in the last code i'm trying to call the method using the protocol function. It doesn't seem to work for some reason, i've put in NSLOG and it doesn't even run the setNameLabel method at all. :( Will appreciate any help offered :)

In the code above I cant see you setting the delegate as so:
- (void)viewDidLoad
{
[super viewDidLoad];
if (firstController == nil) {
firstController = [[ChildrenTableViewController alloc] initWithStyle:UITableViewStyleGrouped];
}
[firstTable setDataSource:firstController];
[firstTable setDelegate:firstController];
firstController.view = firstController.tableView;
// Set up the delegate for the controller
[firstController setDelegate1:self];
// Do any additional setup after loading the view.
}
Also, the delegate property should usually be (weak) rather than (retain).

Related

(iOS) crash when view controller property is set

I've problems passing data to a new view controller.
I've two VC. In the "FirstVC" there is a table view with dynamic prototypes cells. The generic cell contains a label and a button and it's assigned to its own class "GenericCell". I want to pass to the SecondVC the text of the cell label when I press the button, but the app crashes with errors:
Unknown class _TtC13testTableView37SecondVC in Interface Builder file.
UIViewController setMyString:]: unrecognized selector sent to instance 0x7fa05e418110
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController setMyString:]: unrecognized selector sent to instance 0x7fc8add05710
I tried:
To use the segue (with prepareForSegue method) outside the getText method
1a. Pushing the VC from the outside of the getText method
Implementing and calling set/get method of myString
Adding attributes to myString property
but the app crashes the same.
GenericCell.h
#import <UIKit/UIKit.h>
#protocol MyCellDelegate
-(void)getText:(NSString *)text;
#end
#interface GenericCell: UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel * label;
#property (assign, nonatomic) id <MyCellDelegate> delegate;
#end
GenericCell.m
#import "GenericCell.h"
#interface GenericCell()
#end
#implementation GenericCell
- (IBAction)buttonPressed {
if (self.delegate) {
[self.delegate getText:self.label.text];
}
}
#end
FirstVC.m
#import "FirstVC.h"
#import "GenericCell.h"
#import "SecondVC.h"
#interface FirstVC() <UITableViewDataSource,UITableViewDelegate, MyCellDelegate>
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#property NSString * idToPass;
#end
#implementation FirstVC
NSMutableArray<NSString *> *array;
- (void)viewDidLoad {
array = [[NSMutableArray alloc]initWithObjects:#"0x22", #"0x11", #"0x24", nil];
[super viewDidLoad];
self.tableView.dataSource=self;
self.tableView.delegate=self;
self.tableView.rowHeight=100;
}
-(void)getText:(NSString *)text {
self.idToPass = text;
SecondVC * secondVC = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondVC"];
secondVC.myString = self.idToPass;
[[self navigationController] pushViewController:secondVC animated:YES];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return array.count;
}
- (GenericCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
GenericCell * cell = [[self tableView]dequeueReusableCellWithIdentifier:#"GenericCell" forIndexPath:indexPath];
cell.delegate = self;
cell.label.text = [array objectAtIndex:indexPath.row];
return cell;
}
#end
SecondVC.h
#import <UIKit/UIKit.h>
#interface SecondVC : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *label;
#property NSString * myString;
#end
SecondVC.m
#import "SecondVC.h"
#interface SecondVC ()
#end
#implementation SecondVC
- (void)viewDidLoad {
self.label.text = self.myString;
[super viewDidLoad];
}
#end
The "idToPass" is set correctly with delegation.
This work for me: in the buttonPressed method update the if statement like this
if ([self.delegate respondsToSelector:#selector(getText:)]){
[self.delegate getText:self.label.text];
}
Another option to give SecondVC the data is using
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
SecondVC * vc = segue.destinationViewController;
if ([segue.identifier isEqualToString: #"yourSegue"]) {
vc.myString = self.idToPass;
}
}
A tip I suggest is to check (with a simple if statement) if your object in SecondVC is nil or !nil
I hope this help :)
In getText method you assign text to myProperty instead myString...
It should be:
secondVC.myString = self.idToPass;

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.

Objective-C issue with Segue

I have this Segue here:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
//NSDate *object = self.objects[indexPath.row];
NSString *strPOIndex = [self.tableData[indexPath.row] valueForKey:#"POIndex"];
LHPurchaseOrderDetail *controller = (LHPurchaseOrderDetail *)[[segue destinationViewController] topViewController];
[controller setDetailItem:strPOIndex];
controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
controller.navigationItem.leftItemsSupplementBackButton = YES;
}
}
and what I am trying to do with it is pass strPOIndex to setDetailItem in my detail controller from my master controller.. but when I run this, I get an error:
-[LHPurchaseOrderMaster setDetailItem:]: unrecognized selector sent to instance 0x156cce80
I dont understand why this is happening, is it an issue with my storyboard? or my master controller or detail controller? Here is my Detail Controller:
.h:
#import <UIKit/UIKit.h>
#interface LHPurchaseOrderDetail : UIViewController
#property (strong, nonatomic) IBOutlet UINavigationBar *NavBar;
#property (strong, nonatomic) id detailItem;
#property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#end
.m:
#import "LHPurchaseOrderDetail.h"
#interface LHPurchaseOrderDetail ()
#end
#implementation LHPurchaseOrderDetail
- (void)setDetailItem:(id)newDetailItem {
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
}
- (void)configureView {
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = [self.detailItem description];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
[self configureView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#end
Master Controller:
.h
#import <UIKit/UIKit.h>
#import "ShinobiDataSource.h"
#import "PopupGenerator.h"
#class LHPurchaseOrderDetail;
#interface LHPurchaseOrderMaster : UITableViewController<UIPopoverControllerDelegate, UIPickerViewDelegate>
#property (strong, nonatomic) IBOutlet UIButton *communityBtn;
#property (strong, nonatomic) IBOutlet UIButton *lotBtn;
#property (strong, nonatomic) IBOutlet UIButton *goBtn;
- (IBAction)communityBtnPressed:(id)sender;
- (IBAction)lotBtnPressed:(id)sender;
- (IBAction)goBtnPressed:(id)sender;
#property(nonatomic, retain) NSArray * tableData;
#property (strong, nonatomic) LHPurchaseOrderDetail *purchaseOrderController;
#end
Your error is this:
-[LHPurchaseOrderMaster setDetailItem:]: unrecognized selector sent to instance 0x156cce80
so it seems that somewhere in your LHPurchaseOrderMaster class you're trying to access and set the detailItem property as if it would be a part of LHPurchaseOrderMaster but because it doesn't exist there, you get an unrecognized selector error.
Edit
You should check for three things:
In Interface Builder check that the segue from LHPurchaseOrderMaster ViewController is to an UINavigationController that embeds the LHPurchaseOrderDetail ViewController as the first view controller in its stack.
Check the Class name returned by [segue destinationViewController]topViewController] like this:
id obj = [segue destinationViewController]topViewController];
NSLog(#"%#", NSStringFromClass([obj class]));
The class name should be LHPurchaseOrderDetail. If it's not, then you have a problem in your Storyboard where more than certainly you've connected the segue wrong.
Check your LHPurchaseOrderMaster class for any code that tries to access the "detailItem" property as if it would be part of this class.
It seems that the property you are trying to access is not accessible (wrong retrieved object).
Have you tried to use instead of
LHPurchaseOrderDetail *controller = (LHPurchaseOrderDetail *)[[segue destinationViewController] topViewController];
Something like
LHPurchaseOrderDetail *controller = (LHPurchaseOrderDetail *)[[segue destinationViewController] viewControllers][0];
I had sometimes the same your issue.
Set your detailItem not to NSString. Not to id. The problem is here,
self.detailDescriptionLabel.text = [self.detailItem description];
In configureView method change the code as follow,
- (void)configureView {
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = self.detailItem;
}
}
Don't forget to change this as well,
- (void)setDetailItem:(NSString *)newDetailItem {
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
}

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

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