I am creating an UITableView and has a question on how to redirect the user to a new view when the person clicks on the cell. It would helpful if could provide some code and possible an explanation. Thank you :)
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
IBOutlet UIButton *Startbutton;
}
#property (strong,nonatomic) NSArray *array;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Startbutton.layer.cornerRadius = 5; // this value vary as per your desire
Startbutton.clipsToBounds = YES;
//Status Bar
[self setNeedsStatusBarAppearanceUpdate];
//Array
self.array = [[ NSArray alloc]initWithObjects:#"1",#"2",#"3", nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
//Array Main Code
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.array.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}
cell.textLabel.text = [self.array objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
#end
There is a pretty basic way of doing this without having to write code at all, but I am not sure if it is exactly what you want, sorry if it doesn't help.
Drag in a UITableViewController, in the Attributes inspector, select Static Cells from the 'Content' drop down box. Then add how ever many cells you like, click on the cell, then under the attributes inspector change the 'Style' to whatever you like and then change the content of the cell. Then all you have to do to link that cell to a new view is; right click the cell and drag your cursor to the destination view, then Select Modal (or Push if you are in a navigation controller).
That way when you run the app and click on that cell you should be switched to the new view.
No coding is required at all.
Hoped that helped in someway.
Cheers
Related
i have two view controllers, view controller and tableViewController.
ViewController contains a textField and a button. when the button in viewController is clicked, then TableViewController should start.
in TableViewController, there is a list contains 5 rows, each row contains a string value.
What I am trying to do is, hen the user chooses any row in the list in TableViewController, then ViewController scene should start and the value that the user chose should be displayed in the textfield in ViewController.
to achieve this task, I created a protocol in TableViewController with a required method called valueChoosen: (NSString *) value, and this method is implemented in ViewController, and then I set the value to the textField but, at run time the TextField is empty.
please have look at the code below, and let me know why the value passed to the required method of the protocol can not be set to the textfield, what I am doing wrong;
TableViewController:
#import "TableViewController.h"
#interface TableViewController ()
#property NSArray *tableData;
#end
#implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.tableData = [NSArray arrayWithObjects:#"Android",
#"iOS",
#"swift",
#"objective-c",
#"openCV",nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger) tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [self.tableData count];
}
-(UITableViewCell *) tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [self.tableData objectAtIndex:indexPath.row];
cell.imageView.image = [UIImage imageNamed:#"images.jpg"];
return cell;
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath {
NSLog(#"%#", [self.tableData objectAtIndex:indexPath.row]);
[self performSegueWithIdentifier:#"unwindSegue" sender:NULL];
[self.delegate valueChoosen:[self.tableData
objectAtIndex:indexPath.row]];
}
#end
ViewController:
#import "ViewController.h"
#import "TableViewController.h"
#interface ViewController ()
#property (strong, nonatomic) IBOutlet UITextField
*textFieldDepartment;
#property (strong, nonatomic) IBOutlet UIButton
*buttonSelectFromTableView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a
nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"segueToTableView"]) {
//code
TableViewController *table = segue.destinationViewController;
table.delegate = self;
}
}
-(void) valueChoosen: (NSString *) value {
[_textFieldDepartment setText:value];
NSLog(#"value: %#", value);
}
#end
It maybe because you are setting the textfield text in the viewController which is not being displayed. Try assigning the value to a variable using the delegate function and call the delegate function before performing the unwind segue. And on the viewController try setting the textfield text as the variable whose value was set through delegate method from the viewWillAppear method.
Step 1:
create the unwind action in the viewcontroller you want to unwind it.in your case it is ViewController
- (IBAction)unwindFromModalController:(UIStoryboardSegue *)segue{}
Step 2:
Connect to the unwind Action
Control drag from tableviewcell to the Exit sign.
Select the Action you specified.
Add the Identifier to unwind segue.
Step3
Trigger the segue
in your TableViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
self.selectedText = self.tableData[indexPath.row];
[self performSegueWithIdentifier:#"unwindSegue" sender:self];}
Step 4:
Pass Data
Unwind Action
- (IBAction)unwindFromModalController:(UIStoryboardSegue *)segue{
if ([segue.sourceViewController isKindOfClass:[TableViewController class]]) {
TableViewController *vc = segue.sourceViewController;
if (vc.selectedText) {
[_textFieldDepartment setText:vc.selectedText];}
}
}
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 have been trying to implement a simple table view in Xcode. However I have run into this error:
[UIView tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x7fd23bc76bc0
I searched for an answer online, and basically all I could find out was that I'm trying to send that method something that does not exist. If someone could please explain what exactly is going on here, why it is going, and how I might fix it, I would be grateful. Here is the code:
In ViewController.h :
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
}
#end
In ViewController.m :
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
{
NSArray *recipes;
}
- (void)viewDidLoad {
[super viewDidLoad];
recipes = [NSArray arrayWithObjects:#"Eggs", #"Bacon", #"Ham", #"Steak", #"Bread", #"Lettuce", #"Tomatoes", #"Carrots", #"Milk", #"Pizza", #"Chicken", #"Soup", #"Cheese", nil];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [recipes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableID = #"SimpleTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableID];
}
cell.textLabel.text = [recipes objectAtIndex:indexPath.row];
return cell;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
If you need anymore information, I'd be happy to get it to you. Thanks.
It looks like you have dragged the delegate property of the table view onto a UIView instead of the UiViewController.
In the storyboard make sure you drag the delegate property to the controller (yellow circle at the top of the view).
I have a view controller with a static cell named 'Make' I have two controllers one called "AddCarTableViewController" and "MakeTableViewController" when you click on the static cell named 'Make' it presents the make table view controller where you can select the make, then pops the view controller and am trying to store the selected value in the detailTextLabel of the static cell. here is my code for all the controllers.
The problem I'm having is once I select the make everything happens as it should I even log the selected item and it saves it after popping the view controller, but I can't figure out how to implement selected item into the detailTextLabel. Any help will be much appreciated!
"MakeTableViewController.h"
#import <UIKit/UIKit.h>
#import "AddCarTableViewController.h"
#protocol CarMakeDelegate <NSObject>
- (void)updateCarMake:(NSString *)updateMake;
#end
#interface MakeTableViewController : UITableViewController
#property (nonatomic, strong) NSArray *carMakes;
#property (nonatomic, weak) id <CarMakeDelegate> delegate;
#end
MakeTableViewController.m
#import "MakeTableViewController.h"
#interface MakeTableViewController ()
#end
#implementation MakeTableViewController {
NSIndexPath *oldIndexPath;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.carMakes = [[NSArray alloc] initWithObjects:#"Acura", #"Aston Martin", nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (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.carMakes 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 = [self.carMakes objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
oldIndexPath = indexPath;
NSString *addMake = self.carMakes[indexPath.row];
[self.delegate updateCarMake:addMake];
NSLog(#"%#", addMake );
[[self navigationController] popViewControllerAnimated:YES];
}
#end
AddCarTableViewController.h
#import <UIKit/UIKit.h>
#import "MakeTableViewController.h"
#interface AddCarTableViewController : UITableViewController
#property (strong, nonatomic) NSString *makeName;
#property (weak, nonatomic) IBOutlet UITableViewCell *makeCell;
#end
AddCarTableViewController.m
#import "AddCarTableViewController.h"
#interface AddCarTableViewController ()
#end
#implementation AddCarTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark - Table view data source
- (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 4;
}
-(void)updateCarMake:(NSString *)updateMake {
self.makeCell.detailTextLabel.text = updateMake;
}
#end
You don't need to use delegate in this case. Just update the underlying data model. and call
[tableview reloadData];
When the makeViewController is popped.
In the AddCarVC's cellForRowAtIndex, add another line to check if current indexPath corresponds to Make cell and if it does update the detailLabel text.
Hi I'm a newbie to iOS development I'm facing a problem regarding scrolling of custom cells in a tableview. My table view has around 7 cells but once I scroll the view after running I will be getting only first 5 cells like the below but even tough the rest of the cells are being displayed we can't completely scroll to have a look at those cell.
Here's my viewController.m code
#import "ViewController.h"
#import "MobileTableCell.h"
#interface ViewController ()
{
NSArray *tableData;
NSArray *thumbnails;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
tableData = [NSArray arrayWithObjects:#"Iphone 5s",#"Google Nexus 5", #"Samsung Galaxy S4",#"HTC one", #"LG G2", #"Moto X", #"Micromax Turbo", nil];
thumbnails = [NSArray arrayWithObjects:#"iphone5.jpg",#"nexus5.png",#"galaxys4.jpg",#"htcone.jpg",#"lgg2.jpg",#"motox.png",#"micromaxcanvasturbo2.jpg", nil];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableData count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"MyMobileTableCell";
MobileTableCell *cell = (MobileTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
//NSLog(#"%#",cell);
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MobileTableCell" owner:self options:Nil];
cell = [nib objectAtIndex:0];
}
// cell.layer.shouldRasterize = YES;
cell.nameLabel.text = [tableData objectAtIndex:indexPath.row];
cell.thumbnailImageView.image = [UIImage imageNamed:[thumbnails objectAtIndex:indexPath.row]];
return cell;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 78;
}
#end
Please lemme know where I have gone wrong. Thanks in advance.
You are using a UIViewController to render the UITable because you have: #interface ViewController : UIViewController <UItableViewDelegate , UITableViewDataSource>. Better to directly use the UITableViewController provided #interface ViewController : UITableViewController. If you have a valid reason for using a UIView then you need to set the delegate and dataSource to self:
tableView.delegate = self;
tableView.dataSource = self;
You also need to make sure there isn't anything else that is scrollable on the UIView that makes the table view scroll out of the page like a UIScrollView or something like that. You can use auto layout to help keep your stuff in view.
Last point, your issue might be the result of a UINavigationController covering parts of the table. If you are using a UIView you need to add content margin to the UITable to make sure the navigationController does not hide rows.