views:

107

answers:

4

Hello.

I'm making an Opengl ES application and I am trying to work out how to incorporate parts of the UIKit GUI over the view with the OpenGL ES working on it.

In the init method of the EAGLView class I have this to setup the UITextField:

add_name_field = [[UITextField alloc] initWithFrame: CGRectMake(10, 10, [UIScreen mainScreen].bounds.size.width, 50)];

Somewhere in the drawRect method where everything is rendered and processed for the game I have:

[add_name_field becomeFirstResponder];
[self insertSubview: add_name_field atIndex:0];

I can confirm this code is called because I used NSLog to test that but when it is run the text field does not show over the game's OpenGL view. If I put the code in the init method, the text field shows properly with the keyboard at te beginning of the game.

So how do I get it to work in the drawRect method?

Thank you for any answer. I will write some code for the delegate in the meantime.

A: 

I assume you're in a UIViewController subclass, with the code above? If so, then instead of

[self insertSubview: add_name_field atIndex:0];

do:

[self.view addSubview:add_name_field];

The important part is, you're calling this method on self.view rather than self. Adding subviews is a VIEW function, not a View CONTROLLER function.

insertSubview:atIndex: ought to work too (if called on the right object), but addSubview: will stick it on top of the view no matter what else is there, so it's a bit cleaner.

Dan Ray
drawRect isn't a viewController function though. And, even if self was a UIViewController, he'd get an error just for calling insertSubview on a UIViewController.
David Liu
Right. Also he said it was an EAGLView class... Reading is always a good move when answering a question. ;-)
Dan Ray
A: 

Is there any reason to have it done in the drawRect method? You said that it works fine in the init method, so why not have it there?

As for why it doesn't work, I don't exactly know OpenGL views but, assuming they work just like regular UIViews, you probably shouldn't be adding other UIViews in the drawRect function. UIViews don't get shown & drawn immediately; they have to wait till the runloop tells them to draw. Likely what happens is that when your superview's drawRect finishes, it assumes all its subviews have finished drawing and doesn't realized that your newly added textfield didn't get a chance to. What you could try is calling setNeedsDisplay on your textfield.

David Liu
I've put all my game logic in the drawRect method because the drawRect method is what gets run every frame.The text input must run at a certain point and not at the beginning of the program.The program will run through the frames and I don't see why the text filed wont at least display on the subsequent frames.
Matthew Mitchell
Better way to do that is to call some other function/method every frame and do a setNeedsDisplay when all the frame setup is finished. That way all your views (parent and child) will get taken care of, not just one.
hotpaw2
Okay, I'll look into it. Thank you.
Matthew Mitchell
Wait, are you doing "addSubview" on EVERY frame? That could easily be the reason why. addSubview causes the added view to remove itself from any current superview before it gets added to the new superview.
David Liu
A: 

Add your text subview outside of drawRect. drawRect is for rendering that one view, and may or may not ignore drawing any other views (such as your text view), depending on how the view stack is rendered.

hotpaw2
+1  A: 

THank you for all the other answers but I found the solution.

It was a simple solution. I simply moved the addSubView method to the initialisation of the EAGLView class. The keyboard wont show until I make the text field the first responder. When I'm finished with it, I can simply clear the text and make the EAGLView class the first responder again and that hides it all again.

This way I can simply use the keyboard to get text input for my game, displaying text when typing and hiding it afterwards.

Matthew Mitchell