how to use UITableViewStyleGrouped at the initialization? - objective-c

i found this link : initialize UITableViewController with [super initWithStyle:UITableViewStyleGrouped]
but i don't understand the way to initialize the tableView as "grouped" inside the controller class?
self = [super initWithStyle:UITableViewStyleGrouped];
Could you help me?
Thanks a lot
Paul

[self.tableView initWithFrame:self.view.frame style:UITableViewStyleGrouped];

The easiest way is to change the TableView in Interface Builder to Grouped style in the Attribute Inspector. To do this in code you would need to change the way the UITableViewControler is created. You would not do it through the xib, but in code in the AppDelegate. You could also change the code to a UIViewController and implement the table view delegates and change things yourself.

Not sure if this is what you are looking for, but assuming you have a UITableViewController called myTableVC that is created via code (with no xib) and you want the table to display with a grouped style, you could do so by calling the view controller as follows:
MyTableViewController *myTableVC= [[MyTableViewController alloc] initWithStyle:UITableViewStyleGrouped];
[self presentModalViewController:myTableVC animated:YES];
[myTableVC release];
Similarly, if you wanted a plain tableviewcontroller style, you could do so by:
MyTableViewController *myTableVC= [[MyTableViewController alloc] initWithStyle:UITableViewStylePlain];

Related

Design one XIB and re-use it in different UIViewControllers

I have one UIView that I want to use in every of my UIViewControllers. The main UI is designed with Storyboard. The extra UIView has its own XIB.
So I don't want to put the UI of the extra UIView by hand into every UIViewController, and connect the outlets on every UIViewController. So I thought maybe it is possible to create the UI, and the connections in one XIB and then somehow reuse it. Is this possible? If yes how?
Just add this line to your ViewControllers to have a reference to your custom view:
YourView *yourView = (YourView *)[[NSBundle mainBundle] loadNibNamed:#"YourXIB"
owner:self
options:nil].firstObject;
But since you want this custom view in all of your ViewControllers, I recommend having one UIViewController subclass that contains the line above, then subclass that UIViewController for each additional one in your project. That way you'll have a reference to your custom view in each ViewController, but only have to write this line once.
I think it is possible by keeping the same name in the function initWithNibName:, so you can do this in one of your controller:
UIViewController *oneViewController = [[FirstViewControllerClass alloc] initWithNibName:#"MyXIBThatWillStayTheSame" bundle:nil];
[self presentModalViewController:oneViewController animated:YES];
and do this in another one:
UIViewController *anotherViewController = [[AnotherViewControllerClass alloc] initWithNibName:#"MyXIBThatWillStayTheSame" bundle:nil];
[self presentModalViewController:anotherViewController animated:YES];

TableViewController within a ViewController

I have a UIViewController (StoreViewController), and in it's .xib is a UITableView to the left, and a standard UIView to the right. I have created a UITableViewController called StoreTableController and want to somehow make it the the controller of the table view within the StoreView.xib.
Unfortunately, I need to keep the File Owner of the nib file as StoreViewController. I have a delegate within the StoreTableController which has been set as the StoreViewController (this is for calling certain methods), and within the StoreViewController I have an instance of the StoreTableController.
So far I have tried keeping an outlet of the UITableView within StoreViewController and then doing this:
[self addChildViewController:self.tableController];
[self.tableController setTableView:self.table];
[self.table setDataSource:self.tableController];
[self.table setDelegate:self.tableController];
Where self.table is the outlet, and self.tableController is the instance of the StoreTableController.
However, I do not fully understand how to use UIViewController containment, so this is obviously incorrect.
I have tried variations of this as well, but really don't know what to do.
I have avoided using a UISplitViewController here because not only is the left view larger than the right, but also there are various things I plan to do which mean this must be done in a single .xib file if possible.
Any help is very much appreciated.
First, put a regular UIView instead of a UIScrollView in your .xib. Connect it with an IBOutlet called "tableContentView".
Then, create a new instance of UITableViewController (or your custom class, derived from UITableViewController) in your code, and add its UIView to the tableContentView like so:
- (void)viewDidLoad
{
[super viewDidLoad];
// Add tableView
UITableViewController *someTableViewController = [[UITableViewController alloc] init];
someTableViewController.view.frame = self.tableContentView.bounds;
someTableViewController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self.tableContentView addSubview:someTableViewController.view];
}

Is this a correct way to add/remove views?

Lets say that I have 4 view controllers (call them FirstView,SecondView,ThirdView,FourthView) which are created programmatically and all are in separate files:
In AppDelegate.m didFinishLaunchingWithOptions method I have these lines of code
self.rootViewController = [[rootViewController alloc]initWithNibName:#"rootViewController" bundle:nil];
self.window.rootViewController = self.rootViewController;
In rootViewController.m loadview method I have
self.view = [[UIView alloc]initWithFrame:[UIScreen mainScreen].applicationFrame];
self.firstView = [[FirstView alloc]init];
[self.view addSubview:self.firstView.view];
That code works fine - first view is displayed.
Let's continue
In FirstView.m switchViews method
NOTE: Please see the comments in code
self.secondView = [[SecondView alloc] initWithNibName:#"SecondView" bundle:nil];
// I think here secondView is added to rootViewController - right ?
[self.view.superview addSubview:self.secondView.view];
// Here first view is removed from rootViewController - right ?
[self.view removeFromSuperview];
Here is how I add/remove views.
Is this approach correct?
Can you recommend a better solution?
I have read about UINavigationController, but I don't think it could be a solution in this case.
You say:
I have 4 views (call them FirstView ...
Then you say:
[self.view addSubview:self.firstView.view];
Which makes me think that FirstView isn't actually a UIView - as you claim it is. Instead, it's probably a UIViewController - a different beast altogether.
If my suspicion is correct - then you are "off-track" so to speak.
Going beyond that to your sample code snippet:
self.secondView = [[SecondView alloc] initWithNibName:#"SecondView" bundle:nil];
// I think here secondView is added to rootViewController - right ?
[self.view.superview addSubview:self.secondView.view];
// Here first view is removed from rootViewController - right ?
[self.view removeFromSuperview];
This is definitely not a great idea. Here's why:
First: your view controller doesn't explicitly "know" anything about the superview you are so casually inserting and removing subviews to/from - so it shouldn't do that. You may, alternatively, create your own view and insert/remove subviews from that - which would not only be perfectly acceptable but also common practice.
Second: if these are actually UIViewControllers like I think they are - then you are not properly handling hooking them up to the UIViewController event chain - which means methods on these subclasses like viewDidAppear: or viewDidUnload will not fire.
From what I see in your code, UINavigationController seems like it would help. If you don't want a navigation bar, you can definitely hide it, but the methods in UINavigationController should help you with switching views.
If your views only need to display temporarily, you could also use Modal View controllers. An example of Modal View controllers can be found here.
If you haven't already, check out the View Controller Programming Guide from Apple.

Update uitextView from another controller

I want to update uitextview from another uiviewcontroller classes.
Can anyone help me?
It is not exactly clear what you are asking, but I think you mean that you want to send a message to a UITextView instance within another UIViewController subclass.
So long as this UITextView is a member of this UIViewController, you can send messages to it. (Of course, it must be declared as a property for getters and setters).
Example:
OtherViewController *otherViewController = [[OtherViewController alloc] init];
[[otherViewController textView] setText:#"your text here"];
[[self navigationController] pushViewController:otherViewController animated:YES];
I suppose this could be useful if you were about to switch push or pop a view controller and needed to add information to it before you did so. Hopefully this answered your question.
you can update your textview's text using NSNotificationCenter from other viewcontroller.

Why is this iPhone program not calling -loadView?

I am trying to work my way through basic iPhone programming and I have a good basic understanding of how Interface Builder works, so I decided to try my hand at doing the views programmatically. I have gone through the ViewController Apple guide and searched everywhere and I cannot seem to find a solution to my problem. This leads me to believe it is a very simple solution, but I am just really banging my head against the wall. Basically all I am trying to do is create a view that gets main window as a subview. I know that if self.view is not defined then the loadView method is supposed to be called, and everything is supposed to be set up there. Here is the current state of my code:
The delegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
StartMenuViewController *aViewController = [[StartMenuViewController alloc] init];
self.myViewController = aViewController;
[aViewController release];
UIView *controllersView = [myViewController view];
window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
[window setBackgroundColor:[UIColor redColor]];
[window addSubview:controllersView];
[window makeKeyAndVisible];
}
The view controller:
- (id)init {
if (self = [super init]) {
self.title = #"Start Menu";
}
return self;
}
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
UIView *startView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
[startView setAutoresizingMask:UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth];
[startView setBackgroundColor:[UIColor greenColor]];
self.view = startView;
[startView release];
}
Thanks for the help in advance!
Are you sure that you're inheriting from UIViewController and not overriding the implementation of - (UIView*)view?
EDIT: More info:
UIViewController has a special implementation of the "-(UIView*) view" message so that when it's called, the loadView method is called if the view member variable is not set. So, if you provide an implementation of "- (id)view" in your subclass, (or a property named view) it will break the auto-calling of "- loadView".
Just to document a "loadView is not called" case:
I wrote a 2 UITableViewController(s) to handle detail data for a master ViewController. Since the devil was in #2, I made a simple UITableViewController for #1, and referenced it in the XIB for the "master" ViewController.
When I was done with #2, I could simply copy the code to #1, remove the complicated code, and go on with life.
But to my dismay and several days work, no matter what I did, viewLoad was not being called for my simple #1 UITableViewController.
Today I finally realised that I was referencing the UITableViewController in the XIB to the master ViewController program. - and of course, loadView was never being called.
Just to help some other dork that makes the same mistake....
Best Regards,
Charles
viewDidLoad only if the view is unarchived from a nib, method is invoked after view is set.
loadView only invoked when the view proberty is nil. use when creating views programmatically. default: create a UIView object with no subviews.
(void)loadView {
UIView *view = [[UIView alloc] initWithFrame:[UIScreen
mainScreen].applicationFrame];
[view setBackgroundColor:_color];
self.view = view;
[view release];
}
By implementing the loadView method, you hook into the default memory management behavior. If memory is low, a view controller may receive the didReceiveMemoryWarning message. The default implementation checks to see if the view is in use. If its view is not in the view hierarchy and the view controller implements the loadView method, its view is released. Later when the view is needed, the loadView method is invoked
again to create the view.
I would strongly recommend you use interface builder for at least your initial Window/View.
If you create a new project in XCode you should be able to select from one of many pre-defined iPhone templates that come with everything setup.
Unless I am reading this wrong, you did not associate any view with the the controller's view property like this
myViewController.view = controllersView;
So as far as Cocoa is concerned the view you are setting in the window has no controller to call loadView on. loadView is a View controller, not view, method. The view you assign to the window is not associated with any view controller. So your view controller loadView method is never called. Get it? The view you are trying to display, has no view controller associated with it.
When you use interface builder to create views you can link the UIView object you created in IB to the view property in the controller in IB which the framework automatically
But if not done in IB you have to set it