I have a nib file that I have put inside of this nib a UITableView (grouped), sets the delegate and datasource of the table view to the file's owner, and created an outlet reference to this table view in the table view controller (files owner).
in the TargetsTableViewController i'v just set it up to see something, without some collection, just manually said I want 1 section and 5 rows:
#import "TargetsTableViewController.h"
#interface TargetsTableViewController ()
#end
#implementation TargetsTableViewController
- (id)init {
self = [super initWithNibName:#"TargetsTableViewController" bundle:nil];
if (self) {
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *closeButton = [[UIBarButtonItem alloc]initWithTitle:#"Close" style:UIBarButtonItemStylePlain target:self action:#selector(close)];
self.navigationItem.rightBarButtonItem = closeButton;
}
-(void)close {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (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 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"TargetsTableViewCell" forIndexPath:indexPath];
if (!cell)
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"TargetsTableViewCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
// Configure the cell...
return cell;
}
and I have also a basic nib for a cell.
but when I run it I get this black screen:
does anyone know why is this?
thanks
try set tableview's frame or use some auto layout. You can use tableviewcell without register it. You may seeing the backgroundColor of UIWindow, and you got nothing on view to see, or in another word, a tableview with frame of CGRectZero.
Related
//The tableview is not changing. I have been at this for days. It seems so simple. Thank you for your help
#import "StopsTableViewController.h"
static NSString *MyIdentifier = #"RouteListing";
#interface StopsTableViewController ()
#property (strong, nonatomic) NSArray *TESTARRAY;
#end
#implementation StopsTableViewController
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
//Set the tab bar item's title
self.title = #"Stops";
}
self.stopList = [[API sharedAPI] fetchStopListing];
self.TESTARRAY = #[#"Josh", #"Kyle", #"Nate"];
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:MyIdentifier];
// Adds Segmented Control
[self segmentedView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) segmentedView {
NSArray *segmentedMenu = [NSArray arrayWithObjects:#"All", #"Near Me", nil];
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:segmentedMenu];
[segmentedControl addTarget:self
action:#selector(valueChanged:)
forControlEvents:UIControlEventValueChanged];
segmentedControl.selectedSegmentIndex = 0;
self.navigationItem.titleView = segmentedControl;
}
pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if ([self.segmentedControl selectedSegmentIndex] == 0) {
return [self.stopList count];
}
else {
return [self.TESTARRAY count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:MyIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
if (_segmentedControl.selectedSegmentIndex == 0) {
cell.textLabel.text = [[self.stopList objectAtIndex:indexPath.row] objectForKey:#"stoptitle"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Stop %#", [[self.stopList objectAtIndex:indexPath.row] objectForKey:#"stopnumber"]];
}
else {
cell.textLabel.text = self.TESTARRAY[indexPath.row];
}
return cell;
}
pragma mark - Table view delegate
// In a xib-based application, navigation from a table can be handled in -tableView:didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here, for example:
// Create the next view controller.
StopInfoViewController *detailViewController = [[StopInfoViewController alloc] initWithNibName:#"StopInfoViewController" bundle:nil];
// Pass the selected object to the new view controller.
detailViewController.stopInfo = [[self.stopList objectAtIndex:indexPath.row] objectForKey:#"stopnumber"];
detailViewController.stopName = [[self.stopList objectAtIndex:indexPath.row] objectForKey:#"stoptitle"];
// Push the view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
}
//Function for segmentedView
-(void) valueChanged:(UISegmentedControl *)sender {
[self.tableView reloadData];
NSLog(#"I'm getting called segment number is: %ld", (long)sender.selectedSegmentIndex);
}
#end
Check your datasource array before calling the table reload method and make sure that the array contains new values corresponding to the segment that you have selected.
One thing I always run into when struggle up a table view is connecting the table with the interface using interface builder. Because it sounds like you're getting the data loaded, when the view first loads. But when you call [self.tableView reloadData] without having the connection made to the table, nothing will happen.
I ways forget that super simple step. Hope this helped
Did you set the tableview delegates?
Try putting this in your viewDidLoad function.
[tableView setDelegate:self];
[tableView setDataSource:self];
If you want a fuller explanation, check here:
how to set a tableview delegate
That post also explains how to ensure your class subscribes to the UITableViewDelegate and UITableViewDataSource protocols
Hope that helps.
I am trying to add a TableView as a subview in my RootViewController.The TableView will come from another ViewController(TableViewGeneratorController) instance method.
So,What is the best way to do this?
I have created a TableViewGeneratorController it works fine as a standalone app. Then from my RootViewController I have created one instance of the TableViewGeneratorController and trying to call the instance method prepareField,which will return the TableView. I got the TableView but
numberOfRowsInSection and cellForRowAtIndexPath is not getting called.
TableViewGeneratorController.h
#import <UIKit/UIKit.h>
#interface TableViewGeneratorController:UIViewController<UITableViewDataSource,UITableViewDelegate>
{
UITableView *tableView;
}
#property(strong,nonatomic)UITableView *generatedTbleView;
- (UITableView *)prepareField;
#end
TableViewGeneratorController.m
#import "TableViewGeneratorController.h"
#import "RootViewController.h"
#interface TableViewGeneratorController (){
}
#end
#implementation TableViewGeneratorController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (UITableView *)prepareField
{
tableView = [[UITableView alloc]initWithFrame:CGRectMake(10, 80, 300, 500)];
tableView.dataSource = self;
tableView.delegate = self;
tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
[tableView reloadData];
return tableView;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIndentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIndentifier];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIndentifier];
}
cell.textLabel.text = #"Yes";
return cell;
}
#end
RootViewController.m
Here I am trying to add the TableView as a subview.
TableViewGeneratorController *tableViewGeneratorController = [[TableViewGeneratorController alloc]initWithNibName:#"TableViewGeneratorController" bundle:nil];
UITableView *tv = [tableViewGeneratorController prepareField];
[self.view addSubview: tv];
What is the problem going on?
Thanks
What you are doing is not really the proper way.
The immediate issue is that the TableViewGeneratorController instance that you create goes out of scope and is deallocated. This leaves the table view with not existing data source or delegate. A simple workaround is to assign the TableViewGeneratorController instance to an instance variable instead of a local variable.
But the proper solution is to embed the TableViewGeneratorController as a child controller of the root view controller.
Change TableViewGeneratorController to be a UITableViewController and get rid of the prepareField method.
Then when you create the TableViewGeneratorController, you add it as a child controller. See the docs for UIViewController for details.
I have a UITableView which contains an array of 3 items. Upon user selection, I need each of these three items to segue to a different UITableView. For example:
First Scene is the table which contains the list: Weather, Intelligence, Fuels Status
Second scene would be:
For when a user selects weather, segue to a table which contains the array "daily maps, fire potential, etc."
For when a user selects intelligence, segue to a table which contains the array "current active fires, new initial attacks, etc."
and so forth.
I have been told I could use different UITableViewCells for each prototype cell but I'm sure there is an easier way that I am simply not grasping. All current segues were done in storyboard. Could someone please elaborate on how I should be segueing from scene to scene (at a beginner-intermediate level of understanding)?
Root
#import "PSMenu_TableViewController.h"
#import "WXMenu_TableViewController.h"
#import "PSTableViewCell.h"
#interface PSMenu_TableViewController ()
#end
#implementation PSMenu_TableViewController
#synthesize PSMenuImage = _PSMenuImage;
#synthesize PSMenuText = _PSMenuText;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.PSMenuText = [[NSArray alloc]
initWithObjects:#"Weather",
#"Intelligence",
#"Fuels Status",
nil];
self.PSMenuImage = [[NSArray alloc]
initWithObjects:#"RMACC_114x114.png",
#"RMACC_114x114.png",
#"RMACC_114x114.png",
nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (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 [_PSMenuText count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"rootTableCell";
PSTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == 0) {
cell = [[PSTableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// Configure the cell...
cell.rootLabel.text = [self.PSMenuText
objectAtIndex: [indexPath row]];
UIImage *rootPhoto = [UIImage imageNamed:
[self.PSMenuImage objectAtIndex: [indexPath row]]];
cell.rootImage.image = rootPhoto;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Use indexPath to retrieve info that needs to be passed along to next view controller
[self performSegueWithIdentifier:#"getWeather" sender:self];
}
#end
One of the .m files I am trying to segue to:
#import "WXMenu_TableViewController.h"
#import "DWO_TableViewController.h"
#interface WXMenu_TableViewController ()
#end
#implementation WXMenu_TableViewController
{
//Define array for weather products list
NSArray *allwx;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//Define the weather products list
allwx = [NSArray arrayWithObjects:#"Daily Weather", #"Fire Potential", #"Multi-Media Briefing", #"Sig. Fire Potential",#"Seasonal Outlook", #"Fire Season Broadcast", nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Set table size to one section.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//When Weather is clicked on previous VC, the allwx list is displayed
if ([_weathertable isEqualToString:#"Weather"]) {
return [allwx count];
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *pstableID = #"MainCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:pstableID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:pstableID];
}
if ([_weathertable isEqualToString:#"Weather"]) {
cell.textLabel.text = [allwx objectAtIndex:indexPath.row];
}
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
if ([segue.identifier isEqualToString:#"showDWODetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DWO_TableViewController *destViewController = segue.destinationViewController;
destViewController.dailywxtable = [allwx objectAtIndex:indexPath.row];
destViewController.title = destViewController.dailywxtable;
}
}
#end
You can segue to a single UITableViewController here and make it display respective contents according to the category chosen. This might help you.
In your Destination View Controller, you can declare a variable and use it in your prepareForSegue method as shown to identify what type of content do you want to see on your destination view controller.
destController.varName = #"setYourTypeHere";
Now you can also set the variable value here based on the Row you are clicking in your tableview.
And in your Destination View controller, you can check this value using switch or if...else cases and bind the appropriate data as per your requirement.
In storyboard you wire up each destination not to the prototype tableview cell, but to the view controller itself (little yellow box on left side of the title bar of the view controller in the storyboard).
Name each segue with a meaningful name, and then in your "didSelect" delegate method you can perform a segue using:
[self performSegueWithIdentifier:#"myNamedSegue" sender:self];
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.
in my application i am using storyboards. In the storyboard i have used the default view controller for login and created another view controller name Inventory. In the new view controller i am using a table view. The table is displaying but the delegate and datasource methods are not being called. I have tried many solutions but i dint understand the problem.The code i used is:
#import <UIKit/UIKit.h>
#interface InventoryViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#end
the implementation file is:
#import "InventoryViewController.h"
#import "customCell.h"
#interface InventoryViewController ()
#end
#implementation InventoryViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor blueColor];
UITableView *table = [[UITableView alloc] initWithFrame:CGRectMake(0, 110, 320, 350)];
table.delegate = self;
table.dataSource = self;
[self.view addSubview:table];
[table relaodData];
}
- (IBAction)Logout:(id)sender {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"Login"];
[self.navigationController pushViewController:vc animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UITableViewDelegate Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"hello");
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
customCell *cell = [tableView dequeueReusableCellWithIdentifier:#"customcell"];
if (cell == nil)
{
cell = [[customCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"customcell"];
}
// Here we use the provided setImageWithURL: method to load the web image
// Ensure you use a placeholder image otherwise cells will be initialized with no image
cell.item_image.image = [UIImage imageNamed:#"ipad_strip_logo.png"];
cell.type.text = #"electronics";
cell.name.text = [NSString stringWithFormat:#"my object %d",indexPath.row];
return cell;
}
#end
You need to apply -reloadData: method after setting deledate, datasource and datasource array.
reloadData
Reloads the rows and sections of the receiver.
- (void)reloadData
Discussion
Call this method to reload all the data that is used to construct the table, including cells, section headers and footers, index arrays, and so on. For efficiency, the table view redisplays only those rows that are visible. It adjusts offsets if the table shrinks as a result of the reload. The table view's delegate or data source calls this method when it wants the table view to completely reload its data. It should not be called in the methods that insert or delete rows, especially within an animation block implemented with calls to beginUpdates and endUpdates
Go through this doc https://developer.apple.com/library/ios/documentation/uikit/reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/reloadData