I am making an app where I have to pass a value from a second class to a first class. I have created a delegate method for that in second class.
In second class I have a UITextField, and if enter any text in this textfield it should be passed to a cell in a UITableView in first view.
However, in my case the value is not being passed properly. What have I done wrong?
This is my code:
second.h
#import <UIKit/UIKit.h>
#protocol secondDelegate<NSObject>
#required
- (void)setsecond:(NSString *)inputString;
#end
#interface second : UIViewController {
IBOutlet UITextField *secondtextfield;
id<secondDelegate>stringdelegate;
NSString *favoriteColorString;
}
#property (nonatomic, retain) UITextField *secondtextfield;
#property (nonatomic, assign) id<secondDelegate>stringdelegate;
#property (nonatomic, copy) NSString *favoriteColorString;
#end
second.m
#import "second.h"
#implementation second
#synthesize stringdelegate, secondtextfield, favoriteColorString;
- (void)viewWillDisappear:(BOOL)animated {
[[self stringdelegate] setsecond:secondtextfield.text];
favoriteColorString=secondtextfield.text;
NSLog(#"thuis check:%#", favoriteColorString);
}
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
[theTextField resignFirstResponder];
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
//[[self stringdelegate] setsecond:secondtextfield.text];
//favoriteColorString = secondtextfield.text;
//NSLog(#"thuis check:%#", favoriteColorString);
}
#end
first.h
#import <UIKit/UIKit.h>
#import "second.h"
#import "TextviewExampleAppDelegate.h"
#interface first : UITableViewController<secondDelegate> {
//TextviewExampleAppDelegate *app;
TextviewExampleAppDelegate *check;
}
first.m
#implementation first
- (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] autorelease];
}
// Configure the cell...
cell.textLabel.text = #"message";
cell.detailTextLabel.text = check.favoriteColorString;
NSLog(#"this second check:%#", check.favoriteColorString);
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
second *viewtwo = [[second alloc] initWithNibName:#"second" bundle:nil];
//viewtwo.favoriteColorString = indexPath;
viewtwo.stringdelegate = self;
[self.navigationController pushViewController:viewtwo animated:YES];
[viewtwo release];
}
- (void)setsecond:(NSString *)inputString {
if (nil != self.stringdelegate) {
[self.stringdelegate setsecond:inputString];
}
[self.tableView reloadData];
}
#end
remove delegate methods.
import your second class to first one.
in 2nd class import first class and implement id firstClass variable there.
when you pushing 2nd class, set id from (3) to self.
when you'v done and ready to pass it, set firstClass.passedValue = passingValue
pop second class
for example:
//first.h:
#import "second.h"
#class second
//second.h:
#import "first.h"
#class first
...
id firstClass;
//first.m:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
second *viewtwo =[[second alloc]initWithNibName:#"second" bundle:nil];
[self.navigationController pushViewController:viewtwo animated:YES];
viewtwo.firstClass = self;
[viewtwo release];
}
//second.m:
firstClass.passedValue = self.passingValue;
Please refer following rough scratch:
in application delegate .h
Create variable
NSString *varStr;
Assign Property
#propery (nonatomic, retain) NSString *valStr;
In delegate .m
#synthesize varStr;
initialize var
varStr = [NSString strinWithFormat:#"Hi"];
in First class
create delegate var;
delegate class *var = (delegate class*)[[UIApplication sharedApplication] delegate];
set value
var.varStr = [NSString strinWithFormat:#"First"];
get value
NSLog (#"%#",var.varStr);
in Second class
create delegate var;
delegate class *var = (delegate class*)[[UIApplication sharedApplication] delegate];
set value
var.varStr = [NSString strinWithFormat:#"Second"];
get value
NSLog (#"%#",var.varStr);
Related
I have a UIViewController and a UITableViewController.
In ViewController I have a UIButton and UITextfield, when I press button it will navigate to TableViewController with static data in the tableview like (iPhone 5S, iPhone 6, iPhone 6S, iPhone 7), when I select any of the row it should be displayed in the textfield of ViewController. Tried but cannot get this one. Help me to solve this. below is my code:
ViewController.h
————————————————
#import <UIKit/UIKit.h>
#import "Utility.h"
#interface ViewController : UIViewController
- (IBAction)oneButtonClicked:(id)sender;
#property (strong, nonatomic) IBOutlet UITextField *txtOne;
ViewController.m
————————————————
//Can't understand what to do in this viewcontroller.
TableViewController.h
—————————————————————-
#import <UIKit/UIKit.h>
#import "Utility.h"
#interface FamilyDetailsViewController : UITableViewController
#end
TableViewController.m
—————————————————————-
#import "FamilyDetailsViewController.h"
#interface FamilyDetailsViewController ()
{
NSArray *arr;
}
#end
#implementation FamilyDetailsViewController
- (void)viewDidLoad {
[super viewDidLoad];
arr=[[NSArray alloc]initWithObjects:#"Parent",#"Grandparent",#"Sibling",#"Child",#"Other", nil];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [arr count];
}
- (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];
}
cell.textLabel.text=[arr objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.navigationController popViewControllerAnimated:YES];
}
in `ViewControllerB.h` which is a TableViewController declare a delegate to pass the data to ViewControllerA and create a delegate object
#import <UIKit/UIKit.h>
#protocol DataDelegate <NSObject>
- (void)passData:(NSString *)data;
#end
#interface ViewControllerB : UIViewController
#property (weak, nonatomic) id<DataDelegate> delegate;
#end
in ViewControllerB.m file
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *selectedText = titleArray[indexPath.row];
if [self.delegate respondsToSelector:#selector(passData:)]) {
[self.delegate passData:"hello"];
}
[self.navigationController popViewControllerAnimated:YES];
}
**in ViewControllerA**
#import "ViewControllerA.h"
#import "ViewControllerB.h"
#interface ViewControllerA () <DataDelegate>
#property (strong, nonatomic) ViewControllerB *viewControllerB;
#end
#implementation ViewControllerA
- (void)viewDidLoad {
_viewControllerB.delegate = self;
}
- (void)passData:(NSString *)data {
self.textField.text = data
}
Try Using NSNotification. Pass data back to ViewController with NSNotification. First register a notification in viewWillAppear of ViewController.
Try below code:
In ViewController:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(getTextFromTable:) name:#"PassTextBackToViewController" object:nil];
}
Then define Method in ViewController like this:
-(void)getTextFromTable:(NSNotification *)notification
{
[self.textField setText:[notification.userInfo valueForKey:#"cellText"]];
}
And in tableView's didSelectRowAtIndexPath method, Post the notification:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell=[tableView cellForRowAtIndexPath:indexPath];
NSDictionary *dictionary=[NSDictionary dictionaryWithObjectsAndKeys:cell.textLabel.text,#"cellText", nil]
[[NSNotificationCenter defaultCenter]postNotificationName:#"PassTextBackToViewController" object:dictionary];
[self.navigationController popViewControllerAnimated:YES];
}
Make Sure, Notification's name must be same in both ViewController and
TableViewController
Follow this:
In AppDelegate.h
#property (strong, nonatomic) NSString *selectedText;
In ViewController.m
-(void)viewWillAppear:(BOOL)animated
{
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
txtOne.text = appDelegate.selectedText;
}
Make appDelegate.selectedText = #"" while navigating to UITableViewController Class.
In FamilyDetailsViewController.m
pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *selected= [arr objectAtIndex:indexPath.row];
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
appDelegate.selectedText = selected;
[self.navigationController popViewControllerAnimated:YES];
}
In this way you are storing selected value in Singleton class.(App delegate). You can fetch data from this in ViewController(viewWillAppear).
I have a UITableViewController with many UITableViewCell. Each Cell have a UISwitch Button.
Here is my UITableViewController Class:
#implementation DanhsachTableViewController{
NSMutableArray *data;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self loadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DichVu2TableViewCell *cell = (DichVu2TableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"dscell"];
NSDictionary *dataCell = data[indexPath.row];
cell.service = dataCell[#"service"];
cell.package = dataCell[#"package"];
cell.loai_goi = dataCell[#"loai_goi"];
return cell;
}
-(void) changeCellState:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi{
for (int i =0;i<data.count;i++){
DichVu2TableViewCell *cellLocal = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
if ([service isEqualToString:cellLocal.service] && ![package isEqualToString:cellLocal.package] && [loai_goi isEqualToString:cellLocal.loai_goi]){
[cellLocal.sudung setOn:NO animated:YES];
}
}
}
"Data" array was loaded in method loadData (not important here so I don't include it).
In UITableViewCell (class name: DichVu2TableViewCell), I set event Value Change of Switch so that each time a Switch change value (ON for example), all other cell's switch which have the same value "service" and "loai_goi" will be set OFF.
DanhsachTableViewController *tableview = [[DanhsachTableViewController alloc] init];
tableview.tableView.delegate = (DanhsachTableViewController *)self.superview.superview;
[tableview changeCellState:_service package:_package loaigoi:_loai_goi];
But when I call, the array "data" of above tableview have 0 object so nothing happened.
Is there any way to do that?
Hi Oyeoj,
Thanks for your help.
I have a little problem when followed your guide. There are some error in xcode when I use extract your code so I have to customize. But the program still has error when running. Would you please help me review my code. Thanks in advance.
DichVu2TableViewCell.h
#class DichVu2TableViewCell;
//Change : NSObject to <NSObject> because XCode 6.3 has error.
#protocol DichVu2TableViewCellDelegate <NSObject>
-(void)changeCell:(DichVu2TableViewCell *)sender state:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi;
#end
#interface DichVu2TableViewCell : UITableViewCell
#property (weak) id <DichVu2TableViewCellDelegate> delegate;
#end
DichVu2TableViewCell.m
#implementation DichVu2TableViewCell
….
- (void)someSwitchingEvent
{
[self.delegate changeCell:self state:_service package:_package loaigoi:_loai_goi];
}
#end
DanhsachTableViewController.h
#interface DanhsachTableViewController : UITableViewController
#property (strong,nonatomic) NSString *loaitb;
#property (strong,nonatomic) NSString *type;
#property (strong,nonatomic) NSString *name;
#property NSMutableArray *pre_inuse_;
#property NSMutableArray *data_inuse_;
#property NSMutableArray *vas_inuse_;
#end
DanhsachTableViewController.m
#import "DichVu2TableViewCell.h"
//Change <DichVu2TableViewCellDelegate> to (DichVu2TableViewCellDelegate) because XCode 6.3 has error.
#interface DanhsachTableViewController (DichVu2TableViewCellDelegate)
#property (nonatomic) NSIndexPath *forUpdateIndexPath;
#end
#implementation DanhsachTableViewController{
NSMutableArray *data;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DichVu2TableViewCell *cell = (DichVu2TableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"dscell"];
NSDictionary *dataCell = data[indexPath.row];
cell.service = dataCell[#"service"];
cell.package = dataCell[#"package"];
cell.loai_goi = dataCell[#"loai_goi"];
cell.kieu_goi = dataCell[#"kieu_goi"];
[cell.sudung setOn:NO animated:YES];
cell.delegate = self;
//Change cellLocal —> cell because there are no cellLocal avaiable. And Program error when run to this row.
[cell.sudung setOn:(self.forUpdateIndexPath == indexPath) animated:YES];
return cell;
}
-(void)changeCell:(DichVu2TableViewCell *)sender state:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi
{
//Add cellLocal —> cell because there are no cellLocal avaiable
DichVu2TableViewCell *cellLocal = (DichVu2TableViewCell *)[self.tableView cellForRowAtIndexPath:self.forUpdateIndexPath];
if ([service isEqualToString:cellLocal.service] && ![package isEqualToString:cellLocal.package] && [loai_goi isEqualToString:cellLocal.loai_goi]){
// get the indexPath of the cell
self.forUpdateIndexPath = [self.tableView indexPathForCell:sender];
// update the date source
NSMutableDictionary *dataCell = [data[self.forUpdateIndexPath.row] mutableCopy];
[dataCell setObject:service forKey:#"service"];
[dataCell setObject:package forKey:#"package"];
[dataCell setObject:loai_goi forKey:#"loai_goi"];
// you dont need the for-statement just reload the table
[self.tableView reloadData];
// then update the switch inside `- cellForRowAtIndexPath`
}
}
A more efficient method would be to use custom delegates.
You can declare a protocol in your UITableViewController class.
Declare the changeCellState function in the protocol.
Create a delegate property in the UITableViewCell class.
Call the delegate method from the UITableViewCell class when the switch value is changed.
The UITableViewController will itself receive the message, and the function will be called respectively.
Have you tried logging self.superview.superview; ? are your sure is in type UIViewController?
if so:
Do not call [[DanhsachTableViewController alloc]
instead use the DanhsachTableViewController from your parentview
DanhsachTableViewController *tableview = (DanhsachTableViewController *)self.superview.superview;
[tableview changeCellState:_service package:_package loaigoi:_loai_goi];
This
DanhsachTableViewController *tableview = [[DanhsachTableViewController alloc] init]; assigns a new DanhsachTableViewController class and not the existing one.
Edit
USING protocol and delegate
When using delegate you dont need the self.superview.superview :)
UNDER DichVu2TableViewCell
#class DichVu2TableViewCell;
#protocol DichVu2TableViewCellDelegate <NSObject>
-(void)changeCell:(DichVu2TableViewCell *)sender state:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi;
#end
#interface DichVu2TableViewCell : UIViewController
#property (weak) id <DichVu2TableViewCellDelegate> delegate;
#end
#implementaion DichVu2TableViewCell
..
- (void)someSwitchingEvent
{
[self.delegate changeCell:self state:_service package:_package loaigoi:_loai_goi];
}
#end
while
UNDER DanhsachTableViewController
// assuming you alreading imported the `DichVu2TableViewCell` like
//
// #import "DichVu2TableViewCell.h"
//
// set the delegate
#interface DanhsachTableViewController () <DichVu2TableViewCellDelegate>
#property (nonatomic) NSIndexPath *forUpdateIndexPath;
#end
// then implement the method from the delegate under implementation file
#implementation DanhsachTableViewController
{
NSMutableArray *data;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DichVu2TableViewCell *cell = (DichVu2TableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"dscell"];
NSDictionary *dataCell = data[indexPath.row];
cell.service = dataCell[#"service"];
cell.package = dataCell[#"package"];
cell.loai_goi = dataCell[#"loai_goi"];
// this is the magic .. :)
//--
cell.delegate = self;
[cell.sudung setOn:(self.forUpdateIndexPath == indexPath) animated:YES];
//--
return cell;
}
-(void)changeCell:(DichVu2TableViewCell *)sender state:(NSString *)service package:(NSString *)package loaigoi:(NSString *)loai_goi
{
// `self.forUpdateIndexPath` is declared as property
if ([service isEqualToString:service] && ![package isEqualToString:package] && [loai_goi isEqualToString:loai_goi]){
// get the indexPath of the cell
self.forUpdateIndexPath = [self.tableView indexPathForCell:sender];
// update the date source
NSMutableDictionary *dataCell = [data[self.forUpdateIndexPath.row] mutableCopy];
[dataCell setObject:service forKey:#"service"];
[dataCell setObject:package forKey:#"package"];
[dataCell setObject:loai_goi forKey:#"loai_goi"];
// you dont need the for-statement just reload the table
[self.tableView reloadData];
// then the switch will be updated inside `- cellForRowAtIndexPath`
}
}
Hope this is more helpful now.. :) Cheers...
i have problem to display selected data into detaillabeltext in one of my row of section, beside reload the whole table view any other method to reload only certain row of section?
//RootViewController.m (parent controller)
-(void) selectedData:(NSString*) text
{
selectedAbsenceType = text;
NSLog(#"the absence type select is %#",text);
}
-(void) (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
if (indexPath.section == 0)
{
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
NSDictionary *dictionary = [dataArray objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:#"data"];
NSString *cellValue = [array objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
if([cellValue isEqual: #"Absence Type"])
{
cell.detailTextLabel.text = selectedAbsenceType;
}
else if([cellValue isEqual:#"Start Date"])
{
cell.detailTextLabel.text = selectedDate;
}
return cell;
}
===========================================================================================
i have a problem when i calling the method of the protocol, it keep prompt me a ARC Semantic Issue at this statement
[self.delegate selectedData: (NSString*) [self.absenceTypes objectAtIndex:indexPath.row]];:
//child.h
#import <UIKit/UIKit.h>
#protocol childViewControllerDelegate;
#interface AbsenceTypesViewController : UITableViewController
{
id<childViewControllerDelegate>delegate;
}
#property (nonatomic,weak) id<childViewControllerDelegate> delegate;
#property NSArray *absenceTypes;
#end
#protocol childViewControllerDelegate <NSObject>
-(void) selectedData:(NSString*) text;
#end
//child.m
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *selectedCell = nil;
selectedCell = [self.absenceTypes objectAtIndex:indexPath.row];
[self.delegate selectedData: (NSString*) [self.absenceTypes objectAtIndex:indexPath.row]];
//[self.navigationController popViewControllerAnimated:YES];
NSLog(#"%#", selectedCell);
}
Remove {
id<childViewControllerDelegate>delegate;
} inside user class interface.id<childViewControllerDelegate>delegate; means strong variable which will be released only when holding object is released. But in property declaration you are mentioning delegate as weak property. Hence the ARC Semantic is giving you warning. You can also make the delegate weak by declaring it as weak explicitly like __weak id<childViewControllerDelegate>delegate;
Try replacing the .h file content with this.
#import <UIKit/UIKit.h>
#class AbsenceTypesViewController;
#protocol childViewControllerDelegate <NSObject>
-(void) selectedData:(NSString*) text;
#end
#interface AbsenceTypesViewController : UITableViewController
{
id<childViewControllerDelegate>delegate;
}
#property (nonatomic,weak) id<childViewControllerDelegate> delegate;
#property NSArray *absenceTypes;
#end
So that you have forward declaration of class.
You can save all selected option of second view controller in NSMutable Array and save all components separated by comma and send this array to your parent controller.
NSMutableArray *selectedVal =[[NSMutableArray alloc] init];
FirstViewController *FVC = (FirstViewController*)
if ([FVC isKindOfClass:[FirstViewController class]])
{
[FVC setSelectedOption:[selectedVal componentsJoinedByString:#","]];
}
[self.navigationController popViewControllerAnimated:YES];
I have two view controllers in tab bar controller. ViewControllerA has two buttons (MybuttonA and MybuttonB with enabled box unchecked in storyboard). ViewControllerB is a TableViewController. I would like to enable buttons in ViewControllerA upon selecting specific rows in ViewControllerB table.
Greatly appreciate any help...
ViewControllerA.h
#import <UIKit/UIKit.h>
#interface ViewControllerA : UIViewController {
IBOutlet UIButton * MybuttonA;
IBOutlet UIButton * MybuttonB;
}
-(IBAction)mybuttonaction:(id)sender;
#property(strong,nonatomic)UIButton *MybuttonA;
#property(strong,nonatomic)UIButton *MybuttonB;
#end
ViewControllerA.m
#import "ViewControllerA.h"
#interface ViewControllerA ()
#end
#implementation ViewControllerA
#synthesize MybuttonA;
#synthesize MybuttonB;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
-(IBAction)mybuttonaction:(id)sender{
NSString * link = #"https://google.com";
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:link]];
}
ViewControllerB.h
#import <UIKit/UIKit.h>
#import "ViewControllerA.h"
#interface ViewControllerB : UITableViewController{
ViewControllerA *viewcontrollerA;
}
#property (nonatomic, retain) ViewControllerA *viewcontrollerA;
#end
ViewControllerB.m
#import "ViewControllerB.h"
#import "ViewControllerA.h"
#interface ViewControllerB () {
}
#end
#implementation ViewControllerB
#synthesize viewcontrollerA;
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"CONTENTS";
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:#selector(reload) forControlEvents:UIControlEventValueChanged];
[self reload];
[self.refreshControl beginRefreshing];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{return 1;}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
{return 5;}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat: #"Cell #%d", indexPath.row];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSString* value = [tableView cellForRowAtIndexPath:indexPath].textLabel.text;
if ([value isEqual:#"1"]){
viewcontrollerA.MybuttonA.enabled=YES;
}
else if ([value isEqual:#"2"])
{
viewcontrollerA.MybuttonB.enabled=YES;
}
}
else {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
}
#end
In ViewControllerB, add the following line to viewDidLoad:
viewControllerA = [self.tabBarController.viewControllers objectAtIndex:0];
Then, the rest of your code should work as you have it.
Note that you should generally use self.viewControllerA instead of accessing the iVar directly unless you have a good reason for it. :-)
So I am trying to display a UITableView inside a UIPopoverController using the piece of code shown below
vc = [[ActionsViewController alloc] init];
initWithContentViewController:vc];
actionsController = [[UIPopoverController alloc] initWithContentViewController:vc];
actionsController.delegate = self;
NSLog(#"Try to sho it ");
[actionsController presentPopoverFromBarButtonItem:(UIBarButtonItem*)sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
And this is ActionsViewController.m which is a subclass of UITableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray* list = [[NSMutableArray alloc] initWithCapacity:4];
self.actionList = list;
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, 400.0);
[self.actionList addObject:#"Print as book"];
[self.actionList addObject:#"Print page"];
[self.actionList addObject:#"Save Page"];
[self.actionList addObject:#"Share"];
}
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog(#"in number of section");
return 1;
}
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString* lab = [self.actionList objectAtIndex:indexPath.row];
NSLog(#"here in there");
cell.textLabel.text = lab;
return cell;
}
- (NSInteger)numberOfRowsInSection:(NSInteger)section
{
return [self.actionList count];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.delegate != nil) {
[self.delegate actionSelected:indexPath.row];
}
}
The corresponding .h file
#import <UIKit/UIKit.h>
#protocol KLActionsViewControllerDelegate
- (void)actionSelected:(NSInteger)index;
#end
#interface KLActionsViewController : UITableViewController <UITableViewDataSource,UITableViewDelegate>
#property (nonatomic, retain) NSMutableArray* actionList;
#property (nonatomic, assign) id<KLActionsViewControllerDelegate> delegate;
#end
Also, I don't think the functions cellForRowAtIndexPath and numberOfSectionsInTableView are getting called because I don't see any console output.
EDIT: This is what I see in the popover
:
In viewDidLoad I added self.tableView = [[UITableView alloc] init]
I guess, the problem would be in that line:
vc = [[ActionsViewController alloc] init];
if you have a NIB file, you should load the UIViewController with using it.
vc = [[ActionsViewController alloc] initWithNibName:#"ActionViewController" bundle:nil];
// the NibName must be the exact name of XIB file without extension.
OR/AND
you should set the popoverContentSize:
[actionController setPopoverContentSize:vc.view.frame.size];
I hope it helps a bit for you.
UPDATE:
it seems it is not an UIPopoverController problem, just a simple UITableViewController delegate issue.
in that line:
actionsController.delegate = self;
you should set that class as delegate which implements the UITableViewDelegate. basically it is the UITableViewController itself like
actionsController.delegate = actionController;
therefore you should not replace this in that case if you haven't implemented the delegate callback methods in the self which the new delegate class is. you simple steal the chance from the class which was really delegated to answer the callbacks, and in you new delegate class you don't answer the callbacks.
this would be the reason why you are seeing the empty table, without the datas.
You need to load the table view via (last line of viewdidload :
[self.tableView reloadData];
that will trigger the table view methods to action. Put a breakpoint in the various tableview methods particularly in -
(NSInteger)numberOfRowsInSection:(NSInteger)section
{
return [self.actionList count];
}
If this does not get called your tableview is not loaded.
UITableViewController is implicit set datasource and delegate, there is no need to set explicitly datasource and delegate.
Remove UITableViewDataSource,UITableViewDelegate from .h file
#import <UIKit/UIKit.h>
#protocol KLActionsViewControllerDelegate
- (void)actionSelected:(NSInteger)index;
#end
#interface KLActionsViewController : UITableViewController
#property (nonatomic, retain) NSMutableArray* actionList;
#property (nonatomic, assign) id<KLActionsViewControllerDelegate> delegate;
#end
and also remove this line **actionsController.delegate = self;
vc = [[ActionsViewController alloc] init];
actionsController = [[UIPopoverController alloc] initWithContentViewController:vc];
[actionsController presentPopoverFromBarButtonItem:(UIBarButtonItem*)sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];