UIView Subclass not displaying controls...

Member
Posts: 89
Joined: 2002.04
Post: #1
I created a SpellingView class which subclasses from UIView. I then go into Interface Builder to edit the MainWindow.xib file. I drag over a new UIView object into the the dock window, resize it, change its background color and add a UILabel and UITextField to the view. I also associate the SpellingView to the new UIView in the inspector.

In code I want to display SpellingView. So I do the following in my AppDelegate:

Code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

spellingView = [[SpellingView alloc] initWithFrame:[window bounds]];
[window addSubview:spellingView];

NSLog(@" isDescendantOfView: %d", [spellingView isDescendantOfView:window]);
[window makeKeyAndVisible];
return YES;
}

Running the application in the emulator, I don't see the UIView. The SpellingView object IS a subview of window since isDescendantOfView returns 1. Now if I programmatically create the Controls in the SpellingView class:

Code:
sentencePrompt = [[UILabel alloc] initWithFrame:CGRectMake((self.bounds.size.width / 2), 10.0, 150.0, 43.0)];
[self addSubview:sentencePrompt];
[sentencePrompt setText:@"This sucks"];

I now see the label properly...

Why can't I create the view in IB and have the Controls show? Why do I have to programmatically add them in in order for them to show up?

Most of the examples that use a custom view, subclass from a UIViewController. However the API docs mention the following:

Quote:Note: You should not use view controllers to manage views that fill only a part of their window—that is, only part of the area defined by the application content rectangle. If you want to have an interface composed of several smaller views, embed them all in a single root view and manage that view with your view controller.

So I'm using the AppDelegate as the controller to start with...

Thanks for your help!
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #2
It sounds like you are instantiating all of the views that make up your interface from MainWindow.xib, then, after the NIB file is loaded, you are adding another SpellingView to the window. (Which would end up on top of the rest of your views.) If you are creating your user interface with interface builder, you do not need to programmatically create views and vice versa.

The sentence "associate the SpellingView to the new UIView in the inspector" leads me to believe your understanding of the NIB file isn't there yet. You should read the "Nib Files" document in Apple's documentation.

However, it is fairly dry. If you really want to learn, there is always there is this book. Wink
Quote this message in a reply
Member
Posts: 65
Joined: 2009.01
Post: #3
flipflop Wrote:Why can't I create the view in IB and have the Controls show? Why do I have to programmatically add them in in order for them to show up?
You are creating them in IB, but you are covering them up with the second instance of SpellingView that you are creating programmatically.
Quote this message in a reply
Member
Posts: 89
Joined: 2002.04
Post: #4
Perhaps I should explain what I'm trying to accomplish. There is probably a better way of doing this...

I'm working on a spelling practice application for my daughter. Every week she has 10 new spelling words to learn and a test on Friday. The application would allow her to enter in the words for the week, along with a sentence to help prompt her on what word she is trying to spell.

For example, she may have "yellow" as one of the words she needs to spell. So she enters in "yellow" and a sentence like, "The sun is this color"... Eventually I will have the ability for her to record herself saying the word instead of using a sentence. But that's for later... Wink

The portion I'm working on is the practice portion of the application. This is where the sentence (UILabel) and a UITextField is displayed so she can enter in the word. Simple enough...

Now what I'm trying to do is to create a custom UIView with the UILabel and UITextField in it and throw 10 of them into a UIScrollView, 1 for each word she needs to spell. So the UIScrollView will contain 10 of these custom UIView's and will scroll as she spells the words. She can also skip words if she wants to come back to them later...

In the MainWindow.xib file there are 5 items: File's Owner, First Responder, Window, AppDelegate and SpellingView. I created the SpellingView by dragging over a View object from the Library window. Double clicking on the SpellingView instance in the Dock a new window opens up. This new window is where I added the UILabel and UITextField controllers.

The idea here is that (a) I defined what the UIView looks like in IB and I can hook up the IBOutlets for the UILabel and UITextField objects and (b) I'm hoping that I can dynamically instantiate SpellingView's and add them into the UIScrollView programmatically depending on how many words there are in the list.

Hopefully that makes more sense with what I'm trying to accomplish.

P.S. I do have you book in hand Wink and have read several of the chapters. Specifically about Subclassing UIView (which overrides the drawRect method) as well as the View Controllers chapter which creates a UIViewController subclass. I'm looking at the "For the More Curious: Paging" section for adding a UIView to the UIScrollView... However when I try adding an instance of SpellingView, it doesn't show anything in the scroll view.

Perhaps because I'm instantiating the SpellingView programmatically, it's not using the SpellingView that is in the Nib file. This is why, when I add a UILabel programmatically it shows correctly. How can I grab the SpellingView instance in the Nib file, use that in the UIScrollView? Is it possible to clone it for the rest of the words?

In my example I don't think I want to create a UIViewController for the SpellingView since it sounds like a UIViewController is for a view that takes up the whole screen. However my approach isn't currently working!

Thanks again!
Quote this message in a reply
Member
Posts: 65
Joined: 2009.01
Post: #5
flipflop Wrote:How can I grab the SpellingView instance in the Nib file, use that in the UIScrollView?
Sure that's the idea. The nib only creates the instance of the view and maybe makes a connection to a view controller if one exists. It also provides the convenience of being able to drag controls out of the IB Library and place them in your view instead of having to create them programmatically.
You already have a handle to the view in the nib since you changed it's Class in IB's Inspector from UIView to SpellingView. If you remembered to replace SpellingView's initWithFrame method with initWithCoder (since you are using a nib), then you should be all set. The stuff in the nib will load first, and then if you want to add anything else from within the SpellingView.m file, just use
Code:
[self addSubview.....];
Quote this message in a reply
Member
Posts: 89
Joined: 2002.04
Post: #6
That was the trick... I didn't need to alloc and init the SpellingView. The only thing that did was generate a UIView that didn't have anything to draw. I was assuming any time you alloc and init the SpringView it would pull in the information from the Nib file.

So to get this to work I did the following:

Code:
//spellingView = [[SpellingView alloc] initWithFrame:[window bounds]];
[window addSubview:spellingView];

Since I already hooked up the IBOutlet to the SpellingView in IB, the instance was already available. I was just overwriting the view when I did an alloc and init.

Now I just need to figure out how to dynamically create multiple SpellingView's based on how many words there are and toss those into the scrolling view.

Thanks!
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #7
It sounds like you will have a different number of SpellingViews depending on what week it is. In this case, I wouldn't use the NIB file for anything other than the window/app delegate, because your interface will be a bit more dynamic. Interface Builder is nice for laying out a static interface, but it becomes less helpful with scrollviews and dynamic interfaces.

Because it sounds like most of the interface detail is determined by the SpellingView, you won't have much of a use for a NIB file. I'd do something similar to:

Code:
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)d
{
   // Get all of our words and their stuff from somewhere.
    NSArray *wordInfo = [NSArray arrayWithContentsOfFile:...];

   // How much room do we have to work with?
    CGRect r = [[UIScreen mainScreen] applicationFrame];

   // Make our container scroll view
    UIScrollView *sv = [[[UIScrollView alloc] initWithFrame:r] autorelease];
   // It should display as many "pages" as their are words
    [sv setContentSize:CGSizeMake([wordInfo count] * r.size.width, r.size.height];
    [window addSubview:sv];

    float x = 0;
    for(NSDictionary *d in wordInfo)
    {
          // For every word, create a spelling view. Offset its x coordinate to make it a new "page"
           SpellingView *spv = [[[SpellingView alloc] initWithFrame:CGRectMake(x, 0, r.size.width, r.size.height)] autorelease];
           [spv configureWithDictionary:d];
           [sv addSubview:spv];
          // Move the offset over the the width of the screen
           x += r.size.width;
    }
    [window makeKeyAndVisible];
    return YES;
}

That's a bit off the cuff, but should put you in the ballpark.
Quote this message in a reply
Member
Posts: 89
Joined: 2002.04
Post: #8
I was afraid of having to create the view programatically. Not that it would be difficult, just that its an extra step to add the controllers, setup the properties and move them into their proper positions by hand. Too bad IB isn't meant to be used this way...

Thank you for the code snip it. This is exactly what I'm currently doing... except for adding the subviews code... that is currently commented out. Wink

Thank you too for writing the book. It has helped quite a bit! I'm looking forward to adding some Core Animation to the SpellingView... the goal being when the UIScrollView is paged, the new SpellingView would swing back and forth like a sign post. Something to make learning ones spelling list a bit more entertaining.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  UIView opaque blending problems Joecoolage 0 3,679 Aug 2, 2010 12:58 AM
Last Post: Joecoolage
  How to access EAGLView/UIView functions from C? Rasterman 10 6,011 Apr 8, 2010 10:47 AM
Last Post: Rasterman
  Problem displaying point sprites Duddd 0 2,013 Feb 12, 2010 02:45 AM
Last Post: Duddd
  conditionally displaying interface elements aerospaceman 2 2,759 Jun 25, 2009 12:20 PM
Last Post: aerospaceman
  Cocos2d: Making a CocosNode subclass oskob 1 3,681 Jun 18, 2009 10:46 AM
Last Post: Taxxodium