I've a tableviewController in a class which I need to present modally from another class. In the modaltableview class, I'm creating tableview in viewDidLoad and apart from this there are tableView delegate methods in this class.
My question is how do I present this class object to show this tableViewController modally?
I've presented the viewController from same class as:
UIViewController *vw = [[UIViewController alloc]init];
[self presentModalViewController:vw];
But what to write for a viewController from another class? Shall I call presentModalViewController from this class or the modaltableViewControler class?
P.S. I'm having a modalViewController already on the current viewController where I've to present the new modalTableView.
Thanx in advance.
In the visible view controller, create and initialise an instance of your modal tableViewController. Then, still in the visible view controller, call [self presentModalViewController:<THE TABLE VIEW CONTROLLER YOU JUST INITIALISED> animated:YES];
Hope this helps!
-jrtc27
Related
I created my iOS app with Tab Bar template, so here is UITabBarController with bar buttons. An issue is how to set it as delegate. I found at SO that it has to be set programmatically in AppDelegate, but I believe it's impossible, because I've got no access to Tab Bar Controller as outlet.
I added proper value to #interface (both ViewController and AppDelegate), but doesn't know what to do next.
#interface ViewController : UIViewController <UITabBarControllerDelegate>
I hope I don't have to get rid of whole app template and it's possible to set Tab Bar Controller created in IB to be delegate.
Exactly I want to make it delegate to create on tab select event like this:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController;
Any idea?
You can quickly and easily create a new TabBarController Delegate class and connect it as the delegate in the storyboard.
Create a new class :
class TabBarControllerDelegate: NSObject, UITabBarControllerDelegate {
In IB, add an object from the object library to the list of View Controller on the left (note: search "object", it's a yellow cube).
Change the class of this object (your yellow cube in IB) to TabBarControllerDelegate
In IB navigate to your Tab Bar Controller Scene. From the Connection Inspector, drag the delegate circle to the new object you added in Step 3.
Implement your delegate methods in your TabBarControllerDelegate class. Done!
func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController)->Bool {
println("Selected a new tab")
}
I don't remember exactly the Xcode's Tab Bar template set up, but in your AppDelegate you can access to your window's rootViewController, cast it to a UITabBarController, and then set its delegate to your AppDelegate or to any other view controller.
Something like this:
UITabBarController *tabBarController =
(UITabBarController *)[[self window] rootViewController];
[tabBarController setDelegate:self]; // In this example your app delegate would implement the UITabBarControllerDelegate protocol.
EDIT
If you want to set your ViewController instance as the delegate:
UITabBarController *tabBarController =
(UITabBarController *)[[self window] rootViewController];
// I assume you have your ViewController instance set as the first view controller of your tab bar controller
// No need for a cast here since objectAtIndex: returns id, but of course you must implement the UITabBarController protocol in your ViewController.
[tabBarController setDelegate:[[tabBarController viewControllers] objectAtIndex:0]]];
EDIT 2
From your ViewController itself you can set the tab bar controller's delegate as rdelmar comments.
Just keep in mind that this cannot be done in the init method because the view controller is not in the tab bar controller yet. The proper place would be viewDidLoad but therefore it will not be executed until the ViewController view loads...
self.tabBarController.delegate = self;
0 lines of code
Drag an Object and subclass it
Xcode > Show File Inspector > Custom Class.
Class: TabBarControllerDelegate.
Set delegate to that Object
Put your existing code in that Object
This is the code you already have in your current UITabBarControllerDelegate.
class TabBarControllerDelegate: NSObject, UITabBarControllerDelegate {
// Delegate code goes here
}
What about create a viewController lets say MyTabController subclass UITabBarController
#interface MyTabController : UITabBarController<UITabBarControllerDelegate>
and set the tab Controller's class in you storyboard to MyTabController instead of UITabBarController, then put self.delegate = self; in your viewDidLoad
implement:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController;
and here you are.
Edit:
If you find self.delegate = self; is odd, which it is, you can create an outlet in your MyTabController
IBOutlet UITabBarController *tabBarController; and connect it to the tab controller in your storyboard.
Then you can put tabBarController.delegate = self;
how do i pass a value to a table view controller that has a navigation controller?
i have code to push the new view controller and make it active but no way of passing a value to the table view.
UIViewController *newTopViewController = [self.storyboard instantiateViewControllerWithIdentifier:identifier];
the problem is that i dragged a navigation controller onto the storyboard and it came attached to a tableview. i linked that tableview to my custom tableview class. When i instantiate the view controller from the name "nav", which is the storyboard id of the navigation controller, i get the navigation controller as the view controller being instantiated (newTopViewController); so how do pass a value from where i instantiate the view to the tableview controller?
I know this is already answered (nicely done ttarules), but I thought I'd pass along some extra comments. It's very common to have some type of view controller embedded in a navigation controller. Wrapping a standard view controller in a navigation controller then doing a modal segue to it, gives you a modal scene, with a nice nav bar to put buttons in, etc. Also on the iPad, replace segues can commonly use navigation controllers. It's all about how you design things, but if you know how the controllers stack up and how to easily reference them, you will have more design options. Here is a snippet you can use in your prepare for segue method to easily detect it.
if ([segue.destinationViewController isKindOfClass:[UINavigationController class]]) {
//note: have to get reference to next vc through nav controller
self.nextViewController = [[(UINavigationController*)segue.destinationViewController viewControllers]lastObject];
}
else {
self.nextViewController = segue.destinationViewController;
}
You should pass it inside prepareForSegue if your already going to be segueing to that VC.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString:#"whateverYourSegueIsCalled"])
{
YourTableViewController *tableView=(YourTableViewController*)segue.destinationViewController;
tableView.anyPublicProperty = yourValue;
}
}
EDIT:
Okay so since you actually just have the tableView embedded, you simply need to access the viewControllers property of the navigationViewController..
So it will be something like this inside your navigationViewController class:
YourTableViewController *tableView = (YourTableViewController*)[self.navigationController.viewControllers objectAtIndex:0];
tableView.yourPublicProperty = whateverValueYouWant;
-Your tableView will be the object at index 0 unless you have other VC's also embedded..So you can just print out your vc's and then figure it out from there if you do.
I have a view that shows a map. I have a custom subclass of UIViewController (DetailViewController) that gets shown when the detailDisclosureButton of the callout above the pin is pressed. While in my map class, I create my detailview and add it to the subview like this:
DetailViewController *detailView = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
detailView.locationPoint = locationPoint;
detailView.locationCoordinate = locationCoordinate;
[self.view addSubview:detailView.view];
[detailView release];
My DetailViewController has a TableView and parses the data in DetailViewController. However I get an error of sending the numberOfSectionsInTable message to a dealloc'd instance. I'm assuming it is this since I originally had this as a property and it worked fine with (nonatomic, retain). I'm assuming that I'm releasing it before the next view is done with it. If that is the case, when would I clean up the memory??? It seems like this would be the place to do it. Thanks.
I am not sure what makes you adding the view of DetailViewController into this mapviewcontroller's view. Don't you think right approach would be to either presentModalViewController or pushNavigationController?
DetailViewController *detailView = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
detailView.locationPoint = locationPoint;
detailView.locationCoordinate = locationCoordinate;
//[self.view addSubview:detailView.view];
[self.navigationController pushViewController:detailView animated:YES];
//OR
[self presentModalViewController:detailView animated:YES];
[detailView release];
You are getting the error because you are only using the view and deallocating the view controller immediately and hence tableview datasource and delegates are hitting a nil object.
Views do not retain their view controllers. Someone needs to retain the VC or else it will get released, and then the app will crash when the view makes a call into its delegate. When you use a navigation controller, the navcon has a stack of view controllers that it retains. Likewise with presentModalViewController, the OS takes care of retaining the detail VC.
Adding a detail view as a subview is not the normal way to navigate to a new view. Instead, one either uses a navigation controller and [navcon pushViewController::], or a modal subview and [self presentModalViewController::]. If the detail view occupies only a portion of the parent view, then it is normal to retain the view controller for the subview within the parent controller. That is, within the parent VC (your map class) add a property for the detail VC. Actually, it's more common to not even use a VC for a subview, but rather for screen-filling detail views.
I have a viewcontroller and i am adding a subviewcontroller in that. Now i want to set value for a string from subviewcontroller which is in its superviewcontroller.
Please Suggest some idea
Thank You
if you want to access superview use the statement said by Jhaliya,
If you want to access superviewcontroller property frm subviewcontrller property ,
use
id mainViewController = [self.view.superview nextResponder];
here mainViewController is the superviewcontroller reference.
There a parentViewController property in UIViewController class reference,
This property is used for navigation, tab bar, and modal view controller hierarchies.
The above syntax is used for when you are setting a view as subview to a parentviewcontroller
You can access the super view controller using the parentViewController property on every UIViewController.
UIViewController *parent = self.parentViewController;
You can use superView method of UIView to access its parrent.
UIView *mySuperView = [MySubView superView];
use superview property of UIView.
UIMyView* mySuperView = (UIMyView*) myView.superview ;
mySuperView.mytextString = #"Assign string to super view";
EDITED:
You could get the list of all your UIViewController by using methods of UINaigationController .
Also current visible controller and top view controller,
Read the documentation for UINavigationController .
I'm trying to essentially re-implement the UISplitViewController (because it has its limits), but when I create a UIViewController viewController, and then do an "[viewController.view addSubview contentViewController.view]" on it, to add a view that already has a view controller, that content view doesn't seem to get initialised by its view controller. I guess its view controller is getting detached or deallocated, is this the case?
Can you post your code?
UIViewController* myController = [[UIViewController alloc] initWithNibName:#"myView" bundle:nil];
myViewClass* cellView = (myViewClass*)cellController.view;
[self addSubview:cellView];
The above code will add a subview using the view in the "myView" nib.
Ensure that in the nib file -
The view is of myViewClass
the File's Owner is UIViewController and
its view outlet is connected to the view.