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...
Related
First of all I want to apologize for my bad english.
I'm having trouble to set the properties of my custom UITableViewCell (HistoricoCell).
When I try to set a property of my cell I get: Signal SIGABRT error:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Dequeue the cell.
HistoricoCell *cell = (HistoricoCell *)[self.tblHistorico dequeueReusableCellWithIdentifier:#"CellIdentifier" forIndexPath:indexPath];
// Fetch Item
NSDictionary *item = [self.dbManager.arrColumnNames objectAtIndex:indexPath.row];
// Configure Table View Cell
[cell.lblCodigo setText:[NSString stringWithFormat:#"%#", item[#"codigo"]]];
[cell.btnFavoritar addTarget:self action:#selector(didTapButton:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
I followed a lot of tutorials and questions on the web but I stil with my error.
Can someone help me?
My code:
HistoricoCell.h
#import <UIKit/UIKit.h>
#interface HistoricoCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel *lblCodigo;
#property (weak, nonatomic) IBOutlet UIButton *btnFavoritar;
#end
SecondViewController.h
#import <UIKit/UIKit.h>
#interface SecondViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *tblHistorico;
SecondViewController.m
#import "SecondViewController.h"
#import "DBManager.h"
#import "HistoricoCell.h"
#interface SecondViewController ()
#property (nonatomic, strong) DBManager *dbManager;
#property (nonatomic, strong) NSArray *arrPeopleInfo;
-(void)loadData;
#end
#implementation SecondViewController
static NSString *CellIdentifier = #"CellIdentifier";
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Make self the delegate and datasource of the table view.
self.tblHistorico.delegate = self;
self.tblHistorico.dataSource = self;
// Initialize the dbManager property.
self.dbManager = [[DBManager alloc] initWithDatabaseFilename:#"bernoullidb.sql"];
[self.tblHistorico registerClass:[HistoricoCell class] forCellReuseIdentifier:#"CellIdentifier"];
[self loadData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)loadData{
// Form the query.
NSString *query = #"select * from tbHistorico";
// Get the results.
if (self.arrPeopleInfo != nil) {
self.arrPeopleInfo = nil;
}
self.arrPeopleInfo = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];
// Reload the table view.
//[self.tblHistorico reloadData];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.arrPeopleInfo.count;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 60.0;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Dequeue the cell.
HistoricoCell *cell = (HistoricoCell *)[self.tblHistorico dequeueReusableCellWithIdentifier:#"CellIdentifier" forIndexPath:indexPath];
// Fetch Item
NSDictionary *item = [self.dbManager.arrColumnNames objectAtIndex:indexPath.row];
// Configure Table View Cell
[cell.lblCodigo setText:[NSString stringWithFormat:#"%#", item[#"codigo"]]];
[cell.btnFavoritar addTarget:self action:#selector(didTapButton:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
- (void)didTapButton:(id)sender {
NSLog(#"%s", __PRETTY_FUNCTION__);
}
#end
You should set cell indentifier "CellIdentifier" for your cell in File Inspector
Or register your nib file if you add cell with nib:
UINib *itemNib = [UINib nibWithNibName:#"yourCell" bundle:nil];
[self.tableView registerNib:itemNib forCellReuseIdentifier:#"yourCellReuseIndentifier"];
I think your problem is in your cell creation: you try to dequeue a cell if it exists (i.e. recycle a previously used cell). that is OK, but, especially when the TableView is displayed for the first time, no previously used cell for this table exists. So, you have to create one if the dequeueReusableCellWithIdentifier call return nil.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Dequeue the cell.
HistoricoCell *cell = (HistoricoCell *)[self.tblHistorico dequeueReusableCellWithIdentifier:#"HistoricoCellIdentifier" forIndexPath:indexPath];
if( cell == nil ) // no queuded cell to dequeue
{
// you have to create a fresh new one
cell = [HistoricoCell alloc] initWithStyle:<your cell style> reuseIdentifier:#"HistoricoCellIdentifier"];
}
// Fetch Item
NSDictionary *item = [self.dbManager.arrColumnNames objectAtIndex:indexPath.row];
// Configure Table View Cell
[cell.lblCodigo setText:[NSString stringWithFormat:#"%#", item[#"codigo"]]];
[cell.btnFavoritar addTarget:self action:#selector(didTapButton:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
I'm just going to be crazy. I want to display some attributes from an object in a TableViewController.
To resume :
I've got a first screen with a list of different Aircraft. Each Aircraft is different and get 2 attributes (a name and an identification number). When i click on an aircraft i want to display its informations in a new view controller (here a TableViewController).
The only thing i get is an empty string... I don't understand how to do this.
Here my code for AircraftViewController.h (the list of different aircraft)
#import <UIKit/UIKit.h>
#import "AircraftInfoViewController.h"
#interface AircraftViewController : UITableViewController <AircraftInfoViewControllerDelegate>
#property (nonatomic, strong) NSMutableArray *aircraft;
#end
Here my code for AircraftViewController.m
#import "AircraftViewController.h"
#import "Aircraft.h"
#interface AircraftViewController ()
#end
#implementation AircraftViewController
{
NSString *_info;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.aircraft count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
AircraftCell *cell = (AircraftCell *)[tableView dequeueReusableCellWithIdentifier:#"AircraftCell"];
Aircraft *aircraft = (self.aircraft)[indexPath.row];
cell.immatLabel.text = aircraft.immat;
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"PickInfo"]) {
AircraftInfoViewController *aircraftInfoViewController = segue.destinationViewController;
aircraftInfoViewController.delegate = self;
aircraftInfoViewController.info = _info;
}
}
- (void)aircraftInfoViewController:(AircraftInfoViewController *)controller didSelectInfo:(NSString *)info
{
_info = info;
Aircraft *aircraft = [[Aircraft alloc] init];
// Here is my problem !
NSLog(#"String is %#", aircraft.name);
[self.navigationController popViewControllerAnimated:YES];
}
#end
Here my Aircraft Object
#import <Foundation/Foundation.h>
#interface Aircraft : NSObject
#property (nonatomic, copy) NSString *name;
#property (nonatomic, copy) NSString *immat;
#end
Here my AircraftInfoViewController.h (where i display info)
#class AircraftInfoViewController;
#protocol AircraftInfoViewControllerDelegate <NSObject>
- (void)aircraftInfoViewController:(AircraftInfoViewController *)controller didSelectInfo:(NSString *)info;
#end
#interface AircraftInfoViewController : UITableViewController
#property (nonatomic, weak) id <AircraftInfoViewControllerDelegate> delegate;
#property (nonatomic, strong) NSString *info;
#end
Here my AircraftInfoViewController.m
#import "AircraftInfoViewController.h"
#interface AircraftInfoViewController ()
#end
#implementation AircraftInfoViewController
{
NSArray *_infos;
NSUInteger _selectedIndex;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_infos = #[#"TEST"];
_selectedIndex = [_infos indexOfObject:self.info];
}
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_infos count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"AircraftCell"];
cell.textLabel.text = _infos[indexPath.row];
if (indexPath.row == _selectedIndex) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (_selectedIndex != NSNotFound) {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:
[NSIndexPath indexPathForRow:_selectedIndex inSection:0]];
cell.accessoryType = UITableViewCellAccessoryNone;
}
_selectedIndex = indexPath.row;
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
NSString *info = _infos[indexPath.row];
[self.delegate aircraftInfoViewController:self didSelectInfo:info];
}
#end
Thx for helping...
I don't exactly get your problem, but in your code you are:
//1. creating a new aircraft
Aircraft *aircraft = [[Aircraft alloc] init];
//2. this aircraft object is new and dose not have a name yet as you never assigned a name to it.
//3. this is why your log shows an empty string
NSLog(#"String is %#", aircraft.name);
Looks like you need to print the info:
NSLog(#"String is %#", _info);
But it will be helpful to help you if you could explain what you want to get better.
I got a button in a tableview cell (named "deleteTemplate"), and when it's pressed i should get the "index.row" for the cell the button is in. Anybody knows how to get the "index.row" for the cell, when you click a button in the cell?
My current code for the button:
UITableViewCell *clickedCell = (UITableViewCell *)[[sender superview] superview];
NSIndexPath *clickedButtonIndexPath = [self.tableView indexPathForCell:clickedCell];
NSDictionary *dic = [tableData objectAtIndex:clickedButtonIndexPath.row];
But clickedButtonIndexPath = NULL? :(
This worked in iOS 6.
Thank you!!!
You are getting null because the view hierarchy in iOS 7 is changed.
I recommend to use Delegate for getting the indexpath of TableViewCell.
You can get the sample project from here
Here is the sample:
My View Controller looks like this:
//#import "ViewController.h"
//#import "MyCustomCell.h"
#interface ViewController ()
{
IBOutlet UITableView *myTableView;
NSMutableArray *dataSourceArray;
}
#end
#implementation ViewController
-(void)viewDidLoad
{
[super viewDidLoad];
dataSourceArray = [[NSMutableArray alloc] init];
for(int i=0;i<20;i++)
[dataSourceArray addObject:[NSString stringWithFormat:#"Dummy-%d",i]];
}
-(void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
//pragma mark - UITableView Delegate And Datasource -
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return dataSourceArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdenfifier = #"MyCustomCell";
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdenfifier forIndexPath:indexPath];
[cell setDelegate:self];
[cell.myButton setTitle:[dataSourceArray objectAtIndex:indexPath.row] forState:UIControlStateNormal];
return cell;
}
//pragma mark - MyCustomCell Delegate -
-(IBAction)myCustomCellButtonTapped:(UITableViewCell *)cell button:(UIButton *)sender
{
NSIndexPath *indexPath = [myTableView indexPathForCell:cell];
NSLog(#"indexpath: %#",indexPath);
}
#end
MyCustomCell.h looks like this:
//#import
#protocol MyCustomCellDelegate
#optional
- (IBAction)myCustomCellButtonTapped:(UITableViewCell *)cell button:(UIButton *)sender;
#end
#interface MyCustomCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UIButton *myButton;
#property(nonatomic, weak)id delegate;
#end
MyCustomCell.m looks like this:
//#import "MyCustomCell.h"
#implementation MyCustomCell
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
}
return self;
}
-(void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
}
//#pragma mark - My IBActions -
-(IBAction)myCustomCellButtonTapped:(UIButton *)sender
{
if([self.delegate respondsToSelector:#selector(myCustomCellButtonTapped:button:)])
[self.delegate myCustomCellButtonTapped:self button:sender];
}
#end
you set tag for your button in cellforrowatindexpath
clickedButtonIndexPath.tag=indexpath.row;
when button is presse in action write
nslog(#"%i",btutton.tag);
if clickedbuttonindexpath is nil it wont uitableviewcell
This question is already answered many times. For completion, here is the best solution:
-(IBAction)cellButtonTapped:(UIButton *)sender
{
CGRect buttonFrame = [sender convertRect:sender.bounds toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonFrame.origin];
}
when you make the cell assign at you button.tag the indexPath.row and when you click the button in your method you have the sender (the button) and you get the indexPath from the sender's tag
I'm creating an iPad app. The root UITableview has a right bar button item in the navigation controller. When you tap the button, it shows a pop over controller. The popover is a UITableViewController. When you tap a cell in the popover, how could I pass the data in that cell and insert it into a cell into the root UITableview? I searched the Apple docs and couldn't find what I needed. Can anyone push me in the right direction?
Roottable.h
#interface Roottable : UITableViewController<PopoverDelegate>
Popover.h
#protocol AthleteSelectPopoverDelegate <NSObject>
#required
-(void)selectedObject:(Object *)newObject;
#end
#property (nonatomic, weak) id<PopoverDelegate> delegate;
#property (readwrite, nonatomic) Object *currentObject;
#end
popover.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_currentObject = [_objectArray objectAtIndex:indexPath.row];
//Notify the delegate if it exists.
if (_delegate != nil) {
[_delegate selectedObject:_currentObject];
}
}
You add data from the selected cell to the main table's data source delegate.
Then that data source should tell the main table that a cell has been inserted at an index path.
I figured it out. Hope I help someone. I'll explain the code first then post it below. Basically, I set the data source of the root table view, "ObjectSelect", as a NSMutableArray called "currentObjectArray". ObjectSelect is also the ObjectSelectPopoverDelegate. Basically, when a cell in the popover is tapped, it adds the object tapped to the "currentObjectArray" and reloads the tableview.
ObjectSelect.h
#import <UIKit/UIKit.h>
#import "ObjectSelectPopover.h"
#interface ObjectSelect : UITableViewController<ObjectSelectPopoverDelegate>
#property (nonatomic, strong) ObjectSelectPopover *objectPicker;
#property (nonatomic, strong) UIPopoverController *objectPickerPopover;
#property (readwrite, nonatomic) Object *currentObject;
#property (nonatomic, strong) NSMutableArray *selectedObjectArray;
#end
ObjectSelect.m
-(void)selectedObject:(Object *)newObject
{
_currentObject = newObject;
if(!_selectedObjectArray){
_selectedObjectArray = [[NSMutableArray alloc] init];
}
if([_selectedObjectArray containsObject:_currentAthlete]){
//lol you don't get added, bub
}
else{
[_selectedObjectArray addObject:_currentObject];
}
[self.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Object *objectTapped = (Object *)[_objectAthleteArray objectAtIndex:indexPath.row];
return cell;
}
ObjectSelectPopover.h
#import <UIKit/UIKit.h>
#import "Object.h"
#protocol ObjectSelectPopoverDelegate <NSObject>
#required
-(void)selectedObject:(Object *)newObject;
#end
#interface ObjectSelectPopover : UITableViewController
#property (nonatomic, weak) id<ObjectSelectPopoverDelegate> delegate;
#property (nonatomic, strong) NSMutableArray *objectArray;
#property (readwrite, nonatomic) Object *currentObject;
#end
ObjectSelectPopover.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_currentObject = [_objectArray objectAtIndex:indexPath.row];
//Notify the delegate if it exists.
if (_delegate != nil) {
[_delegate selectedObject:_currentObject];
}
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
I think you should have a property with a name other than delegate in your popover controller since UITableViewController already has a delegate property for the UITableViewDelegate protocol; maybe masterTable or something.
Then in the selectedObject: implementation in the root UITableView you can do an insert row or add it to the data array and reload the table.
Oops, my bad... #geraldWilliam is right, UITableViewController does not have the delegate property...
What you have seems like it should work... So does the selectedObject: method get called in the delegate? If so, what do you do in that method? If you add the object to the data set (array or dictionary or database) for the root view, insert a row in its tableview (or reload the data), it should work.
Here is some code that works for me. It is not from a popover but from a pushed view but there is no reason that should make a difference:
- (ThingStatus) thingPicker: (ThingPickerTableViewController *) thingPicker didSelectThing: (Thing *) thing {
NSLog( #"Entering %s", __func__ );
// Dismiss the pushed view controller (for you, the popover)
[self.navigationController popViewControllerAnimated: YES];
NSArray *startingList = self.currentCellObjectList;
[self.databaseManager addThing: thing];
NSArray *endingList = self.databaseManager.thingsForTableView;
// Figure out the differences adding made...
DiffResult *changes = [startingList simpleDiffWithArray: endingList];
NSLog( #"%d deletions, %d insertions", changes.deletionCount, changes.insertionCount );
// I only handle insertions in this code... deletions would be similar
__block NSUInteger objIdx = 0;
NSMutableArray *changeableThingList = [startingList mutableCopy];
[changes.insertionIndexes enumerateIndexesUsingBlock: ^( NSUInteger idx, BOOL *stop ) {
NSLog( #" - insert %# at %d", [[changes.insertionObjects objectAtIndex: objIdx] name], idx );
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: idx inSection: 0];
[changeableThingList insertObject: [changes.insertionObjects objectAtIndex: objIdx] atIndex: idx];
self.currentCellObjectList = changeableThingList;
[self.tableView insertRowsAtIndexPaths: [NSArray arrayWithObject: indexPath] withRowAnimation: UITableViewRowAnimationRight];
++objIdx;
}];
[self.databaseManager save];
return [self.databaseManager: thingStatus];
}
Here is some good code to use that may be able to help you.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return self.item.count;
}
-(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];
}
//Get the row
Sport *rowSport = self.sports[indexPath.row];
cell.textLabel.text = rowItem.itemName;
cell.detailTextLabel.text = rowItem.section;
return cell;
}
I hope this will help you.
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);