This is the first time I have tried to do this and I understand the concept of what I am trying to do but just not 100% sure on how to execute it.
I have a main view and a sub view.. the main view has several custom uitableviewcells each with a single textlabel. when the cell is selected it loads the subview onto the navigational stack, their is a list of standard uitableviews that I have loaded with values from the database.
When you select one of these uitableviewcells in the sub view, I want to capture that value pop the current view from the stack and then load the selected value of the subview into the main tableviews cell that was originally selected..
In the sub view I am thinking something along the lines of
MainViewController *mvc = [[MainViewController alloc] initWithNibName:#"MainViewController" objectAtIndex:indexPath.row]];
[self.navigationController pushViewController:mvc animated:YES];
[mvc release];
But this obviously this isnt passing any values around...
You want to use delegation, if you don't know how to use it, this link might help:
http://cocoadevcentral.com/articles/000075.php
So the general idea is that your main view will be the delegate of your subview, and the subview will tell it's delegate when a cell was tapped and pass in that variable (for example: [delegate cellChanged:cell];), then the main view (the delegate of the subview) will handle that.
Related
Relatively basic issue, but I spent whole day figuring out without any success. I have ViewController with main fullscreen View and separate TableViewController with TableView which does not cover the entire screen. I need to use UIRefreshControl on the TableView, hence the separate TVC.
I want to achieve that on cell selection existing TableView will flip around to be replaced with another TableView (like a step 2 of user selection). I expect that the existing main View will be visible during the TableViews transition.
I was able to achieve the full View flip transiton into different view using the begin animation/commit animation method, but never the childview only, nor using the new animation block method. Can you please suggest the animation code and how should I introduce the second tableview (under the existing TVC or under it's own TVC)?
#implementation ViewController
TableViewController *tableVC;
- (void)viewDidLoad
{
[super viewDidLoad];
tableVC = [self.storyboard instantiateViewControllerWithIdentifier:#"TableVC"];
[self addChildViewController:tableVC];
tableVC.view.frame = CGRectMake(8, 177, 304, 371);
[self.view addSubview:tableVC.view];
}
Many thanks.
See this Sample code it might help you
https://github.com/GrioSF/spincard
I have a problem with transitioning between views in different ViewControllers.
Here is the situation:
My App is a TabBarApplication done with IB which contains a UIViewController for each Tab. The UIViewController (PlayerTabViewController) of the first tab contains another UIViewController (PlayerCreationViewController) to manage a view that will be added as subview.
I was able to add the subview using
[self.view addSubview:playerCreationViewController.view];
In the PlayerTabViewController.
The problem is that from the subview I have to return to the parent view and reload it because it contains a tableview that must be refreshed.
Using [self.view removeFromSuperview]; in the PlayerCreationViewController I can switch back to the parent view, but I'm not able to reload the tableview or do other actions.
I tried to implement the -(void)willRemoveSubview:(UIView *)subview method in PlayerTabViewController but it seems the function is never called.
Do you have an Idea of what am I doing wrong?
you are using wrong method to go on next view. just use navigation view controller to switch from one view to another view.
create a object of view
PlayerCreationViewController *playerViewController = [[PlayerCreationViewController alloc] initWithNibName:#"PlayerCreationViewController" bundle:nil];
[self.navigationController pushViewController:playerViewController animated:YES];
[playerViewController release];
I wanted to add a view to the bottom of my screen. The controller is a UITableViewController, how do I shrink the tableView and add a extra view at the bottom of the tableview?
I've tried setting the frame of self.tableView in different places (viewDidLoad, viewWillAppear etc) but nothing happens. The tableView is created by IB and not programtically.
I've tried added a footer to my table view but that's not what I want, because the footer actually scrolls up, I want a static non moving View at the bottom of the screen.
I'm not saying you can't do it otherwise, but you may not want a UITableViewController for this situation. You can still have your view controller implement UITableViewDelegate and UITableViewDataSource, but place a vanilla UIView in your nib, into which you place a UITableView. Then just make sure to set the view outlet to the UIView containing your table. This has the effect of allowing you to create your additional view within IB. I just tried this and it appeared to work.
I'm guessing you're using a UINavigationController. When you push a controller onto your navigation stack, UINavigationController resizes its view to full screen, ignoring the geometry and autoresizing behavior you've defined in IB.
This resizing seems to happen after viewWillAppear:. In the past I've had some success resizing a table view and adding a sibling view in viewDidAppear:, after calling [super viewDidAppear:]. This is a bit risky though, since Apple could break it by changing how UINavigationController works behind the scenes.
A safer option is to push a view controller onto your navigation stack that controls a wrapper view. Then add your UITableView and its sibling as subviews of that wrapper view. The annoying thing about this option is that you'll probably want to use a nested UITableViewController to manage your non-full screen table view, but the documentation for UIViewController says it's designed to manage full screen views only. If you decide to ignore this admonition and nest your view controllers anyway, you'll find that viewWill/DidAppear/Disappear don't get called on the nested controller, so you'll have to manually delegate those methods from your wrapper view controller. This lack of support for nested controllers is one of my biggest pet peeves about UIKit, and I've gone to great lengths to engineer around it.
If you want to toe the line and use view controllers only for full screen views, you can push a normal view controller that controls your full screen wrapper view, manually implement all the UITableViewDataSource and UITableViewDelegate methods in your view controller, and set it as the delegate for your table view.
you want to change the -loadView method. Not viewDidLoad or viewWillAppear. This will allow you to make additional configurations with your tableview even if it is created in IB.
- (void)loadView {
[super loadView];
CGRect titleRect = CGRectMake(0, 0, 300, 40);
UILabel *tableTitle = [[UILabel alloc] initWithFrame:titleRect];
tableTitle.textColor = [UIColor blueColor];
tableTitle.backgroundColor = [self.tableView backgroundColor];
tableTitle.opaque = YES;
tableTitle.font = [UIFont boldSystemFontOfSize:18];
tableTitle.text = [curTrail objectForKey:#"Name"];
self.tableView.tableHeaderView = tableTitle;
[self.tableView reloadData];
[tableTitle release];
}
I don't know how to do it in IB but the way to do it in code is with this:
- (void) loadView
{
UITableView *tv = [[UITableView alloc] initWithFrame: rect
style: UITableViewStyleGrouped];
// finishg configuring table view
self.view = tv;
[tv release];
}
Trying to do it in two stages -- style first and then frame or frame first and then style -- neither of them works.
I think I'm missing something fundamental and so I want to ask the community for some help. I'm building an app based around a basic iPhone Utility Application. My MainView and FlipsideView share some elements so I have created separate ViewControllers and nib files for those pieces. In order to do this I have done the following:
1. Created a viewcontroller called searchDateViewController which is the file's owner of searchDateView.xib
2. searchDateView.xib is basically a UIView with a UILabel inside, the view is wired up correctly
3. Inside both MainViewController.m and FlipsideViewController.m I add a subview as folllows:
- (void)loadView{
[super loadView];
searchDateViewController = [[SearchDateViewController alloc] initWithNibName:#"SearchDateView" bundle:nil];
[[searchDateViewController view] setFrame:[searchDateView frame]];
[[self view] addSubview:[searchDateViewController view]];
...
}
Everything displays and works just fine. Basically depending on actions that happen in each of the main and flipside views the UILabel of the nib is changed. However, I wanted to do something slightly different if the searchDateViewController is loaded from the MainView or the FlipsideView. However, I can't seem to figure out which ViewController is adding the searchDateViewController subview.
In searchDateViewController I tried:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"superview %#", self.view.superview);
NSLog(#"parentviewcontroller %#", self.parentViewController);
}
In both cases I get nil.
So my question is - can I find out which ViewController is adding searchDateViewController a a subview? If so how? Or if my logic here is completely messed up, how should I be doing this?
Thanks!
viewDidLoad is invoked when the view controller has loaded its view. In your case, that happends in this line:
[[searchDateViewController view] setFrame:[searchDateView frame]];
At that moment, you haven't yet called addSubview: so it is no wonder the view's superview is nil.
To solve your problem, you should define a property inside SearchDateViewController to distinguish between the different cases. This property would then be set accordingly by the parent controller that creates the SearchDateViewController instance.
Generally, I do not think it is a good idea to use a UIViewController subclass as a controller for a view that is used as a subview of one or several fullscreen views rather than be used as a fullscreen view itself. Much of UIViewController's logic works on the assumption that it is used to manage a fullscreen view. For instance, with your design, I think it's possible that SearchDateViewController will modify the view's frame when the device orientation changes etc. Since you don't need all this functionality for a non-fullscreen subview, I suggest you subclass your SearchDateViewController directly from NSObject.
ViewController and views are completely separate.
In most cases, when you add a subview to a parent view you don't add its controller to the parent's viewController. The exception to this rule is the navigation controller which adds the controller instead of the view to maintain a hierarchy of view controllers.
Your SearchDate viewController can't find a parent controller because you never assigned one and the system does not do it automatically. You can just assign a parent controller when you evoke the view from another controller.
searchDateViewController.parentController=self;
I have a navController and tableViewController set up such that selecting a table row will push a detail view on the navController's stack and display detailed information about the row selected. In the detail view I use a single UILabel to display the info, and I set the value of the label's text property in viewDidLoad of the detail view controller.
The first time I select a row, the detail view comes up with the expected text. When I go back to the table view and select a different row, the detail view comes up with the same text as the first time.
I have seen some code samples where the detail view controller is released and then set to nil after being pushed on the navController's stack. If I add that to my code, the problem goes away, but I don't understand why.
Can someone explain to me what's going on here?
Thanks!
-viewDidLoad is called only when the... well, when the view is loaded. That is to say, when it is created in memory, which is the first time you create the view controller. Any customizations based input data should be done in -viewWillAppear: instead, which gets called every time before you push it onto the navigation controller.
Although, in general practice, I always release a new view controller immediately after pushing it onto the stack, since it doesn't belong to me any more, it belongs to the navigation controller. In this case, the next time you push it on to the stack, it will load the view again, since it's a new object.
- (void) tableView:(TableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIViewController *screen = [[MyNewViewController alloc] initWithData:[data objectAtIndex:indexPath.row]];
[self.navigationController pushViewController:screen animated:YES];
[screen release];
}
The main idea, though, is that customizing a view based on data that may change every time you see the view should be done within -viewWillAppear:. Customizing a view further than you can in Interface Builder, changing things which won't change no matter what data you're looking at, should be done in -viewDidLoad