I set an image like this to my view:
self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"map3.jpg"]];
Right now I have it in a button action method. But how do I make it set directly when the app is launched?
If you want to set the backgroundColor of a UIViewController's view, then move your code into viewDidLoad and adapt likewise:
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"map3.jpg"]];
A UIViewController doesn't have a backgroundColor directly, but its view does, like any other UIView.
One way is to put that logic within your view controller's -viewDidLoad method for the UIImageView property.
UIView
If you are in a UIView class place the code in either initWithFrame: or initWithCoder:
initWithFrame gets called when you instantiate the view from code (e.g. UIView *myView = [[UIView alloc] initWithFrame:CGRectZero];
initWithCoder: gets called whenever the UIView is loaded from an XIB file.
http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html
UIViewController
If in a UIViewController a common place to put it would be in viewDidLoad
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html
Related
Simple question about inheritance
I have a standard program with a master view:
MasterViewController.h
enter code here#interface MasterViewController : UIViewController
using a subview for drawing:
MasterViewController.m
frame = CGRectMake(xo, yo, side*width, side*height); // maxSide
backView = [[BackView alloc] initWithFrame:frame];
[backView setBackgroundColor:[UIColor whiteColor]];
[self infoToBackView];
[self.view addSubview:backView];
BackView.h
#interface BackView : UIView
and BackView.m has its drawRect:
- (void)drawRect {
:
:
}
The problem I have is that I want BackView to inherit from MasterViewController, i.e. I want
Backview.h to be
#interface BackView : MasterViewController
which allows it to inherit the variables it needs from MasterViewController.
The problem is that this does not work; BackView must inherit from UIView to be able to draw with DrawRect. Therefore, before calling the UIView BackView, I must send it the variables it needs for drawing:
[self infoToBackView];
[backView setNeedsDisplay];
where infoToBackView is a method sending the needed variables to BackView.
The $64,000 question: How can I have a BackView that inherits from MasterViewController AND has drawRect?
BackView is a View, it is design to DRAW something.
ViewController are design to manage a view Herarchy.
They are not the same things. One is a plane, the other is an aiport! You cannot fly an airport...
UIView's subclass are design to draw. If you want to draw (text, shapes..) on screen, create a subclass of UIView. If you want to manage a scene in your app storyboard, create a subclass of UIViewController.
drawRect: is a method of UIView
Now you can pass variable to your view from your viewController, like a label (another kind of View) received a text to know what to display.
For example in your ViewController, you can have:
self.myBackView.color = [UIColor blueColor];
self.myBackView.progress = .5;
self.myBackView.text = #"MVC is awesome";
For a better understanding of the MVC design pattern, please reffer to Apple doc : https://developer.apple.com/library/mac/documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html
Is there any way that I can add uiview as a subview over a view controller using UIStoryboard, using xib's we can do that, but i'm unable do that using storyboard.
My storyboard is not holding any of the uiview as a subview when I drag and drop on it, it was placing under the view controller.
Is there any way that I can add it programmatically on my view controller using storyboard.? I'm stuck please help me out
Am I right, you want to hold UIView in storyboards without view controller or superview ?
You can't do that. You should use XIBs to hold custom views.
It doesn't matter you add it programmatically or via drag and drop, in storyboards you can't hold "isolated" views, every view must have a superview and therefore a UIViewController.
Check apple's guide, make sure you understand UIViewController,UIView,UIStoryboard classes and relations between them. Also this.
Hope it helped.
Yes, you can override UIViewController's loadView method to do it as i have written code below.
Because loadView is the method which is called first of all other viewController's loading methods. So you can set it here.
Hope this will work for you as I have tested it on my code.
- (void)loadView {
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, [UIScreen mainScreen].bounds.size.height)];
self.view.backgroundColor = [UIColor blackColor];
// enter your customization code here
}
write this line in function
-(void) ViewDidLoad:
[self.view addSubView:...];
I write a simple ios app. All of my views are created programmatically.
Here is some code
rootViewController.m
-(void)loadView
{
UIView *view = [[UIView alloc]initWithFrame:[UIScreen mainScreen].applicationFrame];
self.view = view;
self.view.backgroundColor = [UIColor greyColor];
}
In appDelegate I add rootViewController view to the window and everything work fine. But if expression
self.view = view
is removed rootViewController is not loaded in window.
Why is this happening ?
Because if you don't set the view property of the view controller then the view controller's view is nil and a nil view means a blank screen.
What would you expect to happen if you try to display a view controller with a nil view?
Normally view controllers create their own empty view (or load it from a nib file) when you first reference their view property, but since you are overriding the loadView method, you have to set the view yourself.
Your code may be easier to understand if written like this - the view variable and view property having the same name may be the source of your confusion:
-(void)loadView
{
self.view = [[UIView alloc]initWithFrame:[UIScreen mainScreen].applicationFrame];
self.view.backgroundColor = [UIColor grayColor];
}
Incidentally, if you aren't using ARC, you need to autorelease the UIView above before you assign it to the self.view or you'll have a leak.
There is a UIViewController that uses a UIImageView, and that image view is initialized with image data (NSData). It does not use a XIB, but creates its view programmatically:
- (void)loadView
{
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithData:self.imageData]];
scrollView = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
scrollView.contentSize = imageView.bounds.size;
scrollView.delegate = self;
[scrollView addSubview:scrollView];
}
That data has to be set by another controller which allocs, inits, and pushes this view controller onto the navigation controller:
ImageViewController *imageViewController = [ImageViewController alloc] init];
imageViewController.imageData = someData;
[self.navigationController pushViewController:imageViewController animated:YES];
How do I know that everything that needs to be done, which in this case, is setting the data, is done before loadView is called? Or, do I not know, and I have to create a custom initializer, or somehow call loadView again when the view controller receives the data?
I have faced many similar situations where I was confused about what will happen, such as with UITableViewControllers.
How do I know that everything that needs to be done, which in this case, is setting the data, is done before loadView is called?
Because the documentation mentions that view controllers do not load their views until they are needed. And the view controller's view is not needed before the navigation controller tries to push it on screen.
Besides, the proper place for assigning the imageData to your image view is probably viewDidLoad ("If you want to perform any additional initialization of your views, do so in the viewDidLoad method."). And your loadView method will not do anything visible in its current form. You have to assign a view to the view controller's view property in that method.
loadView will happen when the view property of the view controller is accessed. The code you wrote will work fine, because the first time the view property will be accessed will be somewhere inside pushViewController.
If you wrote this you'd have a problem:
ImageViewController *imageViewController = [ImageViewController alloc] init];
NSLog(#"size = (%.0f, %.0f)", imageViewController.view.frame.size.width,
imageViewController.view.frame.size.height);
imageViewController.imageData = someData;
[self.navigationController pushViewController:imageViewController animated:YES];
because you access the view property in the NSLog. That would cause loadView to get called before imageData was set.
My code is working so far but I had to create a Class for the UIView. This is a bit inconvenient because I need to interact with the ViewController too.
BTW, I did try [self setNeedsDisplay] on the ViewDidLoad of the UIViewController subclass file but it didn't work.
Here's the code, which works on UIView Subclass but doesn't get called on a UIViewController one:
- (void)drawRect:(CGRect)rect
{
UIColor *currentColor = [UIColor redColor];
CGContextRef context = UIGraphicsGetCurrentContext();
someNum = 1;
CGContextBeginPath(context);
CGContextMoveToPoint(context, 30, 40);
[self addDotImageX:30 andY:40];
CGContextSetLineWidth(context, 2);
CGContextSetStrokeColorWithColor(context, currentColor.CGColor);
CGContextStrokePath(context);
}
Any ideas on what to try? BTW, this is a TabBar App. I know those can somehow block the calls to drawRect.
The Tabs where created programatically, not through a Nib. Eg:
NSMutableArray *listOfViewControllers = [[NSMutableArray alloc] init];
UIViewController *vc;
vc = [[Education alloc] init];
vc.title = #"Education";
[listOfViewControllers addObject:vc];
vc.tabBarItem.image = [UIImage imageNamed:#"info.png"];
[vc release];
I would appreciate any ideas. I've been through the answers on this site related to setNeedsDisplay not calling drawRect and haven't found an answer for my particular case.
Thanks.
You are mixing up two classes. A UIViewController is not a UIView, meaning it doesn't inherits from UIView. But the good news is it has a view, declared as property: It's composition. The drawRect method is only available in a UIView class/subclass.
If you like to force the controller's view to redraw you can call
[self.view setNeedsDisplay];
in the viewController.
You can set your own custom view as the view of your viewController with the loadView method. It could look like this:
- (void)loadView
{
MySubclassOfUIView *rootView = [[MySubclassOfUIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// do more view configuration ...
self.view = rootView;
[rootView release];
}
So you can keep your drawing code separated in your MySubclassOFUIView.m file.
About the UIViewController:
The UIViewController class provides
the fundamental view-management model
for iPhone applications. The basic
view controller class supports the
presentation of an associated view,
support for managing modal views, and
support for rotating views in response
to device orientation changes.
And the purpose of a UIView:
The UIView class defines a rectangular
area on the screen and the interfaces
for managing the content in that area.
At runtime, a view object handles the
rendering of any content in its area
and also handles any interactions with
that content.
Have a look at Cocoa Core Competencies / Model-View-Controller in Apple's official documentation, it describes the MVC design pattern.
You can't override drawRect in a UIViewController, because UIViewController doesn't have a drawRect method.
As I understand, you're making some custom drawing, so it's ok for you to subclass UIView (though if you can have the same results without doing so, it's better). But then if you want to control its behavior, then you should subclass UIViewController.
Make sure you understand how MVC works!
Set your class's class which has been inherited from UIViewController in the interface builder
class which is inherited from UIView and don't override the -drawRect: method in the class which has been inherited from UIViewController. Define the -drawRect: method in the class which has been subclassed from UIView.