show side bar for iPad like facebook in landscapemode in ios - ios

I am having an iPad app in which I want to implement a Side Bar functionality like we have in facebook app.
I am using this Demo for this.
With this I have successfully implemented the Side Bar functionality and its working well but with that my first view doesn't show me well.
Below is the screenshot.
As you can see from the screenshot, there is a black background and my whole view is not showing in full screen when the app launches.
It should be like below.
Also on clicking the button the Side View is showing like below.
It should be small as I have taken the view size with width = 300 and height = 768.
But it is showing bigger than that.
Here is my code which I change in my appdelegate.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self createEditableCopyOfDatabaseIfNeeded];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:self.viewController];
SlidingViewController *slidingView = [[SlidingViewController alloc]initWithNibName:#"SlidingViewController" bundle:nil];
self.slideMenuController = [[SlideMenuController alloc] initWithCenterViewController:navController];
self.slideMenuController.leftViewController = slidingView;
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
- (IBAction)sideBarPressed:(id)sender
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (appDelegate.slideMenuController.position == TKSlidePositionCenter) {
[appDelegate.slideMenuController presentLeftViewControllerAnimated:YES];
} else {
[appDelegate.slideMenuController presentCenterViewControllerAnimated:YES];
}
}
I want this for my iPad for Landscape mode only.
Please tell me What is wrong here?
I am stuck here for quite a while.
Any help will be appreciated.
Thanks in advance.

So better u need to use UISplitViewController
//in app delegate do like this
//in appDelegate.h file
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (nonatomic, retain) UISplitViewController *splitViewCOntroller;
#end
//in appDelegate.m file
#import "AppDelegate.h"
#import "SplitMasterViewController.h" //create a UITableviewController
#import "SplitViewDetailController.h" //create a UIViewController
#implementation AppDelegate
#synthesize splitViewCOntroller = _splitViewCOntroller;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
SplitMasterViewController *masterController = [[SplitMasterViewController alloc]initWithNibName:#"SplitMasterViewController" bundle:nil]; //this is the master menu controller
UINavigationController *masterNavController = [[UINavigationController alloc]initWithRootViewController:masterController];
SplitViewDetailController *detailViewController = [[SplitViewDetailController alloc]initWithNibName:#"SplitViewDetailController" bundle:nil]; //this is the master detail controller
UINavigationController *detailNavController = [[UINavigationController alloc]initWithRootViewController:detailViewController];
masterController.detailViewController = detailViewController;
_splitViewCOntroller = [[UISplitViewController alloc]init]; //initilise split controller
_splitViewCOntroller.delegate = detailViewController; //set the delegate to detail controller
_splitViewCOntroller.viewControllers = [NSArray arrayWithObjects:masterNavController,detailNavController, nil]; //set the splitview controller
self.window.rootViewController = _splitViewCOntroller; //finally your splitviewcontroller as the root view controller
[self.window makeKeyAndVisible];
return YES;
}
//in SplitMasterViewController.h this must be a table that contains your side bar menu items
#import "ViewController.h" //comment this if it shows any error
#import "SplitViewDetailController.h"
#interface SplitMasterViewController : UITableViewController<UITableViewDataSource,UITableViewDelegate>
#property (nonatomic, retain) SplitViewDetailController *detailViewController; //to get the detailview from masterMenu controller
#property (nonatomic, retain) NSArray *Names;
#end
// in SplitMasterViewController.m file
#import "SplitMasterViewController.h"
#import "SplitViewDetailController.h"
#interface SplitMasterViewController ()
#end
#implementation SplitMasterViewController
#synthesize Names;
#synthesize detailViewController;
- (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 from its nib.
Names = [[NSArray alloc] initWithObjects:#"apple", #"banana",
#"mango", #"grapes", nil];
[self.tableView selectRowAtIndexPath:
[NSIndexPath indexPathForRow:0 inSection:0]
animated:NO
scrollPosition:UITableViewScrollPositionMiddle];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [Names 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];
}
// [self configureCell:cell atIndexPath:indexPath];
cell.textLabel.text = [Names objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SplitViewDetailController *detailController = self.detailViewController;
detailController.myLabel.text = [Names objectAtIndex:indexPath.row]; //set the name from the array
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
//in SplitViewDetailController.h
#import "ViewController.h"
#interface SplitViewDetailController : UIViewController<UISplitViewControllerDelegate>
#property (strong, nonatomic) id detailItem;
#property (strong, nonatomic) IBOutlet UILabel *myLabel;
#property (nonatomic, retain) UIBarButtonItem *leftBarButtonItem; //to show a button on left side
#end
//in SplitViewDetailController.m
#import "SplitViewDetailController.h"
#interface SplitViewDetailController ()
{
UIPopoverController *masterPopoverController;
}
#end
#implementation SplitViewDetailController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// _leftBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:#"Menu" style:UIBarButtonItemStyleBordered target:self action:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//these are the call back to detail view controller to hide or show the button
- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
_leftBarButtonItem = barButtonItem;
_leftBarButtonItem.style = UIBarButtonItemStyleBordered;
_leftBarButtonItem.title = #"Menu";
[self.navigationItem setLeftBarButtonItem:_leftBarButtonItem animated:YES];
}
// Called when the view is shown again in the split view, invalidating the button
- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
[self.navigationItem setLeftBarButtonItem:nil animated:YES];
}
#end

I successfully implemented this side bar menu functionality with this Demo code and its working perfectly well in my case.
Hope it works to someone else also.
Thanks for your help and suggestions.

i am using this and it's good
https://github.com/ECSlidingViewController/ECSlidingViewController

Related

TableView doesn´t reload after modal view

Im making a program where im practicing UIPopoverController's for iPad
in the first popover i have a tableView with some cells , what i want to do is to call a new view with a textfield so i can add new cells with the textfield text .
The problem i have is that when i dismiss the second view the tableView is not updated . I can't call reloadData because the first view don't call "viewWillAppear" ou any other .
In the iphone simulator it works well because iphone don't use uiPopoverController but in iPad i have to dismiss the first popover and the view only reloads when i enter the second time.
I know by reading some posts that its possible to use notification center to make it happen but i don't know how
My code is this
-first view , the tableView
BNRAssetTypeViewController.h
#import <Foundation/Foundation.h>
#class BNRItem;
#interface BNRAssetTypeViewController : UITableViewController
#property (nonatomic,strong) BNRItem *item;
#property (nonatomic, copy) void (^dismissBlock)(void);
#end
BNRAssetTypeViewController.m
#import "BNRAssetTypeViewController.h"
#import "BNRItem.h"
#import "BNRItemStore.h"
#import "BNRDetailViewController.h"
#import "AddNewAssetedTypeViewController.h"
#implementation BNRAssetTypeViewController
-(instancetype)init
{
//Chamar o designated initializer
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
//Titulo
UINavigationItem *navItem = self.navigationItem;
navItem.title=#"New Asseted Type";
//Criar um novo bar button que faz novo item do lado direito
UIBarButtonItem *bbi =[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self action:#selector(addNewAssetedType)];
//meter do lado direito
navItem.rightBarButtonItem=bbi;
}
return self;
}
-(instancetype)initWithStyle:(UITableViewStyle)style
{
return [self init];
}
-(void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"ViewDidLoad");
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"UITableViewCell"];
}
-(void)viewWillAppear:(BOOL)animated
{
NSLog(#"ViewwillApear");
[self.tableView reloadData];
}
-(void)viewDidAppear:(BOOL)animated{
NSLog(#"ViewDidApear");
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[[BNRItemStore sharedStore]allAssetTypes]count];
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell" forIndexPath:indexPath];
NSArray *allAssetTypes = [[BNRItemStore sharedStore]allAssetTypes];
NSManagedObject *assetType = allAssetTypes[indexPath.row];
// Use key-value coding to get the asset type's label
NSString *assetLabel = [assetType valueForKey:#"label"];
cell.textLabel.text = assetLabel;
// Checkmark the one that is currently selected
if (assetType == self.item.assetType) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType=UITableViewCellAccessoryCheckmark;
NSArray *allAssets = [[BNRItemStore sharedStore]allAssetTypes];
NSManagedObject *assetType = allAssets[indexPath.row];
self.item.assetType=assetType;
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
self.dismissBlock();
} else {
[self.navigationController popViewControllerAnimated:YES];
}
}
-(void)addNewAssetedType{
AddNewAssetedTypeViewController *anatvc = [[AddNewAssetedTypeViewController alloc]init];
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:anatvc];
navController.modalPresentationStyle=UIModalPresentationCurrentContext;
[self.navigationController presentViewController:navController animated:YES completion:nil];
}
-The second View
AddNewAssetedTypeViewController.h
#import <UIKit/UIKit.h>
#interface AddNewAssetedTypeViewController : UIViewController <UITextFieldDelegate>
#property (nonatomic,copy) void (^dismissBlock)(void);
#end
AddNewAssetedTypeViewController.m
#import "AddNewAssetedTypeViewController.h"
#import "BNRItemStore.h"
#import "BNRAssetTypeViewController.h"
#interface AddNewAssetedTypeViewController ()
#property (weak, nonatomic) IBOutlet UITextField *textField;
#end
#implementation AddNewAssetedTypeViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
UIBarButtonItem *doneItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(save:)];
self.navigationItem.rightBarButtonItem=doneItem;
UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self action:#selector(cancel:)];
self.navigationItem.leftBarButtonItem=cancelItem;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
-(void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.view endEditing:YES];
[[BNRItemStore sharedStore] createAssetType:self.textField.text];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)cancel:(id)sender
{
[self.presentingViewController dismissViewControllerAnimated:YES
completion:nil];
}
-(void)save:(id)sender
{
[self.presentingViewController dismissViewControllerAnimated:YES
completion:nil];
}
#end
Olá!
You can fire a notification using NSNotificationCenter when something is added in the popover. First, register the first view controller to observe for that notification. In the first VC retain a reference to the observer you'll register later on:
#implementation BNRAssetTypeViewController {
id _observer;
}
In viewWillAppear:
_observer = [[NSNotificationCenter defaultCenter] addObserverForName:#"somethingAddedNotification"
object:nil
queue:nil
usingBlock:^(NSNotification *notification)
{
[self.tableView reloadData];
}];
In viewWillDisappear:
- (void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:_observer];
}
Then in the method save: in the second view controller:
[[NSNotificationCenter defaultCenter] postNotificationName:#"somethingAddedNotification" object:nil];
Disclaimer: untested code. Let me know how it goes.

Property requires a method to be defined

I'm trying to create a SplitViewController view but I get the following warning:
Property splitViewController requires a method setSplitViewController to be defined -use #Synthesize,#dynamic or provide a method implementation in this class implement.
Here is the code
///AppDelegate.h
#class ViewController;
#class DetailViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate, UISplitViewControllerDelegate>
{
UISplitViewController *splitViewController;
ViewController *viewcontroller;
DetailViewController *detailViewController;
}
#property (nonatomic,retain) UIWindow *window;
#property (nonatomic,retain) DetailViewController *detailViewController;
#property(nonatomic,retain) UISplitViewController *splitViewController;
#property (nonatomic,retain) ViewController *viewController;
#end
///AppDelegate.m"
#import "ViewController.h"
#import "DetailViewController.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize viewController = _viewController;
#synthesize splitviewController;
#synthesize detailViewController;
- (void)dealloc
{
[_window release];
[_viewController release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
ViewController *rootViewController = [[ViewController alloc] initWithStyle:UITableViewStylePlain];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
rootViewController.detailViewController = detailViewController;
splitViewController = [[UISplitViewController alloc] init];
splitViewController.viewControllers = [NSArray arrayWithObjects:navigationController, detailViewController, nil];
splitViewController.delegate = detailViewController;
[self.window makeKeyAndVisible];
return YES;
}
///ViewController.h
#import <UIKit/UIKit.h>
#class DetailViewController;
#interface ViewController : UITableViewController{
DetailViewController *detailViewController;
NSMutableArray *phone;
}
#property (nonatomic,retain)IBOutlet DetailViewController *detailViewController;
#property (nonatomic,retain) NSMutableArray *phone;
#end
///ViewController.m
#import "ViewController.h"
#import "DetailViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize detailViewController,phone;
- (CGSize)contentSizeForViewInPopoverView {
return CGSizeMake(320, 600);
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.phone = [[NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"phone" ofType:#"plist"]] retain];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [phone count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
}
// Configure the cell.
cell.textLabel.text = [self.phone objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
/*
When a row is selected, set the detail view controller's detail item to the item associated with the selected row.
*/
detailViewController.detailItem = [self.phone objectAtIndex:indexPath.row];
}
- (void)dealloc {
[detailViewController release];
[super dealloc];
}
#end
In ur code, you haven't synthesized your splitViewController property. Since You have not synthesized it the property, the compiler is issuing a warning asking u to either synthesize the property so that it can generate setters and getters automatically for your convinienvce (You can use the generated setters and getters using . notation as in self.splitViewController so synthesize it as
#synthesize splitViewController = _splitViewController
or
implement your own custom setter and getter as
//setter
- (void)setSplitViewController:(UISplitViewController*)splitViewController_ {
//assuming your property has retain identifier
if (splitViewController != splitViewController_) {
[splitViewController release];
splitViewController = [splitViewController_ retain];
}
}
//getter
- (UISplitViewController*)splitViewController {
return splitViewController;
}
or
declaring the property as dynamic using #dynamic splitViewController . This means that the setter and getter for the property will be provided from somewhere else.
EDIT:
replacedidFinishLaunchingWithOptions method in appDelegate.m with the following:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
_viewController = [[ViewController alloc] initWithNibName:#"ViewController's nib name" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:_viewController];
detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
rootViewController.detailViewController = detailViewController;
splitViewController = [[UISplitViewController alloc] init];
splitViewController.viewControllers = [NSArray arrayWithObjects:navigationController, detailViewController, nil];
splitViewController.delegate = detailViewController;
self.window.rootViewController = splitViewController;
return YES;
}
also edit the dealloc:
- (void)dealloc
{
[_window release];
[_viewController release];
[splitViewController release];
[detailViewController release];
[super dealloc];
}
And in viewController viewDidLoad replace self.phones line with this
self.phone = [[NSArray arrayWithObjects:#"Cell ONE",#"Cell TWO",#"Cell THREE",#"Cell FOUR",#"Cell FIVE",#"Cell SIX", nil];
this is just for testing that the array part is loading properly..so that you can see the cells if they are getting created. put a break point in cellForRowAtIndexPath method and see if its getting called
and then finally in didSelect see if the detailItem iVar is not nil.
And Yes, check the NIB names properly before loading them, and also that all outlets in the NIB are properly connected.
Cheers and Have fun.
The problem is you misspelled splitViewController in your #synthesize statement -- you didn't capitalize the v.
You wouldn't run into this problem if you did it the easy way. There's no need for either the instance variables or the #synthesize statements any more -- you get both automatically when create the property.
In your case add #synthesize splitViewController = _splitViewController; and detailViewController = _ detailViewController;
Here is useful code for, how can i add UISplitViewController.
/// AppDelegate.h file
#import <UIKit/UIKit.h>
#import "MasterViewController.h"
#import "DetailViewController.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate, UISplitViewControllerDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (nonatomic, strong) UISplitViewController *splitViewController;
#property (nonatomic, strong) MasterViewController *masterVC;
#property (nonatomic, strong) DetailViewController *detailVC;
#property (nonatomic, strong) UINavigationController *mvcNavCon;
#property (nonatomic, strong) UINavigationController *dvcNavCon;
#end
/// AppDelegate.m File
#import "AppDelegate.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
self.masterVC = [[MasterViewController alloc] init];
self.mvcNavCon = [[UINavigationController alloc] initWithRootViewController:self.masterVC];
self.detailVC = [[DetailViewController alloc] init];
self.dvcNavCon = [[UINavigationController alloc] initWithRootViewController:self.detailVC];
self.splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.delegate = self;
self.splitViewController.viewControllers = [NSArray arrayWithObjects:self.mvcNavCon, self.dvcNavCon,nil];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = self.splitViewController;
[self.window makeKeyAndVisible];
return YES;
}

Adding an Array to a UITableView, using a UINavigationController on a Tab Bar based application

I have made simple cocoa touch apps before but I have never used UINavigationControllers, any advice would be greatly appreciated.
I'm trying to add an array of a list of store names to a UITableView. The UITableView is accessed through a UINavigation controller by a tab on a tab bar.
I have a TabBarController.xib file that holds the tab bar.
I also have a AtoZNavigationController.xib that holds the UINavigationController.
And I have a AtoZTableController.xib file that holds the UITableView.
This is my AppDelegate.h:
#import <UIKit/UIKit.h>
#class AtoZNavigationController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) IBOutlet UITabBarController *rootController;
#property (strong, nonatomic) IBOutlet AtoZNavigationController *navController;
#end
The AppDelegate.m
#import "AppDelegate.h"
#import "AtoZNavigationController.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize rootController;
#synthesize navController;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
[[NSBundle mainBundle] loadNibNamed:#"TabBarController" owner:self options:nil];
[self.window addSubview:rootController.view];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
#end
The AtoZNavigationController.h
#import <UIKit/UIKit.h>
#interface AtoZNavigationController : UINavigationController
#end
The AtoZNavigationController.m
#import "AtoZNavigationController.h"
#interface AtoZNavigationController ()
#end
#implementation AtoZNavigationController
-(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 from its nib.
}
-(void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
The AtoZTableController.h
#import <UIKit/UIKit.h>
#interface AtoZTableController : UITableViewController <UITableViewDelegate, UITableViewDataSource>
{
IBOutlet UITableView *AtoZTableView;
NSMutableArray *AtoZArray;
}
#property (nonatomic, retain) IBOutlet UITableView *AtoZTableView;
#end
The AtoZTableController.h
#import "AtoZTableController.h"
#interface AtoZTableController ()
#end
#implementation AtoZTableController
#synthesize AtoZTableView;
-(id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
-(void)viewDidLoad
{
[super viewDidLoad];
self.title = NSLocalizedString(#"A to Z", #"An A to Z List of Stores");
AtoZArray = [[NSMutableArray alloc] init];
[AtoZArray addObject:#"Apple"];
[AtoZArray addObject:#"Boots"];
[AtoZArray addObject:#"Topman"];
}
-(void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 0;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [AtoZArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
NSInteger row = [indexPath row];
cell.textLabel.text = [AtoZArray objectAtIndex:row];
return cell;
}
#pragma mark - Table view delegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
#end
In your AtoZTableController.h, you have a problem.
The problem is in your 'tableView:cellForRowAtIndexPath:' method.
Here's what you have:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
NSInteger row = [indexPath row];
cell.textLabel.text = [AtoZArray objectAtIndex:row];
return cell;
}
The problem is that you never handle for a return value of nil from dequeueReusableCellWithIdentifier:CellIdentifier.
Try this out:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// What happens if you don't get a cell to use?
// This is the way to create a new, default UITableViewCell
if (!cell) {
// You can look at the UITableViewCell class reference to see the 4 available styles
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSInteger row = [indexPath row];
cell.textLabel.text = [AtoZArray objectAtIndex:row];
return cell;
}
Edit/Update:
OK, so it's a little bit difficult to know exactly where your error is, so I'll set up/describe for you a typical situation (or how I'd do it in your shoes).
If you create a new app and select the "Tabbed Application" template in Xcode, you get the following method in your app delegate (more or less; I condensed it a little bit and "fixed" Apple's poor choice to use dot notation):
Note: I believe the problem you're having with pushing a new view controller will be fixed below now...End Note
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]];
// Override point for customization after application launch.
UIViewController *vc1 = [[FirstViewController alloc] initWithNibName:#"FirstVC" bundle:nil];
// New line...
UINavigationController *navC = [[UINavigationController alloc] initWithRootViewController:vc1];
UIViewController *vc2 = [[SecondViewController alloc] initWithNibName:#"SecondVC" bundle:nil];
[[self setTabBarController:[[UITabBarController alloc] init]];
// Change here, too...
[[self tabBarController] setViewControllers:[NSArray arrayWithObjects:navC, vc2, nil]];
[[self window] setRootViewController:[self tabBarController]];
[[self window] makeKeyAndVisible];
return YES;
}
This method sets up all you need to launch your app with 2 UIViewControllers created and set as tab 1 and tab 2 inside of a UITabBarController.
Now, you can make FirstViewController and SecondViewController be whatever you want. For purposes of this question, we'll assume that you want to alter FirstViewController to host a UITableView, which will push a detail UIViewController when a user selects a row on the screen.
Requirements
EITHER FirstViewController must be a subclass of UITableViewController (this is not what the default template provides) OR you must add a UITableView onto FirstViewController's view and set up all of the connections.
Let's assume you're going to keep FirstViewController as a standard UIViewController subclass and that you'll add a UITableView onto its view. (I'd probably change it to a UITableViewController subclass, but that might be more confusing at this point.)
First, in FirstViewController.h, change this:
#interface MMFirstViewController : UIViewController
#end
to this:
#interface MMFirstViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
UITableView *TableView;
}
#property (strong, nonatomic) IBOutlet UITableView *TableView;
#end
Next, in FirstViewController.m, synthesize the TableView property (#synthesize TableView).
Next, click on FirstViewController.xib in Xcode to have it load up in Interface Builder (I'm assuming here that you're using Xcode 4).
Now, drag a UITableView from the controls panel onto your UIViewController's view.
Make the following connections in Interface Builder:
Right click on File's Owner and connect the TableView property to the UITableView you dropped on the view of FirstViewController.
Right click on the UITableView and connect BOTH the datasource AND delegate properties to File's Owner.
Now, the code you posted initializing and populating AtoZArray should work fine. Don't forget to copy in the 3 UITableView methods you previously had, numberOfSectionsInTableView:, tableView:numberOfRowsInSection: and tableView:cellForRowAtIndexPath:.
Those steps should get you working and should also let you see where you perhaps went wrong in your setup. Please note, you'll still have to figure out tableView:didSelectRowAtIndexPath: on your own in order to push in your new UIViewController.
Here's a teaser to get you started:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
ThirdViewController *detailVC = [[ThirdViewController alloc] initWithNibName:#"ThirdViewController" bundle:nil];
[[self navigationController] pushViewController:detailVC animated:YES];
}
I had to create an instance of the navigationController and pass that into the subview in my appDelegate.m along with the tabBarController. It can then later be referenced in my UITableViewController.
Here's the code I added:
navigationController = [[UINavigationController alloc] initWithRootViewController:_tabBarController];
[self.window addSubview:_tabBarController.view];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
Where navigationController is simply an instance of a subclass of either UITableViewController or UIViewController, depending on what type of screen you want to display.

iPad application with multiple DetailView and have navigation in detailview

i search for a way to have multiple detail view in iPad application and i find the sample code in apple developer site http://developer.apple.com/library/ios/#samplecode/MultipleDetailViews/Introduction/Intro.html , but now i want to have navigation in detail view which this sample does not cover, i add uinavigationcontroller to detail view as :
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
ReportsViewController_iPad *master = [[ReportsViewController_iPad alloc] initWithNibName:#"ReportsViewController_iPad" bundle:nil];
DetailViewController_iPad *detail = [[DetailViewController_iPad alloc] initWithNibName:#"DetailViewController_iPad" bundle:nil];
UINavigationController *masterNavController = [[[UINavigationController alloc] initWithRootViewController:master ] autorelease];
UINavigationController *detailNavController = [[[UINavigationController alloc] initWithRootViewController:detail ] autorelease];
splitViewController.viewControllers = [NSArray arrayWithObjects:masterNavController , detailNavController, nil];
[window addSubview:splitViewController.view];
[window makeKeyAndVisible];
return YES;
}
but when i run the sample i got error
[UINavigationController showRootPopoverButtonItem:]: unrecognized selector sent to instance...
showRootPopoverButtonItem is a method define in a protocol in RootViewController
#protocol SubstitutableDetailViewController
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
#end
---- ReportsViewController.h
#protocol SubstitutableDetailViewController
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
#end
#protocol DetailViewControllerManagerDelegate
-(void) didSelectRowAtIndexPathPopOver:(NSString *)ID;
#end
#interface ReportsViewController_iPad : ReportsViewController<UISplitViewControllerDelegate , DetailViewControllerManagerDelegate>
{
UISplitViewController *splitViewController;
UIPopoverController *popoverController;
UIBarButtonItem *rootPopoverButtonItem;
}
#property (nonatomic, assign) IBOutlet UISplitViewController *splitViewController;
#property (nonatomic, retain) UIPopoverController *popoverController;
#property (nonatomic, retain) UIBarButtonItem *rootPopoverButtonItem;
#property(nonatomic, retain) id<DetailViewControllerManagerDelegate> delegate;
-(void)didSelectRowAtIndexPath:(NSString*)ID;
#end
--DetailViewController.h
#import <UIKit/UIKit.h>
#import "ReportsViewController_iPad.h"
#interface DetailViewController_iPad : UIViewController<SubstitutableDetailViewController>
{
UIToolbar *toolbar;
}
#property (nonatomic, retain) IBOutlet UIToolbar *toolbar;
#end
--DetailViewController.m
#import "DetailViewController_iPad.h"
#implementation DetailViewController_iPad
#synthesize toolbar;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#pragma mark -
#pragma mark Managing the popover
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
// Add the popover button to the toolbar.
NSMutableArray *itemsArray = [toolbar.items mutableCopy];
[itemsArray insertObject:barButtonItem atIndex:0];
[toolbar setItems:itemsArray animated:NO];
[itemsArray release];
}
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
// Remove the popover button from the toolbar.
NSMutableArray *itemsArray = [toolbar.items mutableCopy];
[itemsArray removeObject:barButtonItem];
[toolbar setItems:itemsArray animated:NO];
[itemsArray release];
}
- (void)dealloc {
[toolbar release];
[super dealloc];
}
#end
So Thanks in advance.
Where definition of method showRootPopoverButtonItem is present, seems like this is not defined. You need to define it.
If you want to avoid crash then you can use -
if ([aViewController respondsToSelector:#selector(showRootPopoverButtonItem:)]) {
[aViewController performSelector:#selector(showRootPopoverButtonItem:) withObject:self.rootPopoverButtonItem];
}
EDIT -
I have checked this and found what you are doing wrong , for e.g. code in willHideViewController-
UIViewController <SubstitutableDetailViewController> *detailViewController = [splitViewController.viewControllers objectAtIndex:1];
this is expecting a view controller, while you are passing navigation controller which in turn has view controller(similar at some other position), so you need to alter these codes as well if you want to pass navigation controller from app delegate.

iOS (iPhone/iPad) SDK - UITableView not refreshing on reloadData (numberOfSectionsInTableView etc. does not get called on reloadData)

For some reason [tView reloadData] (where tView is a UITableView) does not refresh my UITableView. cellForRowAtIndexPath, numberOfSectionsInTableView and numberOfRowsInSection only get called once - at load. Those methods don't seem to be called after [tView reloadData]. Here's my code:
(AppDelegate.h):
#import <UIKit/UIKit.h>
#import "MBProgressHUD.h"
#class FirstNavViewController;
#class SecondTableViewController;
#interface <appname>AppDelegate : NSObject <UIApplicationDelegate, MBProgressHUDDelegate> {
UIWindow *window;
UITabBarController *rootController;
FirstNavViewController *viewController;
SecondTableViewController *viewController1;
NSMutableData *responseData;
NSMutableArray *blogEntries;
MBProgressHUD *HUD;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *rootController;
#property (nonatomic, retain) IBOutlet FirstNavViewController *viewController;
#property (nonatomic, retain) IBOutlet SecondTableViewController *viewController1;
#property (nonatomic, retain) NSMutableArray *blogEntries;
#end
(AppDelegate.m):
#import "AppDelegate.h"
#import "FirstNavViewController.h"
#import "SecondTableViewController.h"
#import "SBJson.h"
#define TMP NSTemporaryDirectory()
#implementation AppDelegate
#synthesize window = _window;
#synthesize rootController;
#synthesize viewController;
#synthesize viewController1;
#synthesize blogEntries;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
CGFloat width = self.rootController.view.bounds.size.width;
CGFloat height = self.rootController.view.bounds.size.height;
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, width, height)];
UIImage *imageView = [UIImage imageNamed:#"theme_frame.png"];
UIColor *kMainColor = [[UIColor alloc] initWithPatternImage:imageView];
[v setBackgroundColor:kMainColor];
[kMainColor release];
[self.rootController.tabBar insertSubview:v atIndex:0];
imageView = nil;
[v release];
responseData = [[NSMutableData data] retain];
blogEntries = [NSMutableArray array];
NSURLRequest *request = [NSURLRequest requestWithURL:
[NSURL URLWithString:#"ENTER_JSON_URL_HERE"]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
NSAssert(nil != self.rootController, #"tab bar controller not hooked up!");
BOOL iPad = NO;
#ifdef UI_USER_INTERFACE_IDIOM
iPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#endif
if (iPad) {
self.viewController = [[[FirstNavViewController alloc] initWithNibName:#"FirstNavViewController_iPad" bundle:nil] autorelease];
self.viewController1 = [[[SecondTableViewController alloc] initWithNibName:#"SecondTableViewController_iPad" bundle:nil] autorelease];
}
else {
self.viewController = [[[FirstNavViewController alloc] initWithNibName:#"FirstNavViewController_iPhone" bundle:nil] autorelease];
self.viewController1 = [[[SecondTableViewController alloc] initWithNibName:#"SecondTableViewController_iPhone" bundle:nil] autorelease];
}
self.rootController.viewControllers = [NSArray arrayWithObject:self.viewController];
self.rootController.selectedIndex = 0;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
self.window.rootViewController = self.rootController;
#else
[self.window addSubview:rootController.view];
#endif
[self.window makeKeyAndVisible];
HUD = [[MBProgressHUD alloc] initWithView:viewController.view];
[viewController.view addSubview:HUD];
[HUD show:NO];
// Regisete for HUD callbacks so we can remove it from the window at the right time
HUD.delegate = self;
HUD.labelText = #"Loading";
return YES;
}
#pragma mark NSURLConnection delegate methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[HUD hide:YES];
[connection release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
[responseData release];
NSMutableArray *allBlogEntries = [responseString JSONValue];
[viewController1 setBlogEntries:allBlogEntries];
[responseString release];
[HUD hide:YES];
}
- (void)dealloc
{
[_window release];
[rootController release];
[viewController release];
[viewController1 release];
[super dealloc];
}
#end
(FirstNavViewController.h):
#import <UIKit/UIKit.h>
#interface FirstNavViewController : UIViewController {
UINavigationController *navController;
}
#property (nonatomic, retain) UINavigationController *navController;
#end
(FirstNavViewController.m):
#import "FirstNavViewController.h"
#import "SecondTableViewController.h"
#implementation FirstNavViewController
#synthesize navController;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
UITabBarItem *tabBarItem = [self tabBarItem];
UIImage *tabBarImage = [UIImage imageNamed:#"blog.png"];
[tabBarItem setImage:tabBarImage];
[tabBarItem setTitle:#"Blog"];
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
navController = [[UINavigationController alloc] initWithRootViewController:self];
SecondTableViewController *secondViewController = [[SecondTableViewController alloc] initWithNibName:#"BlogOverviewViewController_iPhone" bundle:nil];
[navController pushViewController:secondViewController animated:NO];
[blogOverviewViewController release];
[self.view addSubview:navController.view];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
(SecondTableViewController.h):
#import <UIKit/UIKit.h>
#import "SBJson.h"
#interface SecondTableViewController : UIViewController {
NSMutableArray *blogEntries;
IBOutlet UITableView *tView;
}
#property (nonatomic, retain) NSMutableArray *blogEntries;
#property (nonatomic, retain) NSArray *arryData;
#property (nonatomic, retain) IBOutlet UITableView *tView;
#end
(SecondTableViewController.m):
#import "SecondTableViewController.h"
#import "ThirdDetailViewController.h"
#import "NSString+HTML.h"
NSString *convertedString;
#implementation SecondTableViewController
#synthesize arryData;
#synthesize tView;
-(NSMutableArray*)blogEntries {
return [[blogEntries retain] autorelease];
}
-(void)setBlogEntries:(NSMutableArray*)newBlogEntries {
if(newBlogEntries != blogEntries) {
[newBlogEntries retain];
[blogEntries release];
blogEntries = newBlogEntries;
[tView reloadData];
}
}
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [blogEntries count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
NSDictionary *aBlogEntry = [blogEntries objectAtIndex:[indexPath row]];
NSArray *bPosts = (NSArray *)[aBlogEntry objectForKey:#"posts"];
NSString *stringToConvert = [bPosts valueForKey:#"title_plain"];
NSString *convertedString = [stringToConvert stringByConvertingHTMLToPlainText];
cell.textLabel.text = convertedString;
cell.textLabel.adjustsFontSizeToFitWidth = YES;
cell.textLabel.font = [UIFont systemFontOfSize:12];
cell.textLabel.minimumFontSize = 10;
cell.textLabel.numberOfLines = 4;
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
NSString *stringToConvert1 = [bPosts valueForKey:#"excerpt"];
NSString *convertedString1 = [stringToConvert1 stringByConvertingHTMLToPlainText];
cell.detailTextLabel.text = convertedString1;
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ThirdDetailViewController *detailViewController = [[ThirdDetailViewController alloc] initWithNibName:#"BlogContentViewController_iPhone" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
NSDictionary *aBlogEntry = [blogEntries objectAtIndex:[indexPath row]];
NSArray *bPosts = (NSArray *)[aBlogEntry objectForKey:#"posts"];
NSString *stringToConvert = [bPosts valueForKey:#"title"];
NSString *convertedString = [stringToConvert stringByConvertingHTMLToPlainText];
[contentViewController changeTitleTextLabel:convertedString];
NSString *stringToConvert1 = [bPosts valueForKey:#"content"];
NSString *convertedString1 = [stringToConvert1 stringByConvertingHTMLToPlainText];
NSString *newConvertedString1 = [convertedString1 stringByReplacingOccurrencesOfString: #"\n" withString:#"\n\n"];
[detailViewController changeContentTextLabel:newConvertedString1];
[tableView deselectRowAtIndexPath: indexPath animated: YES];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
blogEntries = [[NSMutableArray alloc]init];
self.title = #"Blog";
[self.navigationItem setHidesBackButton:YES animated:NO];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)dealloc {
[blogEntries release];
[super dealloc];
}
#end
Does anyone know what the problem is? I am stuck on why the UITableView will not reloadData.
EDIT: Small background: I am using a UITabBarController (AppDelegate) with a UIViewController in it with a UINavigationController as a subview of that UIViewController (FirstNavViewController). The UINavigationController then has a subview with another UIViewController in it. The latter UIViewController (SecondTableViewController) includes a UITableView.
I've just been having this issue. Turned out to be a threading problem for me. For those those who end up here after a search, here is my quick fix:
[tView performSelectorOnMainThread:#selector(reloadData)
withObject:nil
waitUntilDone:false];
It seems reloadData needs to be called on the main thread. I hope this helps (^_^)
In your viewDidLoad method, add: tView.delegate = self;
Your view setup might be the cause of your problems.
I don't really understand the details of your implementation but right now you are adding that SecondTableViewController to both the tab bar controller and then on the stack of a navigation controller in your FistNavViewController viewDidLoad method.
Create the navigation controller with FistNavViewController as its rootViewController, then add the navigation controller as the first view controller to your UITabBarViewController
(code here is typed from memory so please excuse any typos)
FirstNavViewController *vc = [[FirstNavViewController alloc] initWithNibName:#"nibname" andBundleName:nil];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];
UITabBarController *tbc = [UITabBarController setViewControllers:[NSArray arrayWithObjects:nc, otherVc1Example, otherVc2Example, nil] animated:NO];
In your FirstNavViewController viewDidLoad method, you can then instantiate SecondTableViewController and push it onto the stack with
[self.navigationController pushViewController:secondTableViewController animated:YES];
Finally, within that nav controller you need to make sure you have your UITableView setup correcly either in Interface Builder (by connecting the datasource and delegate outlets to the file owner) or in code by manually setting the tableview delegate and datasource to self.
Bottom line is everything you are trying to do above is WAY easier and less error prone if you use Interface Builder. In MainWindow.xib simple add a tab bar controller and under it add navigation controllers and view controllers as you see fit. It should work "pretty much" out of the box.
Good luck.
Rog

Resources