I'm having a weird bug in my app that uses a sidebar menu with a UITableView to list buttons to navigate. When I start my app, everything looks fine and is in the correct place.
Once I make a selection to the respective viewController, and navigate back to sidebar menu theUITableView` is shifted down about 1 inch.
If I press the sidebar menu button to close it, the menu resets and everything works and looks normal. This bug only happens once, once I select an row, navigate back to it, close it, the UITableView will be in the correct position until the user hard restarts the app. Any idea whats going on?
Here is my code for the sidebar menu:
#import "SideBarViewController.h"
#interface SideBarViewController ()
#end
#implementation SideBarViewController
#synthesize controllerArray, sidebarButton;
- (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.
controllerArray = [NSArray arrayWithObjects:#"Search For Games", #"Login", #"Library", nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [controllerArray 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 = [controllerArray objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIViewController *selection;
if (indexPath.row == 0) {
selection = [self.storyboard instantiateViewControllerWithIdentifier:#"SearchController"];
[self.navigationController pushViewController:selection animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
else if (indexPath.row == 1) {
selection = [self.storyboard instantiateViewControllerWithIdentifier:#"LoginController"];
[self.navigationController pushViewController:selection animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
else if (indexPath.row == 2) {
selection = [self.storyboard instantiateViewControllerWithIdentifier:#"LibraryController"];
[self.navigationController pushViewController:selection animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
}
I followed the tutorial on the "Ray Wenderlich" website for sidebar code.
Also, I've tested other objects, such as buttons and labels and they do not move, its only the UITableView that shifts.
Thanks!
I found the solution! It had to do with the setting for the Navigation controller. Credit due here.
Container View getting pushed down as if it had a UINavigationBar?
You need to check and see if "Translucent" is checked under the Navigation Bar settings.
Try adding self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0); to viewDidLoad. This could be a solution if your app is adding insets automatically.
Try setting self.automaticallyAdjustsScrollViewInsets = NO in your view controller.
Try setting the edgesForExtendedLayout to UIRectEdgeNone.
Hope it helps.
Related
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.
I have a tableview with dynamic prototypes content. I want to call for a specific ViewController programatically when a dynamic cell tap. I used SWRevealViewController calls for my project.
When I tap on cell one with #"l1" identifier I want to load main view controller with sw_front , used in SWRevealViewController. I cannot use controll+drag becaue in her I have use tabviewcontrller. When I do that it disappear the tab bar.
#import "ListViewController.h"
#interface ListViewController ()
#end
#implementation ListViewController
{
NSArray *menuItems;
}
- (void)viewDidLoad {
[super viewDidLoad];
menuItems = [NSArray arrayWithObjects:#"l1",#"l2",#"l3",#"l6",#"l4",#"l5",#"l7", nil];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [menuItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = [menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if ([cell.reuseIdentifier isEqualToString:#""]) {
UIViewController *mainviewcontroller = [[UIViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:mainviewcontroller];
[self.navigationController presentViewController:navi animated:YES completion:nil];
}
}
If you already set storyboard ID then you can push programmatically using following code.
Here viewController1, viewController2 etc are storyboard Id of individual UIViewController.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *pushViewController = [self.storyboard instantiateViewControllerWithIdentifier:[NSString stringWithFormat:#"viewController%ld",indexPath.row]];
[self.navigationController pushViewController:pushViewController animated:YES];
}
//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 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.