I am trying to learn something basic and very important to develop decent iPhone apps. But I don't know enough to understand what I am not getting. Here's the question:
I have a window project, with 2 views - View1, View2. On each view (thru IB) I dropped an imageView control. When I call a function in view1 I want to set the image control (show an image) of View2.
How do I do that?
There must be a simple way but I haven't managed (and did search a lot) to find a straightforward simple way to do it or at least understand the concept.
Thanks in advance.
-mE
You don't necessarily need to share the image. Is it large? Are you downloading it? In other words, does it really need to be shared?
If it does, you can just instantiate the UIImage in your app delegate and pass it to each view controller when they are created. Set a property for each view controller for the image. Something like this:
ViewController1 *controller1 = [[ViewController1 alloc init];
[controller1 setImage:image];
[[self navigationController] pushViewController:controller1];
[controller1 release];
ViewController2 *controller2 = [[ViewController2 alloc init];
[controller2 setImage:image];
[[self navigationController] pushViewController:controller2];
[controller2 release];
Then in each view controller's viewDidLoad, you can set the image for your imageView's
- (void)viewDidLoad;
{
[super viewDidLoad];
[[self imageView] setImage:[self image]];
}
I'm not sure how you're a loading your view controllers, but the above code assumes you are using a navigation controller stack. If you need clarification for a different approach, let me know.
You should connect the UIImageViews in IB to outlets in your ViewController class. In your class's .h interface file, add as appropriate:
IBOutlet UIImageView *view1;
add a property:
#property (nonatomic,retain) IBOutlet UIImageView *view1;
and in your class implementation file (.m), synthesize the property:
#synthesize view1;
Finally, you need to connect the UIImageView object in IB to that new outlet. Then you can access the image property of the UIView within your class with view1.image
Related
Bit confused with this one so bear with me...
I have a Navigation-based project which is working fine. I'm trying to create my first custom UIView to make a couple of buttons which I will use in multiple places. One of the buttons needs to push a viewcontroller into the navigation when it's clicked but I'm not sure how to do this.
When I had the button set up within a view controller I was using:
LocationViewController *controller = [[LocationViewController alloc] initWithNibName:#"LocationViewController" bundle:nil];
[self.navigationController pushViewController:controller animated:YES];
[controller release];
but the self.navigation controller won't work now, will it? How do I access the navigation controller of the viewcontroller that this uiview will be added to?
Hope at least some of that makes sense, as I said it's my first go at subclassing the uiview and adding it to multiple pages so I'm a bit lost.
EDIT TO ADD - I have the button click events inside the custom UIView, so that is where I'm trying to change the viewcontroller from. Should I instead wire up the events in whichever viewcontroller I add the view to?
Usually your appDelegate has a UINavigationController property. You can access it in your custom view like this:
UINavigationController *navController = (MyAppDelegate *)[[[UIApplication sharedApplication]
delegate] navigationController];
But more effective way is to make delegate method for your custom view and handle button action in your viewController.
MyCustomView.h
#protocol MyCustomViewDelegate
#interface MyCustomView : UIView {
id<MyCustomViewDelegate> cvDelegate; }
#property(nonatomic, assign) id<MyCustomViewDelegate> cvDelegate;
#protocol MyCustomViewDelegate #optional
-(void)didClickInCustomView:(MyCustomViewDelegate*)view withData:(NSObject*)data;
#end
MyCustomView.m
- (void)myButtonClick:(id)sender
{
[self.cvDelegate didClickInCustomView:self withData:someData];
}
So now you can handle this event in any place where is your custom
view.
Add the button from the interface builder or from the view controller's viewDidLoad using code:
CGRect frame = CGRectMake(0, 0, 24, 24);
UIButton *button = [[UIButton alloc] initWithFrame:frame];
[button addTarget:self action:#selector(handleMyButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
Then implement -(void)handleMyButton:(id)sender {}; in your view controller. Or you could instead write -(IBAction)handleMyButton:(id)sender {}; and link method and button using the interface builder.
Then inside the method just paste the block of code you posted above. If you started with the Xcode navigation controller template project it should work.
I think it's cleaner to hide the designated initializer initWithNibName: because it is an implementation detail.
When you say you are subclassing the UIView I don't know exactly what you mean. If you want to add another view controller with a custom view just use the UIViewController template and customize the XIB file, no need to subclass an UIView unless you are really modifying its behaviour, which I guess you are not. The view is a view, and the controller stuff like handling buttons should be in the controller.
The actual controller need to be in the navigation controller stack to be able to push another controller.
Or you can make a new navigation controller instance and push your LocationViewController.
I have a simple question that I couldn't see it answered on the whole site,
One XIB file that has a UIView as the main,
in it has another UIView that's connected to one IBoutlet so I can assign it later to load a view from another XIB file. That assignment doesn't work.. it remains blank...
#interface Subclass : UIViewController {
UIView *view1;
}
#property (nonatomic,retain) IBOutlet UIView *view1;
#end
i linked view1 to the subview in the xib file
in implementation in initWithNibName I'm loading Other XIB file and use it's view and assigning it to the view1. Still this doesn't work...
detailControler = [[XibViewControler alloc] initWithNibName:#"XibViewControler" bundle:nil];
//one aproach
[self.view1 addSubview: detailControler.view];
//another aproach
[self setView1:detailControler.view];
If I'm adding the subview programaticaly to [self.view addSubview:detailControler.view] and set a frame to it, it will go fullscreen, and hide the original view.
I also had a different approach that didn't work
How to load multiple views on each button tap when using a UISegmentedVIew
This is how I usually set up a UIView inside another view, although I'm not entirely sure if it's best practice or anything like that:
if(newViewController == nil){
newViewController = [[NewViewController alloc] initWithCoder:nil];
}
newViewController.view.autoresizingMask = UIViewAutoresizingNone;
if([newViewController.view superview] == nil){
[view1 addSubview:newViewController.view];
}
Hope that Helps!
I have application
I want a button to open another screen with done button
after click this button a data be transfered from the current screen to the previous one
like opening options screen , how to let the main view know the changes be done on this subview
Best regards
You can use properties for this.
Create a property in the second class: .h file
#interface DetailViewController : UIViewController {
NSString *head;
}
#property(nonatomic,retain)NSString *head;
#end
in .m file
#synthesize head;
Now in your firstviewcontroller or first class
if (dt==nil) {
DetailViewController *d = [[DetailViewController alloc]initWithNibName:#"Detailview" bundle:nil];
self.dt = d;
[d release];
}
dt.head=itemsum;
[self.navigationController pushViewController:self.dt animated:YES];
Suppose you have to pass NSString to other class then declare one Nsstring in second class and make accessor method for nsstring and then call this code from first view controller
yournextviewcontroller *viewcontroller = [[yournextviewcontroller alloc] initWithNibName:#"yournextviewcontroller" bundle:nil];
viewcontroller.Stringname = name;
[self.navigationController viewcontroller:evernotebook animated:YES];
You can take UIView as IBOutlet in the same ViewController. Show that view with click on Button like
IBOutlet UIView *yourAnotherScreenView; //Bind this to your view in XIB file.
[self.view addSubView:yourAnotherScreenView];
[self.view bringSubViewtoFront:yourAnotherScreenView];
Take Done button on the view and wireup the action event in the same controller and do the necessary stuff as required.
Use the simple delegate concept of Objective-C .
Check very simple answers in the below post for using delegate in Objective-C .
How do I set up a simple delegate to communicate between two view controllers?
I have an image I want to display inside a UIView. In Interface Builder, the UIView is the root and a UIImageView is its child.
The view is connected to view controller's view outlet, and the image view is connected to the image view outlet:
#property (nonatomic, retain) IBOutlet UIImageView *imageView;
If I try to set the image property of UIImageView before it's visible, the image doesn't show up.
TestView *testView = [[TestView alloc] initWithNibName:#"TestView" bundle:nil];
testview.imageView.image = [logos objectAtIndex:indexPath.row];
[self.navigationController pushViewController:testView animated:YES];
If, however, I pass the image to the controller and set the image property in viewDidLoad, the image becomes visible.
TestView *testView = [[TestView alloc] initWithNibName:#"TestView" bundle:nil];
testview.image = [logos objectAtIndex:indexPath.row];
[self.navigationController pushViewController:testView animated:YES];
- (void)viewDidLoad
{
[super viewDidLoad];
imageView.image = image;
}
What is causing the image to not show up in the first scenario?
The iOS documentation for a UIViewController's initWithNibName:bundle: method states that:
…
The nib file you specify is not loaded right away. It is loaded the first time the view controller’s view is accessed. If you want to perform additional initialization after the nib file is loaded, override the viewDidLoad method and perform your tasks there. …
A consequence of the nib/xib file not being loaded immediately (i.e. it uses so called lazy loading) means that the imageView IBOutlet property in your TestView controller is still nil when you try to set it in your first example.
In your second example you are setting it in the viewDidLoad which is called after the nib/xib file is loaded, and therefore it works as you expect.
I'm trying to keep my code clean and keep the number of files down. I am using a UITableViewController and I would like to load another view on top of it. I thought this would be pretty simple:
(1) create an IBOutlet in my .h file
#interface MyViewController : UITableViewController {
...
UIView *downloadView;
...
}
...
#property (nonatomic, retain) IBOutlet UIView *downloadView;
...
(2) link it to my view in IB
(3) do something like:
self.view = downloadView;
or
[self.view addSubview:self.downloadView];
But that doesn't work for me. If I do
[self.tableView removeFromSuperview];
Then the table view goes away but I don't know how to add my view from my nib. I'm doing everything for tableView programatically but I didn't think that would matter. And with UITableViewController subclassing UIViewController I thought it would be no problem using addSubview or something like that. What am I missing? This shouldn't be that hard right?
Update:
So if I do the following:
UIView *newView = [[UIView alloc] initWithFrame:self.view.frame];
newView.backgroundColor = [UIColor greenColor];
[self.view addSubview:newView];
It does (mostly) what I want. So does this mean I'm messing something up with the way I'm connecting my view from IB? In IB I set the fileOwner's class to MyViewController and I make a connection between downloadView and the view that I created (in IB). That's all I should have to do right?
I think it's an issue of where in the hierarchy you're adding the view. You can try this:
[UIWindow addSubview:self.downloadView];
and see if it appears. Or perhaps,
[self.tableView addSubview:self.downloadView];
Otherwise I think you have the right idea.