I use the "jazzHands" keyframe animation library to help my App finish the introduction view.jazzHands link
In the official example, it use a init method to configure the subViews. But I found when I use the viewDidLoad or viewWillAppear or view...,etc methods to configure the subViews, the subView will never add to the superView(self.scrollView), in here, self.scrollView is a subView in the self.view, see the original code below:
#import "IFTTTAnimatedScrollViewController.h"
#implementation IFTTTAnimatedScrollViewController
- (id)init
{
if (self = [super init]) {
self.animator = [IFTTTAnimator new];
self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
self.scrollView.delegate = self;
[self.view addSubview:self.scrollView];
}
return self;
}
But I found that you can add a subView to the self.view and it works! Why??
help me......
I solved it.....
The reason that I can't add the subView through the viewDidLoad method is that the self.scrollView has already release(nil)
Related
when set self.view.tag is 10 in loadView ,but in viewDidload it's tag is 0
why ? thanks
- (void)loadView
{
[super loadView];
NSLog(#"loadView %d",self.view.tag);
[self.view setTag:10];
self.view = [[UIView alloc] initWithFrame:self.view.frame];
self.view.backgroundColor = [UIColor yellowColor];
}
#pragma mark view loaded
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"ViewDidload %d",self.view.tag);
[self.view setTag:10];
}
The loadView method is not usually implemented. The system calls it in order to create your view hierarchy. At the time it's called, your views will not exist.
Why are you implementing loadView? You probably should not be.
To quote the docs:
If you use Interface Builder to create your views and initialize the
view controller, you must not override this method.
What code are you putting in your loadView method?
I'm sure this is some stupid mistake, but i'm trying for the past hour to remove a subview from my superview without any success.
On my first view i'm having
UIViewController *helpView = [[[UIViewController alloc] initWithNibName:#"HelpView" bundle:nil] autorelease];
[self.view addSubview:helpView.view];
And then inside helpView i have a button which is connected to an IBAction called "closeHelp" which just does the following:
- (IBAction) closeHelp{
[self.view removeFromSuperview];
}
But this causes my app to crash with EXC_BAS_ACCESS for some weird reason, even those this is inside the HelpView, meaning self.view should be pointed to the correct subview..
Would appreciate your help
Thank you.
Shai.
As Andreas answered, you are trying to remove self.view from its super/parent view.
You basically need to remove the helpView from its parent view.
so it should be
- (IBAction) closeHelp{
[helpView removeFromSuperview];
}
But we dont know what is "helpView" in the above method. As we dont have any handle for it.
So our code should finally look like this.
#define HELP_VIEW_TAG 101 // Give tag of your choice
HelpView *helpView = [[HelpView alloc] initWithNibName:#"HelpView" bundle:nil];
helpView.view.tag = HELP_VIEW_TAG;
[self.view addSubview:helpView.view];
[helpView release];
- (IBAction) closeHelp{
UIView *helpView = [self.view viewWithTag:HELP_VIEW_TAG];
[helpView removeFromSuperview];
}
The self.view does not point to your subview but the root view which your uiviewcontroller manages. You should probably remove only the last object in the subview stack, not the whole view, because now you are removing the whole help view.
Anyway, why do you not present the viewcontroller modally instead of doing this?
[self presentModalViewController:helpView animated:NO/YES];
helpView. modalTransitionStyle = //One of the constants below
UIModalTransitionStyleCoverVertical
UIModalTransitionStyleFlipHorizontal
UIModalTransitionStyleCrossDissolve
UIModalTransitionStylePartialCurl
Usually I am writing self.modalTransitionStyle = // One of the constants
in the viewcontroller which will be presented modally, instead of spreading the code.
You are initializing helpView as a UIViewController.
Make sure you have #import "HelpView.h" (or whatever the helpView .h file is called) in the .h file of the view controller where you are initializing it.
Then, use this code:
HelpView *helpView = [[HelpView alloc] initWithNibName:#"HelpView" bundle:nil];
[self.view addSubview:helpView.view];
That should fix it.
The easiest solution for me eventually was to just define my XIB's file owner as the same class as the parent controller, meaning the parent controller would control both the parent and the subview, which just makes a lot easier. :)
Declare the help view on calss level.
in.h file
#class HelpView;
..
#interface
{
HelpView *helpView;
}
#property(nonatomic,retain)HelpView* helpView;
In.m file
#import "HelpView"
#synthensize helpView;
now add this Code where you want
helpView = [[HelpView alloc] initWithNibName:#"HelpView" bundle:nil];
helpView.view.tag = HELP_VIEW_TAG;
[self.view addSubview:helpView.view];
- (IBAction) closeHelp{
//UIView *helpView = [self.view viewWithTag:HELP_VIEW_TAG];
[helpView removeFromSuperview];
}
-(void)dealloc
{
[helpView release];
}
I've been trying to understand View Controllers and Views and even after watching some of the classes on iTunesU, I'm still having some trouble implementing them programmatically. I'm hoping someone can clarify a bit.
So I'm trying to create a UIViewController which in turn creates its view.
The program is broken up in the following classes:
ProgramNameAppDelegate.h and .m
ApplicationRootViewController.h and .m
From the AppDelegate, I create the UIWindow and UIViewController. Partial code goes like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
_window = [ [UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
if (!_window)
{
[self release];
return NO;
}
_rootViewController = [ [ApplicationRootViewController alloc] init];
if (!_rootViewController)
{
NSLog(#"No _rootViewController");
[self release];
return NO;
}
[_window addSubview:[_rootViewController view]];
[_window makeKeyAndVisible];
return YES;
}
In the ApplicationRootViewController I call init. My UIView is created in loadView as such:
- (void)loadView
{
NSLog(#"In loadView");
[super loadView];
CGRect _frame = [[UIScreen mainScreen] applicationFrame];
UIView* _rootView = [[UIView alloc] initWithFrame:_frame];
[_rootView setBackgroundColor:[UIColor redColor]];
self.view = _rootView;
return;
}
The problem I'm having is apparently the program is creating the view, however, it is never displaying the view that I created until the app resigns active. Once I go out of the app and come back in, the view is there. I have tried several other things, but it always behaves the same.
I would eventually like to for the controller to create the view from a subclassed UIView.h and .m file.
Thanks,
Kevin
From the docs:
Your custom implementation of loadView
method should not call super.
So, get rid of [super loadview] and it should work;)
Also, if you want to use a custom view (Subclass of UIView). Alloc/Init using initWithFrame: and when referring self.view from uiviewcontroller you will have to cast it like so:
[(MyView *)self.view myMethod];
As simple as that ;)
EDIT:
Suppose you make a class like this:
//MyView.h
#interface MyView : UIView{
...
}
- (void) doSomething:(NSString *)string;
#end
//MyView.m
#import MyView.h
#implementation MyView
... write your implementation here
#end
then in the UIViewController,
in loadView
do:
//don't forget to #import "MyView.h"
-(void) loadView{
MyView *myView = [[MyView alloc] initWithFrame:CGRectMake(...)];
self.view = (UIView *)myView;
[myView release];
}
then when referring your view somewhere else in the controller:
- (void) viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[(MyView *)self.view doSomething:#"something"];//1
[self.view setBackgroundColor:[UIColor greenColor]];//2
}
In //1 you should cast because your are calling doSomething: method (or it could be a property as well), which is declared/defined in MyView and not in UIView. If you don't cast you will get a warning but it will work.
In //2 you don't need to cast since setBackgroundColor: is a method defined in UIView class ;)
Objective-C is very flexible and will allow to cast many things, so you have to be careful because casting is like telling the compiler: "trust me, is not a UIView, is MyVIew" and the compiler will obey you. But if you were wrong your app will crash when attempting to call doSomething: because it does not exist in UIView.
I'm trying to add a subview to my main view. Here's the relevant code from my viewController:
- (void)viewDidLoad {
[super viewDidLoad];
MyUIViewSubclass* myView = [[MyUIViewSubclass alloc] init];
[self.view addSubview:myView]; // self.view is a simple UIView
[myView setNeedsDisplay];
}
drawRect in myView doesn't get called.
However, if I use a MyUIViewSubclass as the main view for the viewController (setting it in Interface Builder), drawRect does get called.
What do I need to do to get drawRect called in my subView?
In your subclass you should use the designated initialiser for UIView:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
//Implementation code...
}
}
Ok, figured it out. Wasn't setting the frame of my subView.
I want to implement a custom initialization method for my UIViewController subclass to "replace" the initWithNibName method.
This is the code:
- (id) initWithMessage:(NSString *)message {
if ((self = [super initWithNibName:#"ToolTip" bundle:nil])) {
label.text = message;
}
return self;
}
The label is loaded from xib but at this point the reference to the label is nil (probably because the xib is not loaded yet?). Does anyone know a solution for that? Thanks
I know this is an old question, but the correct answer is to use the viewDidLoad method to do any additional setup after the view has loaded. The view is not loaded until it's needed, and may be unloaded when a memory warning is received. For that reason, a view controller's view should not be touched in an init method.
You should declare the label programmatically and initialize it within the init rather than do it from the nib.
This is how :
Assume UILabel *label is a class variable with #property and #synthesize defined for it.
- (id) initWithMessage:(NSString *)message {
if ((self = [super initWithNibName:#"ToolTip" bundle:nil])) {
label = [[UILabel alloc] init];
label.text = message;
[self.view addSubView:label];
}
return self;
}
Release the label in the "dealloc" method.
Hope this helps.