I used containerView in static table cell on StoryBoard.
self.TableViewCell.childViewControllers[0];
self.ContentView.childViewControllers[0];
self.childViewControllers[0];
These had nothing. I want not to use custom UIViewCell.
How can I access in TableViewController?
In your viewController class you can just create array property that will keep references on childViewControllers.
If you add childViewController programmatically, you can just add reference to array in code.
If you use embed segue in storyboard, you can get childViewController by getting destinationViewController of segue in prepareForSegue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"EmbedSegue"]) {
UIViewController *childViewController = segue.destinationViewController;
[self.childViewControllers addObject:childViewController];
}
}
Related
I have 2 view controller
Main has a button
Detail has a label: lblDetail
I'm trying to pass data by segue : "sgPushDetail". When click on the button on Main, the label on Detail will be changed.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"sgPushDetail"]) {
DetailViewController *detail = segue.destinationViewController;
detail.lblDetail.text = #"you've already clicked";
}
}
But when i build, the label doesn't change. Please help me with this case!
The DetailViewController is not loaded when you are setting value for the label in prepareForSegue method. Do the following:
Create a property (i.e. NSString) in DetailViewController
Set the value for this property in prepareForSegue method
In viewDidLoad method of your DetailViewController, assign this property value to the label.
My storyboard controllers: http://i.stack.imgur.com/4LBEd.png
MenuViewController -> ChooseViewControler -> MapViewController and EditViewController.
I need to pass variable called address from MapViewController or EditViewController to MenuViewController. How i can implement this?
I try to use delegate, from this answer Passing Data between View Controllers
but dont understand, how to tell MapViewController or EditViewController that MenuController is its delegate before we push its on nav stack.
I do this at EditVC and its worked:
- (IBAction)OkButton:(id)sender {
NSString *address = addressInput.text;
MenuTableViewController *menuVC =
[self.navigationController.viewControllers objectAtIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
UITableViewCell *cell = [prevVC.tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.text = address;
[self.navigationController popToViewController:menuVC animated:YES];
}
I guess you have the classes of these viewcontrollers as
MenuViewController.h,
MenuViewController.m
ChooseViewControler.h,
ChooseViewControler.m
MapViewController.h,
MapViewController.m
EditViewController.h,
EditViewController.m
There is this method called -PrepareForSegue called when you perform a segue either programatically(performSegue method) or by using push or model in navigation controller
implement this on your source ViewController (VC) ie, if you are passing from MapViewController to EditViewController ,
Implement this in the .m file of MapViewController.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"toEditViewController"])
{
EditViewController *destinationVC=(EditViewController*)segue.destinationViewController;
destinationVC.address=self.address;
}
}
Note that you have to identify the segue which is called by its name give in the storyboard
There many be many more segues you need to prepare...you need to do all this in the same method.
identify the segue by name>prepare the methods
I'm new using storyboards and I'm facing this situation: A uinavigationcontroller contains a view controller (root controller) which contains ten buttons linked each one of then through storyboard to the same view controller.
The behavior of the second view controller depends on the button tapped in the first view controller, but how can identify which button is tapped (like tag value) and pass this info to second view controller?
Thank you.
To add on Daniel's answer:
First, add a public property onto your secondVC that is accessible from your first VC:
#interface SecondViewController : UIViewController
#property (nonatomic) int buttonTagClicked;
#end
You need to set tags up on your UIButtons. This is either done in storyboard or programmatically in your code. I would create a generic IBAction that each button is linked to. You can extract the tag off the button through the sender parameter later.
- (IBAction)buttonClicked:(id)sender
{
[self performSegueWithIdentifier:#"pushSegue" sender:sender];
}
That is linked up to
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"pushSegue"]) {
SecondViewController *destinationVC = (SecondViewController *)[segue destinationViewController];
UIButton *selectedButton = (UIButton *)sender;
destinationVC.buttonTagClicked = selectedButton.tag;
}
}
You can set a segueIdentifier for each connection. Then in your ViewController you could trigger an action based on the identifier you set.
e.g.:
If you select your connection in storyboard you can name it:
And in your ViewController you can trigger an action based on the identifier like this:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"segue1"]) {
UIViewController *destinationVC = [segue destinationViewController];
destinationVC.property = ...;
}
}
Before storyboards I was able to set delegates and datasources just by dragging an outlet to a class. With storyboards, I cannot drag the outlet to another view controller; there is no destination that will respond to it.
If I click on a view controller object, I am able to see the class owner at the bottom, but as soon as I select the other view controller containing the outlet, the old selection is gone, so I cannot connect the two.
Is this Apple's way of saying we should only connect them programmatically?
Correct. Set the delegate or other data in your prepareForSegue:sender: method. Here is an example:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Check the segue identifier
if ([segue.identifier isEqualToString:#"showDetail"])
{
// Get a reference to your custom view controller
CustomViewController *customViewController = segue.destinationViewController;
// Set your custom view controller's delegate
customViewController.delegate = self;
}
}
If your storyboard segue destination View Controller is an UIViewController then #Marco answer is right. But if your destination View Controller is a UINavigationViewController then you have to get the UIViewController from UINavigationViewController :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Check the segue identifier
if ([segue.identifier isEqualToString:#"chooseCategoryType"])
{
// Get a reference of your custom view controller if your segue connection is an UIViewController
// CustomViewController *customViewController = segue.destinationViewController;
// Get a reference of your custom view controller from navigation view controller if your segue connection is an UINavigationViewController
CustomViewController *customViewController = [[[segue destinationViewController] viewControllers] objectAtIndex:0];
// Set your custom view controller's delegate
customViewController.delegate = self;
}
}
I'm using storyboard in my ipad application and successfully able to do transitions, use segues etc.
Currently I am showing pop over view controller on click of a button. I want to detect when the pop over dismisses.
How can I do it?
Here is what I did:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"popover"])
{
UIStoryboardPopoverSegue *pop = (UIStoryboardPopoverSegue*)segue;
pop.popoverController.delegate = self;
}
}
UIPopoverController
Now with my revelation that you're talking about a UIPopoverController, here are the steps:
Setup the UIPopoverController with an appropriate delegate (I'm assuming the "sender" view controller)
Have your "sender" conform to the UIPopoverControllerDelegate
Implement the – popoverControllerDidDismissPopover: message and have any detection logic here
Implement - prepareForSegue:sender: and use the segue's destinationController to both get a reference and set the delegate, something like below:
((MyViewController*)segue.destinationController).delegate = self;
Modal View Controller
Add a delegate to the view controller that is being presented
Name your segue if you haven't already
Have your base view controller implement - prepareForSegue:sender: (refer to the UIViewController documentation)
Assign the sending view controller as the modal view controller's delegate in prepareForSegue:sender:
Call a desired method on the delegate immediately before or after you call dismissModalViewControllerAnimated:
That is how I would approach this. I would also recommend having a formal protocol to conform your sending view controller with.
Create a segue in view controller:
#property (strong, nonatomic) UIStoryboardPopoverSegue* popSegue;
In XIB, create an identifier called "popover" for the view.
In Interface, write the following code:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [[segue identifier] isEqualToString:#"popover"] )
{
//[[segue destinationViewController] setDelegate:self];
NSLog(#"%#",[[segue destinationViewController] viewControllers]);
self.popSegue = (UIStoryboardPopoverSegue*)segue;
.
.
.
}
Write the following code to dismiss the pop over by coding:
[self.popSegue.popoverController dismissPopoverAnimated:YES];
Since UIStoryboardPopoverSegueis deprecated in iOS 9, you can use a UIStoryboardPopoverPresentationSegue.
Then in prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)you can set the delegate like this:
Swift:
if let identifier = segue.identifier where identifier == "showPopover" {
let destVC = segue.destinationViewController as! UIViewController
destVC.popoverPresentationController?.delegate = self
}
An Objective-C code for the question is below.
if ([segue.identifier isEqualToString:#"home_login"])
{
UIViewController *dest = segue.destinationViewController;
dest.popoverPresentationController.delegate = self;
}
- (BOOL) popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController
{
return NO;
}