I'm diving into iOS development and I'm trying to create an iPad app that uses the split view layout, without using the UISplitViewController. I found this question already posted, but it's too vague to help me with my current level of iOS experience.
In short, I have a UIViewController class named MySplitViewController that contains two children view controllers, one for the master view and one for the detail view. I'm trying to implement this in a way that when I push an instance of MySplitViewController onto the nav stack, I get a table view (master) on the left and a detail view on the left. However, when I run my code, the entire split view is filled with the table view. How can I manually create a Split View layout? Here are my three view controller classes, they're very simple...
MySplitViewController.m
#import "MySplitViewController.h"
#import "MasterViewController.h"
#import "DetailViewController.h"
#interface MYSplitViewController (){}
#property (nonatomic, strong) MasterViewController *masterViewController;
#property (nonatomic, strong) DetailViewController *detailViewController;
#end
#implementation MySplitViewController
- (id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
self.masterViewController = [[MasterViewController alloc] initWithNibName:nil bundle:nil];
self.detailViewController = [[DetailViewController alloc] initWithNibName:nil bundle:nil];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.frame = CGRectMake(0, 0, 768, 1004);
[self.view addSubview:self.masterViewController.view];
[self.masterViewController viewDidLoad];
[self.view addSubview:self.detailViewController.view];
[self.detailViewController viewDidLoad];
}
#end
MasterViewController.m
#import "MasterViewController.h"
#interface MasterViewController ()
#end
#implementation MasterViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
UITableView *table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 100, 1004) style:UITableViewStylePlain];
table.dataSource = self;
table.delegate = self;
[self.view addSubview:table];
}
#end
DetailViewController.m
#import "DetailViewController.h"
#interface DetailViewController ()
#end
#implementation DetailViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
UIView *uiview = [[UIView alloc] initWithFrame:CGRectMake(100, 0, 668, 1004)];
[self.view addSubview:uiview];
}
#end
What am I not understanding?
Thanks so much in advance for your wisdom!
P.S. It's worth noting why I'm not using the UISplitViewController. My app is currently designed so that the root view is not split view. The root view of my app will cause a split view to be pushed on to the nav stack. The problem with this is that the UISplitViewController is designed to be the root view of an app and Apple's docs specifically say that if you use a UISplitViewController that it needs to be the root view. Therefor, I'm implementing my own split view and manually managing the views.
Maybe thinking about showing your root view in a different way could help you. e.g like this: using a UISplitViewController as root view and present a modal view on top of it with your current root view. So you use your current root view and the UISplitViewController.
you might wanna try MGSplitViewController which is also based on UIViewController.. and allows push..MGSplitViewController
Related
Using XCode 4.5 & iOS6
I created a UINavigationController with a UITabBar (NIBs) and the tab vertical positioning for the first launch is incorrect. When you click the second tab and again the first tab the vertical positioning is OK.
So ... How can I have the first tab properly positioned when the first run is done?
See wrong positioning:
http://img231.imageshack.us/img231/2159/badbf.png
My code:
AppDelegate.h
#interface bib_AppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UINavigationController *mainControllercode;
#property (strong, nonatomic) UITabBarController *tabBarController;
in the AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// change defaul selected icon tabbar color to orange
[[UITabBar appearance] setSelectedImageTintColor:[UIColor orangeColor]];
// Override point for customization after application launch.
UIViewController *viewController1 = [[agendaViewController alloc] initWithNibName:#"agendaViewController" bundle:nil];
UIViewController *viewController2 = [[messagesViewController alloc] initWithNibName:#"messagesViewController" bundle:nil];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[viewController1, viewController2];
self.mainControllercode = [[UINavigationController alloc] initWithRootViewController:self.tabBarController];
self.window.rootViewController = self.mainControllercode;
[self.window makeKeyAndVisible];
return YES;
}
agendaViewController.h
#import <UIKit/UIKit.h>
#interface agendaViewController : UIViewController
#end
agendaViewController.m
#import "agendaViewController.h"
#interface agendaViewController ()
#end
#implementation agendaViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Agenda", #"Agenda");
self.tabBarItem.image = [UIImage imageNamed:#"83-calendar"];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
EDIT 1:
I created a sample project with Storyboards that you can see. I would like to have the same features without Storyboards, download this here:
http://www.freefilehosting.net/atestsb
Thanks
You are going about this the wrong way.
A UITabBarController should have a collection of UINavigationControllers which then have their root controller set to the primary Nib. Each tab then handles its own navigation stack.
You are currently putting the UITabBarController inside the root of the UINavigationController. This will cause issues as well as remove the tab bar when you move through the navigation stack.
Check out this link for more details to handle it programmatically :
http://www.xdracco.net/howto-implement-uinavigationcontroller-uitabbarcontroller-programmatically/
I have a project with one View. I'm drawing everything on it programically. So when i want to add another View (screen) to my project i create a class inherits from the UIViewController class and implements method
- (void)viewDidLoad
And then i want to load this View from my original View, and i do this:
In ViewController.h
#import <UIKit/UIKit.h>
#import "TestViewControllerClass.h"
#interface ViewController : UIViewController <UITableViewDataSource> {
}
#property (strong,nonatomic) TestViewControllerClass *testView;
#end
In ViewController.m
#implementation ViewController
#synthesize testView;
- (void)viewDidLoad
{
[super viewDidLoad];
testView = [[TestViewControllerClass alloc] init];
[self.view addSubview:testView]; //crash here
}
And then in my TestViewControllerClass.h
#import <UIKit/UIKit.h>
#interface TestViewControllerClass : UIViewController
#end
And TestViewControllerClass.m
- (void)viewDidLoad
{
[super viewDidLoad];
}
To check if method wiewDidLoad will be executed i put there a breakpoint, but nothing happend. In fact, my app crash (I put comment at code where).
When crashes i receive: -[TestViewControllerClass superview]: unrecognized selector sent to instance 0x683aca0
Replace
[self.view addSubview:testView]; //crash here
with
[self.view addSubview:testView.view];
Use this code...
[self.view addSubview:testView.view];
Hope,this will help you...
What you're doing is settings your ViewController as the view, not the real view
testView = [[TestViewControllerClass alloc] init];
[self.view addSubview:testView]; //crash here
this will obviously crash. Assuming you have a view variable declared in your header file called view, use
testView = [[TestViewControllerClass alloc] init];
[self.view addSubview:testView.view];
You can load two types for uiviewcontroller loading below:
[self.view addSubview:testView.view];
(or)
use presentmodalviewcontroller below code:
testView *popupView = [[testView alloc] initWithNibName:#"testView" bundle:nil];
popupView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:popupView animated:YES];
dimiss modal view cntroller below code:
[self dismissModalViewControllerAnimated:YES];
thanks..!
In my navigation based application, initWithNibName method does not called/fire
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
I'm defining rootViewController (calViewController) in appdelegate like this
calViewController *objCalViewController = (calViewController *) [navController topViewController];
objCalViewController.context = [self managedObjectContext];
[window addSubview:navController.view];
[window makeKeyAndVisible];
Is this is the issue? Please give me a help
When your UIViewController is defined in a nib file or Storyboard (usually as an IBOutlet), initWithNibName:bundle: is not called, rather initWithCoder: is. This is the case when you use Interface Builder to set your UIViewController as part of UITabBarController or UINavigationController, and almost always when using Storyboards.
in your appdelegate.m do like this
calViewController *objCalViewController = [[calViewController alloc] initWithNibName:#"WebViewController_iPhone" bundle:nil];
objCalViewController.managedObjectContext = self.managedObjectContext;
navController = [[UINavigationController alloc] initWithRootViewController:objCalViewController];
[self.window setRootViewController:navController];
[window makeKeyAndVisible];
Ok lets say i have a viewController named TCViewController with
TCViewController.h, TCViewController.m and TCViewController.xib
and in TCViewController.m
i am overriding the below method.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
In my RootViewController i want to initialize TCViewController like this
RootViewController.m
-(void)viewDidLoad //not necessarily this one, can be any method
{
// This initialization calls the initWithNibname method implemented in TCViewController.m
TCViewController *viewController = [[TCViewController alloc] initWithNibName:#"TCViewController" bundle:nil];
[self.navigationController pushViewController:viewController animated:YES];
}
If you initialize a viewController like this, control will pass to the initWithNibName method in your subclass if you have implemented it.
I have created a navigation-based application. In that, I have created MyTableViewController using uiviewcontroller.class.
#import "RootViewController.h"
#import "MyTableViewController.h"
#implementation RootViewController
- (void)viewDidLoad
{
[super viewDidLoad];
MyTableViewController *tableViewController = [[MyTableViewController alloc] init];
}
#end
#import "MyTableViewController.h"
#implementation MyTableViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"sedfsdsd");
}
#end
I don't want to show the view when the instance is created. I want to call the constructor method. I don't know how to do it. Please help me out.
#Caroline have described very good.
A normal method of your class could serve your purpose and you can name that something ViewContruction and define it in your MyTableViewController class.
-(void) ViewContruction
{
//Create all your views here
//Add that to the self.view of your controller
}
Call the above function explicitly on the instance of your view controller.
Just creating a UIViewController instance does not load the view.
If you have something like [self.view addSubview:tableViewController.view] then when that statement is executed, viewDidLoad will get executed.
However, if it's a navigation-based app, then you will need to push the viewcontroller to see it, rather than adding the subview as above.
For example:
Settings *settingsController = [[Settings alloc] initWithNibName:#"Settings" bundle:nil];
settingsController.contentSizeForViewInPopover = settingsController.view.frame.size;
[self.navigationController pushViewController:settingsController animated:YES];
[settingsController release];
I've got a UINavigationController that has a UITableViewController as it's root view. The UINavigationController is inside a UITabBarController.
In the UITableViewController (*viewOne), if I click a cell a the following code runs
UIViewController *newView = [[UIViewController alloc] initWithNibName:#"newView" bundle:nil];
[self.navigationController pushViewController:newView animated:YES];
[newView release];
Then, inside of newView is:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
NSLog(#"%#", self.navigationController);
}
return self;
}
The logs have:
[8947:207] (null)
And if I try to push a new view controller to the navigationController, nothing happens. Any clues?
I've figured it out.
In my application delegate, I've added a new property:
UINavigationController *profileNavigationController;
#property (nonatomic, retain) IBOutlet UINavigationController *profileNavigationController;
And in IB, I've connected the profileNavigationController from the app delegate to Navigation Controller.
And now, when pushing new views, I call:
StartDateSelectorViewController *startDateSelectorViewController = [[StartDateSelectorViewController alloc] initWithNibName:#"StartDateSelectorView" bundle:nil];
Strength_EngineAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.profileNavigationController pushViewController:startDateSelectorViewController animated:YES ];