Change UIViewController to UIView - iphone

I am new at iOS development,
I want to draw a line in my app, i created a simple viewbased application,
I came to know that for drawing a line we require - (void)drawRect:(CGRect)rect method, but this method is available in UIView not in
UIViewCOntroller
How to change my class to UIView ?
Here is my code snippet,
// .h file
#interface Financial_Calc : UIViewController{
UIButton *firstBtn,*secondBtn;
}
#end
//.m file
#implementation Financial_CalculatorViewController
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)drawRect:(CGRect)rect {
NSLog(#"drawRect");
}
#end
Any help will be appreciated

You need to keep the view controller you have, and make a custom view class for it to control.
Choose File > New Fileā€¦
From iOS, Cocoa Touch, Choose 'Objective-C Class', Click Next
Name your class 'MyView' (or anything you like, the convention is to have view at the end)
Make your class a subclass of UIView (type UIView in the 'subclass of' field)
Click next, choose a location to create the file (anywhere in your project's folder is fine).
Add your custom drawing code to drawRect: in MyView.m
In your view controller's Xib file, select the view.
Choose View > Utilities > Show Identity Inspector
In the 'Custom Class' field, change the class field from 'UIView' to 'MyView'
Build & run - your view controller is now controlling your custom view.
It's also possible to do this without using the user interface Xib, but this should get you going.

FYI: you cannot change UIViewController to UIView. One way to do is, create a new subclass of UIView (lets say called CustomUIView). there do your coding of draw rect. and in your ViewController.m in viewDidLoad method create an object of CustomUIView Class (lets say customUIView) and do this
[self.view addSubView:customUIView];

Related

What is the simplest way to add outlet to my view controller?

When I add new view, I always do same and boring work.
If I add UIWebView, I would do follows,
add codes to header file. ( declare, property )
add codes to source file. ( synthesize, viewDidUnload, dealloc )
add UIWebView in IB and connect to the outlet in File's Owner.
[ViewController.h]
#interface ViewController : UIViewController
{
UIWebView *_webView;
}
#property (nonatomic, retain) IBOutlet UIWebView *webView;
#end
[ViewController.m]
#synthesize webView = _webView;
- (void)viewDidUnload
{
[super viewDidUnload];
self.webView = nil;
}
- (void)dealloc
{
[_webView release];
[super dealloc];
}
What if I should add 3 labels and 2 buttons?
What if I have to add textview and some imageviews?
Don't you think it is boring? I would like to listen to your idea.
I hope there will be more easy and simple way to add outlet to the code.
Does anybody have a good idea? :)
When using Interface Builder, If you select an Object drag it's reference to your header, you'll see a popup where you can name it so theres less typing for you to do. As seen below:
This will automatically declare the IBOutlet UIButton *myButton for you, and insert the release and nil code into dealloc and viewDidUnload methods.
Same method also works for actions, as seen below.
Once you Connect it will automatically insert the new Action -(IBAction)cancelSelected:(id)sender into your #implementation class.
Point being, all that's boring for you to do can be done in 2 Reference connections, and inputting data into 2 fields. :)
Hope this helps!
In Xcode 4, you can simply control drag from a UI element to the .h/.m file. If you drag to the .h, Xcode will create a property for you and synthesize that in the corresponding .m, if you drag to the .m, Xcode will stub out an IBAction method for you.
Also, I would recommend switching to ARC, to avoid having to worry about memory management.
If you are having xcode 4.0 you can create outlet property by drag and drop.
Follow the steps:
open the xcode
open you nib file where you need to create an outlet.
Click on the middle tab of the Editor which at right up corner. It will open a new file adjacent to your nib.
Make sure it is the .h file of the controller where you want to create the outlet.
Now select the control, right click on it and drag to the .h file. Name the outlet. Thats it. It will create you a property and it will synthesize it automatically.
It will also insert the code for dealloc and viewDidUnload.
Hope this help.

iOS3, iOS4, xibbed UIViewController and displaying data

I'm writing an app that will run on iOS3.0 and up.
The app has a custom UIViewController (say), which I'm instantiating from a .xib file. It's view comprises a single UILabel, which I've correctly declared and synthesized etc. in my custom UIViewController header and implementation files.
I'd like to set the text of this UILabel dynamically, and for it to be shown to the user by the time my UIViewController appears. For sake of argument please assume the text setting method is expensive.
The catch is on iOS3.0 with my UIViewController at least, -(id)initWithNibName:(NSString *) aNibNameOrNil bundle:(NSBundle *) aNibBundleOrNil returns before -(void)viewDidLoad does, but on my iOS4.0 device it's the other way around. The text label can therefore be nil when I don't want it to be.
Thus, I don't know where I can set the text in such a way as to keep both iOS3.0 and iOS4.0 happy.
Any advice here?
Can you please explain how your label comes out to be nil?
If you have taken an outlet for the label, then in either case, in the - (void)viewDidLoad method it cannot be nil, provided the label outlet is properly connected in the xib file.
If you have not taken the label outlet and doing it by code, then instantiate the label again in - (void)viewDidLoad method and set its text right over there and then add it to the view controller's view.
For more information - read the - (void)viewDidLoad and - (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle method in the UIViewController class reference

What am i missing when creating applications from window-only template?

I'm fairly new to iOS development, but catching on pretty quickly.
I'm attempting to figure out how to create universal apps from the window-only template in xcode. I THOUGHT that i could add a main view to the main_window.xib by following these steps:
Make a new window-based app template.
Go to file > new file > uiviewcontroller subclass with XIB file.
Open the main_window.xib and add a new view controller, with my new uiviewcontroller subclass as the selected NIB name in the inspector.
Control-Drag from the window object to the new view controller, and add it as the rootViewController.
I thought that from here i had something that was essentially the same as the view-based template, but when i add in a segmented view controller, add the IBOutlet/IBAction in code, and then hook up the outlets and received actions in Interface Builder, the app crashes as it launches every time.
I'm positive that i'm missing a vital step in hooking up this process and would be greatful if anyone could offer the solution, as well as some general advice when setting up these sorts of things?
Thanks.
EDIT: Solved it by doing the following:
Create new window based template.
Create UIViewController Subclass, name it whatever you want.
In AppDelegate.h, add #class YourViewControllerName before #interface
Inside the #interface for appDelegate, add YourViewControllerName *mainViewController;
Then outside the #interface add #property (nonatomic, retain) IBOutlet YourViewControllerName *mainViewController;
In AppDelegate.m add in #import YourViewControllerName.h at the top.
Add #synthesize YourViewControllerName.
In ApplicationDidFinishLaunching add: [self.window addSubView:mainViewController.view]
Open MainWindow.xib in interface builder, drag in a new view controller from the library, and use the property inspector to change it's class to be YourViewControllerName, and select the corresponding NIB file from the drop-down menu.
Control drag from the app delegate, which is the yellow box in IB, to your new;y created view controller, and hook up the mainViewController outlet you created.
VOILA! done. Solved all my problems.
Many many thanks for the help guys.
Make an IBOutlet for your custom view controller, called viewController of type MyViewController (or whatever you want your class to be named) in your app delegate, and make MyViewController subclass UIViewController. Next, in the MainWindow.xib file, add a new view controller from the library, being sure to set the class of this view controller to MyViewController (or whatever your class name is). Next, hook up the viewContoller outlet to the view controller in the MainWindow.xib file, and in your applicationDidFinishLaunching method, add this:
[window addSubview:viewContoller.view];
That should do it!
this s my documentation ,this may helps you.....
create Window Based Application (name as your wise)
2.create UIviewcontroller class(.h & .m) with nib file
3.open appdelegate.h and import " view controller .h"(which created in step2)
ADD #class [view controller class name] before (#interface appDelegate )
ADD within #interface appDelegate
view controller class name *alias Name;
#property (nontoxic,retain)IBOutlet view controller class name *alias Name;
4.open appdelegate.m
1.#synthesize aliasname;
2.
-(void)applicationDidfinishLaunching:(UIApplication *)application
{
[window addsubView: aliasname.view];
[window makekeyAndVisible];
}
5.open mainwindow.xib
1.add UIviewcontroller from library
2.open property for UIviewcontroller ,add nib file name and class name
3.link window object with Uiviewcontroller using property

Using a custom UIView from multiple view controllers

I have created a custom UIView that I would like to use on multiple different view controllers in my iPhone application. Currently, I have copied the UIView that contains the controls from the nib file for the first view controller, pasted it into the other view controllers, and then wired up all of the actions to each view controller. This works fine, but is not the optimal way that I would like to use this custom view.
My custom view is reasonably simple, it consists of some UIButtons with labels, and tapping on these buttons fires actions that changes the contents of controls on my view controller's view.
What would be a strategy to consolidate the definition and usage of this UIView? Ideally, I would like to just reference this custom view from the nib of view controllers, and have my view controller respond to actions from this custom view.
EDIT: OK, based on J.Biard's suggestions, I have tried the following with not much luck.
I created another UIView based nib file with the contents (for now just some UIButton objects) of my reusable view and UIView subclass .m and .h files, and then set the nib File's Owner class to my newly created class name.
Then, I added most of the code from J.Biard (I changed the rect to 50,50,100,100, left out the setDelegate out for now, as I am just trying to get it working visually for now, and i found that [self.view addSubview:view] worked much better than [self addSubView:view]) to the end of the viewDidLoad method of the first view controller that is displayed when the app fires up.
And what I get now is my main view with a black square in it. Have I missed an outlet somewhere, or is there some initialization needed in initWithFrame or drawRect in the UIView subclass?
Create your MyCustomView class and nib file.
In the nib file, set Files Owner to MyCustomView - then design your view as normal, with a top level UIView. Create an IBOutlet in MyCustomView to link to your top level UIView in your nib file.
In MyCustomView add this method:
- (BOOL) loadMyNibFile {
if (![[NSBundle mainBundle] loadNibNamed:#"MyCustomView" owner:self options:nil]) {
return NO;
}
return YES;
}
In your view controllers you can use this custom view like so
- (void)viewDidLoad {
MyCustomView *customView = [[MyCustomView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[customView loadMyNibFile];
[self.view addSubview:customView.view]; //customView.view is the IBOutlet you created
[customView release];
}
You could also create a convenience class method on MyCustomView to do this if you liked.
If it is very simple I would recommend that you create a subclass of UIView in code and create instances of this class (or you can use Interface Builder to create the custom UIView that is then archived into the NIB file and restored later on also using code).
Using the code solution you could create instances of your custom UIView in your controller by calling something like:
#import "MyCustomView.h"
// let the superview decide how big it should be or set it as needed.
CGRect sizeRect = CGRectMake(0,0,0,0);
// create an instance of your view
MyCustomView *view = [MyCustomView alloc] initWithFrame:sizeRect];
// set a custom delegate on the view or set callback methods using #selector()...
[view setDelegate:self]; // self = view controller
// add the view to the controller somewhere... (eg: update CGRect above as needed)
[self addSubView:view];
// don't forget to release the view somewhere ;-)
This example assumes that you create a delegate protocol that your View Controller can respond to or you can wire up events dynamically using #selector. If you don't want to create instances of the view in code you could add a "UIView" to your NIB file and set it's class type in the inspector window (command -> 4 -> class dropdown).
If you want to do everything in interface builder you can create your custom UIView and use something like "- (NSArray *)loadNibNamed:(NSString *)name owner:(id)owner options:(NSDictionary *)options" (see NSBundle) to load the NIB file dynamically. This presents it's own challenges though it is also feasible.
The most involved option would be to create your own xcode custom UI library / plugin so that your custom control / view could be dragged into each NIB file from the Library window like any other control shipped by Apple.
Hope this clarifies or eliminates some options for re-using controls for you.
Cheers-

iPhone Views at Runtime?

I am new to the iPhone SDK and am trying to create 3 views and switch between them. Data will come from a server and I will basically be showing 1 view and caching the other two. So far I am just trying to create a view and display it at run-time. My code is listed below. It shows only a blank screen and I think I am missing a key concept. Any Help?
#import <UIKit/UIKit.h>
#import "ImageViewController.h"
#interface Test5ViewController : UIViewController
{
IBOutlet UIView *rootView;
ImageViewController *curImage;
ImageViewController *nextImage;
ImageViewController *prevImage;
}
#property(nonatomic,retain) IBOutlet UIView *rootView;
#property(nonatomic,retain) ImageViewController *curImage;
#property(nonatomic,retain) ImageViewController *nextImage;
#property(nonatomic,retain) ImageViewController *prevImage;
#end
and
- (void)loadView
{
self.curImage = [[ImageViewController alloc]initWithNibName:#"ImageView" bundle:[NSBundle mainBundle]];
UIImage *pic = [UIImage imageNamed:#"baby-gorilla.jpg"];
[self.curImage assignImage:pic];
self.rootView = self.curImage.view;
}
and
#import <UIKit/UIKit.h>
#interface ImageViewController : UIViewController
{
IBOutlet UIImageView *image;
}
-(void)assignImage:(UIImage *)screenShotToSet;
#property(nonatomic,retain) IBOutlet UIImageView *image;
#end
Welcome to the iPhone SDK!
In general, there are two ways to get any view displayed.
First, and most commonly, you use a NIB file created by the Interface Builder. This is usually the easiest way to get started and I would recommend it for what you're trying to do here. It's too lengthy to describe all the steps you need to do for what you have here, but basically start in xcode by creating a new file and selecting "user interfaces" and choose View XIB. This will create a basic NIB file (they're called NIBs rather than XIBs for historical reasons). The first step in interface builder is to change the class name of the "File's Owner" to your UIViewController subclass (Test5ViewController). You can then drop anything that IB will allow into the view window or even replace the pre-supplied view object with one of your own. And here's the trick: make sure the view outlet (supplied by the UIViewController superclass) is connected to a view. Once this is done, this view will be automatically loaded when your NIB is loaded. You can then just put your UIViewController subclass (Test5ViewController) in your MainWindow.xib NIB file to get it automatically loaded, and you're in business.
Now, the way you're doing it here is the second way. Some people like to code this way all the time and not user interface builder. And while it's definitely necessary sometimes and always more flexible, it makes you understand what is happening a bit better. There may be other things, but the main thing you're missing is that in your code above, you have nothing that is adding your view into the view hierarchy. You need to check first that you have an UIApplicationDelegate subclass and it needs to load your "root" UIViewController class. All initial project creation types in xcode do this (except Window-based application). It is code like:
[window addSubview:rootController.view];
Once this is done, if your view controller wasn't loaded by the NIB (described briefly above), your loadView method will be called, expecting you to build your own view hierarchy. Above, you created the view(s), but failed to put them in a hierarchy. You need something like:
[self.view addSubview:curImage.view];
No view will be rendered until added to the view hierarchy. Make sure to look up the UIView class in the documentation and understand the variety of ways to add and remove views to the view hierarchy.
A couple things I should warn you about:
* your code above is leaking. You need to review how objective-C properties work. There's lots on this site about it. More than I have time to write about here.
* don't create a rootView property in the case you have here. There already is one in the superclass (UIViewController). It's just 'view'. Use that for saving your root view.
I hope this helps you get started. It can be bewildering at first, but you'll soon get it going! I recommend building and rewriting and rebuilding a lot of sample code before you do your "real" application. The SDK has many great samples.