I have a UIScrollView which is added modally form a segue in UIStoryboard. I would like to access a UIScrollView in UIViewController ViewController from controller B, I tried this code:
ViewController *linkToA;
linkToA = [[ViewController alloc] init];
linkToA = (ViewController*)self.presentingViewController;
linkToA.groupPass.text = #"cool party ajdaj";
[linkToA.scroll1.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
The code doesn't give errors, but doesn't do anything.
I import the controller in this way:
#import "ViewController.h"
and in the ViewController.h I have:
#property (strong, nonatomic) IBOutlet UIScrollView *scroll1;
What is the problem??
linkToA IBOutlets will be not accesible while linkToA view controller will not be pushed to nav controller or presented modally
Related
I have a scene in the storyboard with a Container View. As you may suppose, I want its associated UIViewController to load there another UIViewController as a child view controller, and to show its view as a subview.
So, in the parent UIViewController I defined the properties:
#property (weak, nonatomic) IBOutlet UIView *containerView;
#property (strong, nonatomic) MyChildViewController *childController;
Then, in the viewDidLoad method of the parent, I do:
if (self.childController == nil) {
self.childController = [[MyChildViewController alloc] init];
}
[self addChildViewController:self.childController];
self.childController.view.frame = CGRectMake(0, 0, self.containerView.frame.size.width, self.containerView.frame.size.height);
[self.containerView addSubview:self.childController.view];
[self.childController didMoveToParentViewController:self];
Both self.childController.view and self.containerView are not nil, but self.childController.view is not displayed when I run the app... What can I be missing?
Thanks
I finally noticed what I was overlooking... since I also created a scene in the storyboard for MyChildViewController, I needed to instantiate it from there.
I am passing textfield data between two view controllers. i have two view controllers Firstviewcontroller, Secondviewcontroller. i have embed them in navigation but when i click the button on first view controller, second view controller is not showing only black screen is showing.below is my code.
First view controller.h
#import <UIKit/UIKit.h>
#import "secondViewController.h"
#interface FirstViewController : UIViewController<SecondViewControllerDelegate>
#property(nonatomic) secondViewController *secondview;
- (IBAction)btnclick:(id)sender;
#property (strong, nonatomic) IBOutlet UITextField *textfield1;
#end
First view controller.m
- (IBAction)btnclick:(id)sender {
secondViewController *SecondViewController= [[secondViewController alloc]init];
SecondViewController.data=self.textfield1.text;
[self.navigationController pushViewController:SecondViewController animated:YES];
}
- (void)dataFromController:(NSString *)data
{
[self.textfield1 setText:[NSString stringWithFormat:#"%#",data]];
}
Seconviewcontroller.h
#protocol SecondViewControllerDelegate <NSObject>
#required
- (void)dataFromController:(NSString *)data;
#end
#interface secondViewController : UIViewController
#property (nonatomic, retain) NSString *data;
#property(nonatomic,weak)id<SecondViewControllerDelegate> _delegate;
#property (strong, nonatomic) IBOutlet UITextField *textfield2;
#end
Seconviewcontroller.m
- (void)viewDidLoad {
[super viewDidLoad];
self.textfield2.text=[NSString stringWithFormat:#"%#",_data];
// Do any additional setup after loading the view.
}
whats the reason ??
You have to either use storyboard and let it intanciate the view controller for you:
[self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"]
Or you can use xib files and tell the view controller which one to load:
[[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil]
second view controller is not showing only black screen is showing
Typically, this means that the view controller has no view. Your code does not explain where secondViewController is expected to get its view from. Is there a secondViewController.xib? If there is, is it correctly configured with a view outlet? If not, what does this view controller do in order to get its view?
Note that you have done a very odd thing with capitalization: you have given your class a small letter (secondViewController), while your instance has a capital latter (SecondViewController). This is backwards and a big mistake, and you should correct it immediately. Perhaps the problem is just a capitalization problem; if you call your class secondViewController and your xib file SecondViewController, that is not a match and they won't find each other.
I see "IBOutlet" in your code, it means you created the user interface of secondviewcontroller on storyboard. I guess [[secondViewController alloc]init] does not get UI element from storyboard then the black screen is shown. You have to create instance of secondViewController by loading from storyboard file.
Basically:
you can get storyboard via storyboard file name
on storyboard, Secondviewcontroller has an storyboard id which is set in Identity Inspector and you can use it to get instance of Secondviewcontroller
You can refer this link for more detail
loading iOS viewcontroller from storyboard
Hope this can help!
I'm using a Tab Bar Controller in my project where the FirstViewController has a Mapbox map view and the SecondViewController has buttons that when pressed add a tile layer to the map view. Here's what I've tried. It creates error ***Use of undeclared identifier '_mapView' in the SecondViewController.m
//FirstViewController.h
#import <UIKit/UIKit.h>
#import <MapBox/MapBox.h>
#import "SecondViewController.h"
#import "SecondViewController.m"
#interface FirstViewController : UIViewController
#property (strong, nonatomic) IBOutlet RMMapView *mapView;
#end
//SecondViewController.h
#import <UIKit/UIKit.h>
#import <MapBox/MapBox.h>
#import "FirstViewController.h"
#import "FirstViewController.m"
#interface SecondViewController : UIViewController
- (IBAction)stationingLayerButton:(id)sender;
#end
//SecondViewController.m
- (IBAction)stationingLayerButton:(id)sender {
RMMBTilesSource *stationingMap = [[RMMBTilesSource alloc] initWithTileSetURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"Stationing20" ofType:#"mbtiles"]]];
[_mapView addTileSource:stationingMap atIndex:2];
}
}
The map calls are correct because I've tested it on a project that only uses one view controller. Now that I'm trying it on a Tab Bar Controller I get this error.
My question is
1.how do I get mapView in the FirstViewController to respond to calls in the SecondViewController?
2.Can this be done? I've imported the class files thinking this would open communication between the two but I'm stuck with this error.
Using tabbar controller you can get array on all associated view controllers.
You can find more details here: UITabbarController - viewControllers property
For example :
In a tabbar, if we have two view controllers, let say VC1 and VC2, then we can have any of these reference by using below code snippet.
Accessing VC1 reference in VC2 class implementation (VC2.m):
VC1 *myVC1ref = (VC1 *)[self.tabBarController.viewControllers objectAtIndex:0];
Now we can use public properties and methods of VC1 class and it will give the same reference which tabbar has loaded.
Hope this helps.
You basically add view controller to UITabBarController. So, if you need to access a UIViewControler in a specific tab, you need to query the UITabBarController. The following answered SO question might help you
any code example of how access viewcontroller from uitabbarcontroller?
Once you get hold of the view controller, you can pass all the data you want.
Thanks to Mrunal and Naz Mir.
I added a UITabBarController Class file and assigned it to my TabBarController. I then NSLog the array description of view controllers of the TabBarController.
//TabBarController.h
#property (strong, nonatomic) NSArray *array;
//TabBarController.m
- (void)viewDidLoad
{
NSArray *array = self.viewControllers;
NSLog(#"View Controllers = %#", [array description]);
}
I then imported the FirstViewController.h to SecondViewController.h and in SecondViewController.m I wrote...
//SecondViewController.m
- (IBAction)stationingLayerButton:(id)sender {
FirstViewController *FVC = [self.tabBarController.viewControllers objectAtIndex:0];
[[FVC mapView] addTileSource:stationingMap atIndex:2];
}
I'm doing an Ipad app. Now I have 2 viewcontrollers, ViewController has a button1 which has a popover segue to the second viewcontroller(PopoverController). Then, the PopoverController has a button2, if I click the button2, I'll receive some UIImage from my server. I want to add fews subviews of UIImageView to the ViewController to display these images if I click the button2.
The button1 works well, the PopoverController can pop up as expected. BUT when I click the button2, nothing happend. I want to know how can I pass the data between 2 viewcontrollers and how to add subviews to another one.
Some codes relating to my problem:
ViewController.h:
#import <UIKit/UIKit.h>
#class PopoverController;
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIButton *button1;
#property (strong, nonatomic) PopoverController *popoverController;
#end
PopoverController.h:
#import <UIKit/UIKit.h>
#class ViewController;
#interface PopoverController : UIViewController
#property (strong, nonatomic) IBOutlet UIButton *button2;
#property (strong, nonatomic) UIImage *tempImg;
#property (strong, nonatomic) ViewController *viewController;
- (IBAction)addsubviews:(id)sender;
#end
I can not just use [viewController.view addSubview:img1]; in the - (IBAction)addsubviews:(id)sender;method to addsubview. So someone can help me? :)
====1st update====
Someone suggest that I have to use - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender method. I have tried this one by control click the button2 and create a custom segue between button2 and ViewController. When I clicked the button2, it showed :
Terminating app due to uncaught exception 'NSGenericException', reason: 'Could not find a navigation controller for segue 'change'. Push segues can only be used when the source controller is managed by an instance of UINavigationController.'
So I'm wondering whether I should add a NavigationController. If so, what should I do?
====2nd update====
I use Paramasivan 's code now, and I found the way to call method from another viewcontroller. The problem now is the newly added subview in my viewcontroller doesn't show up. I guess I have to update my viewcontroller in order to make it visible.
in my - (IBAction)addsubviews:(id)sender; method, i invoke the method in ViewController by [self.viewController createSubViewWithImage:_tempImg];
so the method can be invoked when i click the button2, but the view of viewcontroller has nothing changed.
Add this in - (void)viewDidLoad,
self.popoverController = [[PopoverController alloc] init];
self.popoverController.viewController = self;
Make sure that in no other places, you are setting self.popoverController = ....
Do NOT add anything like self.viewController = ... in popovercontroller class. And you dont have to do self.viewController.popoverController = self; as well. Just remove these lines if you already have it.
Once these are done, make sure that you are displaying self.popoverController only in the popover and you are not creating a new object for popoverController class there. So if these are fine, you can use any approach you want for passing the image from popoverController class to viewController class.
as you mentioned in your comment you can use [self.viewController createSubViewWithImage:_tempImg]; in your popovercontroller class.
Update:
If you are doing via storyboard, you need to set this in prepareForSegue method and you dont have to create self.popoverController at all. Remove that part in your case. You can follow the procedure mentioned here to set up a custom segue and implement prepareForSegue method to pass the object. Source: On storyboards, views and passing data along
Set the name of segue in storyboard to "CustomSegue"
Implement prepareForSegue method
Inside the method, check if name of segue matches "CustomSegue" and then set the viewController in the popoverController object there as,
Try,
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"CustomSegue"]) {
PopoverController *popoverController = [segue destinationViewController];
popoverController.viewController = self;
}
}
After doing this, you need to call [self.viewController createSubViewWithImage:_tempImg]; in your popoverController class.
Check out the Communicating with Objects doc, there are several ways to do what you want.
In ViewController.h add the following
-(void)createSubViewWithImage:(UIImage *)imageDownloaded {
UIImageView *imageViewTemp = [[UIImageView alloc] initWithImage:imageDownloaded];
[self.view addSubView:imageViewTemp];
}
In PopoverController.h add the following
#property (nonatomic, retain) ViewController *viewControllerPassed;
And after image downloaded, call the following in PopoverController.h
[viewControllerPassed createSubViewWithImage:imageDownloaded];
You can pass data using the below method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ViewController2"])
{
ViewController2 *v2VC = [segue destinationViewController];
v2VC.yourData = self.someStuff;
}
}
I'd like to develop for iOS5 and have a storyboard...
I've just created UIView with UIViewController on the storyboard.
I have added a lot of other UIButtons and labels and creates outlets to VC.
I would like to use this view with it's viewcontroller 3 times on a single parent view.
How is it possible? I dont want to copy "a lot of other UIButtons and labels" ...
Maybe i should create this view out of storyboard in separate XIB? How will i use XIB in storyboard?
UPDATE:
Thanx you, Juzzz - your solution works perfect:
You have to create 2 custom viewControllers (one for each view in your story board.
example:
#interface GraphCollectionViewController : UIViewController
#interface GraphViewController : UIViewController
To connect them you can use something called: UIViewController containment
For your GraphCollectionViewController create 3 outlets for your UIViews. Then create 3 properties of GraphViewController's (or an array, what you want) and initialize them in the view did load.
#property (strong, nonatomic) IBOutlet UIView *topView;
#property (strong, nonatomic) IBOutlet UIView *middleView;
#property (strong, nonatomic) IBOutlet UIView *bottomView;
#property (strong, nonatomic) GraphViewController *topGraphViewController;
#property (strong, nonatomic) GraphViewController *middleGraphViewController;
#property (strong, nonatomic) GraphViewController *bottomGraphViewController;
...
//top graph
self.topGraphViewController = [storyboard instantiateViewControllerWithIdentifier:#"GraphViewController"]; //init with view from storyboard
self.topGraphViewController.view.frame = self.topView.bounds; //set frame the same
[self.view addSubview:self.topGraphViewController.view];
[self addChildViewController:self.topGraphViewController];
[self.topGraphViewController didMoveToParentViewController:self];
//middle graph
self.middleGraphViewController = [storyboard instantiateViewControllerWithIdentifier:#"GraphViewController"]; //init with view from storyboard
self.middleGraphViewController.view.frame = self.middleView.bounds; //set frame the same
[self.view addSubview:self.middleGraphViewController.view];
[self addChildViewController:self.middleGraphViewController];
[self.middleGraphViewController didMoveToParentViewController:self];
//bottom graph
self.bottomGraphViewController = [storyboard instantiateViewControllerWithIdentifier:#"GraphViewController"]; //init with view from storyboard
self.bottomGraphViewController.view.frame = self.bottomView.bounds; //set frame the same
[self.view addSubview:self.bottomGraphViewController.view];
[self addChildViewController:self.bottomGraphViewController];
[self.bottomGraphViewController didMoveToParentViewController:self];
I think you get the point. For more understanding this example .
You can create a new view class (with it's own .h, .m files) and base this on the ViewController you created yourself.
So as for code:
#interface ViewController : UIViewController
Let's say the above is your original ViewController that you want to use in other places.
This has buttons, labels, etc. in it.
When you create a new view class base it on your own instead of UIViewController class like this:
#interface MyNewController : ViewController
Now that MyNewController is based on ViewController you created earlier, it should have it's buttons, labels, etc. you created as well.
Edit: You might also have to change your view's base class in the storyboard.
Click on the view you want to change, look at the right hand side attributes window, under Custom Class choose your own controller, in this case ViewController.