How to draw a view over a GLkit view on iOS5/Ipad - ios5

I´m creating a GLK view on iOS5.
First, i create the context.
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
[self setupGL];
Second, i draw a triangle moving.
This works.
Now, i want to create a view over the GLKview. So, i used the Storyboard, to draw a View (HUDView) with background red, and i put it over the main view. When i run the app, only openGL appear, i assume that red background view is drawing behind GLKView. Why?
I have tried to use on Hudview -> viewDidLoad
[self bringSubviewToFront:self];
But the problem nothing happen.
Any idea how could i solve this problem????
Thanks in advance.

I have found a sample that solve the problem. Glfun is a sample where a openGL layer is drawn, and you can add a hud view over it. Hopes help people :D

Related

What exactly is done to a UIView on interface rotation?

could someone explain what iOS does on rotation of the interface. I´ve got a layout problem with one View that is gone after rotating the iPhone. Seems that the View got set a new frame, bounds or whatever, don´t know. Anyhow after the interface was rotated once the layoutproblem is gone forever. So something must be set to the view at the time the interface rotates.
I´m loading the View from a NIB file and show it with a navigationcontroller:
BirthdayReminderWidgetConfigViewController *vc = [self.storyboard
instantiateViewControllerWithIdentifier:#"BirthdayConfigController"];
self.navigationController pushViewController:vc animated:true];
Maybe there is some setting I have to do in order to show up the view correct without rotating the interface.
I´ve got a layout problem with a view that is loaded from a nib file as follows:
The project contains a MainStoryboard. Within that, I load a view from a nib file.
NSArray *xib = [[NSBundle mainBundle] loadNibNamed:#"View" owner:self options:nil];
self.configViewController = [xib objectAtIndex:0];
The storyboard has a navigation controller and the loaded view is shown like this:
if (currentWidgetConfigViewController != nil)
{
[self.navigationController pushViewController:currentWidgetConfigViewController animated:true];
}
So in my opinion nothing wrong? (First question)
But now the problem.
What I designed is that:
What iOS does is the following
The controls are not arranged well.
And besides that with a button on the new view I open up a PeoplePicker with that code:
[self presentViewController:self.picker animated:YES completion:nil];
After closing the People picker with [self.picker dismissViewControllerAnimated:true completion:nil]; I get this result:
So what is going wrong here?
Override -setFrame: and -setBounds: in your view to see what happens:
- (void) setFrame: (CGRect) newFrame
{
NSLog(#"New frame: %#", NSStringFromCGRect(newFrame));
[super setFrame:newFrame];
}
Also, the transform usually changes during a rotation. Orientation Zoo might help, it’s a sample Xcode project showing what happens in various rotation use cases. Didn’t touch it for a long time, though, so I don’t know if it still works.

How to add UITextView in CCLayer or CCScene in cocos2d-iphone

I want to add an instruction page where instruction written in UITextView. How to do it in Cocos2d. Because this is a game page and I want to take menu transaction effects of cocos2d like CCTransitionRadialCCW.
I wrote this code
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(10,60, 300,360)];
textView.backgroundColor = [UIColor clearColor];
textView.text = #"I am First enemy";
[textView setEditable:NO];
[[[CCDirector sharedDirector]openGLView]addSubview:textView];
But there is problem that it is added to the main CCDirector page, while I am writing this code
// [[[CCDirector sharedDirector]openGLView]addSubview:textView];
// replaced by :-
[self addChild:textView];
It gives me error. Please tell me how to add UITextView in CCScene or CCLayer.
I know that [self addChild:(CCNode *)node];
addChild: method needs CCNode so please tell me that how can typecast or convert UITextView object to CCNode.
If there is some alternate option for that please tell me .Like CCLabelTTF is alternate for UILabel, is there alternate for UITableView in Cocos2d-iphone.
Thanks in advance
Have a look at CCTableView: http://www.cocos2d-iphone.org/archives/943.
Combining UIKit and Cocos2D in such a way that you have the interleaving you have mentioned is likely to be very difficult, because everything done in Cocos2D is drawn in one OpenGL view. When you add a UIView, you can only add it in front of or behind Cocos2D's view.
No matter which way you're adding the UIView to cocos2d, it will not be animated by the cocos2d transition effects because simply speaking the UIView objects exist outside the OpenGL view that cocos2d uses (and animates in the case of transitions).
Adding UIViews to a cocos2d view as in your first example code is correct. But in order to position the view like a node, you should consider using the CCUIViewWrapper.

Changing frame of UIView's CALayer (self.view.layer.frame = ...) appears to have no effect

I'm sure I'm missing something basic here. I'm trying out the CALayers 'hello world' code from:
http://www.raywenderlich.com/2502/introduction-to-calayers-tutorial
Doing the very first example. New single view project in xcode 4.2. No change to the nib/storyboard. Import QuartzCore. Add the following code to ViewDidLoad in the ViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.layer.backgroundColor = [UIColor blueColor].CGColor;
self.view.layer.cornerRadius = 30.0;
self.view.layer.frame = CGRectMake(20, 20, 20, 20);
}
I run this (ipad 2 or ipad simulator) and get a full screen blue rectangle with rounded corners. What I hoped to get was a 20x20 blue rectangle offset by 20/20.
I'm clearly getting control over the views layer (as shown by the color and rounded corners). However, adjusting the frame seems to have no impact. I've NSLog'ed the frame before/after setting it, and it has changed. Is the frame of the root layer locked to the uiview frame?
I don't have a strong reason to change the views layers frame, I'm just trying to reason through what is going on. Hopefully this is an easy question...
Thanks!
Paul
Actually, the previous answer (you can't set uiview.layer.frame as it always fills the uiview) is close, but not quite complete. After reading the answer, I registered for the original site and to comment that the tutorial had issues. In doing so, I found that there were already comments that I hadn't seen in my first pass that addressed this. Using those, I started doing some testing.
The bottom line, if you move the self.view.layer.frame setting code from viewDidLoad to viewWillAppear, it works fine. That means that you can change the frame of the root layer of a view. However, if you do it in viewDidLoad it will be undone later.
However, the previous answer is still pretty close. I NSLog'ed the frame of the root layer and the frame of the view. Changing the root layer frame changes the view frame. So, the answer that the view.layer.frame always fills the view.frame is correct. However, setting the layer frame resets the view frame to match. (I'm guessing that uiview.frame property simply returns uiview.layer.frame...)
So, at some point in time between 2010 and today, something in the environment changed. Specifically, after viewDidLoad and before viewWillAppear the uiview/layer frame appears to be reset to the nib specified value. This overrides any changes in viewDidLoad. Changes made in viewWillAppear appear to stick.
Robin's answer got me on the right track, but I wanted to spell out the full answer.
The tutorial is wrong. Setting the frame of the view's main layer has no effect. The main layer is 'special' and will always fill the view's bounds. What you need to do is create a sublayer of the main layer like this:
- (void)viewDidLoad
{
[super viewDidLoad];
CALayer *newLayer = [[CALayer alloc] init];
newLayer.backgroundColor = [UIColor orangeColor].CGColor;
newLayer.cornerRadius = 20.0;
newLayer.frame = CGRectMake(100.0f, 100.0f, 200.0f, 200.0f);
[self.view.layer addSublayer:newLayer];
[newLayer release]; // Assuming you're not using ARC
}
Also, in your code a layer with width 20pt and height 20pt is too small to have rounded corners of 30pt anyway.

Remove or change color of frame around UIWebView document display?

I'm using a UIWebView to display a variety of file types (so I can't use a specialized PDF viewer) embedded into my main view (so I can't use a modal document interaction controller). My main view has a background design that clashes with the light gray frame that appears around documents in the UIWebView. Does anyone know a way to remove that gray frame, make it transparent or change its color?
I'm familiar with and have used the techniques for changing the background color of the UIWebView to avoid a "color flash" while it loads, and for removing the top and bottom shadow that appear when "overscrolling" the web view, but I haven't seen anyone address this gray frame. (It only appears when displaying documents like .doc or .pdf, not when displaying HTML content.) I've hidden all the images that are subviews of the UIWebView's scroll view, so apparently this is coming from somewhere else.
This question was written while iOS 4 was current, but in iOS 5 and later, simply setting the backgroundColor and opaque properties of the UIWebView will remove that gray frame:
myWebView.opaque = NO;
myWebView.backgroundColor = [UIColor clearColor];
You can change WebView's background color by assigning its backgroundColor property:
myWebView.backgroundColor = [UIColor redColor]; // will make red bakground
If you want transparency use [UIColor clearColor] instead. But remember - by making your views tranparent you can worsen app's performance.
Since this has been around for a while I'll just throw some ideas out there.
You may be able to utilize the stringByEvaluatingJavaScriptFromString: method of the UIWebView class to manipulate the document object model if the UIWebView treats the loaded document as a page, but this method has some limitations.
Other than that, the only thing you really have left at your disposal is manipulating the view hierarchy to modify any subviews of the UIWebView, but there may not be anything for you manipulate if the UIWebView class renders the viewer directly rather than creating a hierarchy.
It looks like it is not possible to remove the border from a UIWebView but could you not use CGContextDrawPDFPage() as Apple show here: http://developer.apple.com/library/ios/#samplecode/ZoomingPDFViewer/Introduction/Intro.html
Try this,
self.webview.backgroundColor = [UIColor whiteColor];
for (UIView* subView in [self.webview subviews])
{
if ([subView isKindOfClass:[UIScrollView class]]) {
for (UIView* shadowView in [subView subviews])
{
if ([shadowView isKindOfClass:[UIImageView class]]) {
[shadowView setHidden:YES];
}
}
}
}
This may help you. :-)
You need a bunch of CoreAnimation magic:
- (void) hideShadowInLayer:(CALayer *) layer
{
for (CALayer *l in layer.sublayers) {
l.shadowOpacity = 0;
[self hideShadowInLayer:l];
}
}
- (void) hideShadows
{
[CATransaction begin];
[CATransaction setValue:(id) kCFBooleanTrue forKey:kCATransactionDisableActions];
[self hideShadowInLayer:webView.layer];
[CATransaction commit];
}
You need to perform hideShadows method somewhere AFTER loading your document and while you are scrolling it (I guess scrollViewDidScroll of webView.scrollView.delegate is a good place). You also need to include QuartzCore framework to your project.
What's going on here:
Any view uses something called layer for rendering. Layers can have its own hierarchy and every layer can have its own border and shadow, so the frame that annoying you is the shadow of one of them. Bad thing - UIWebView recreates it while scrolling - so you need to use this method constantly. And I guess shadowOpacity has a default animation attached to it, so you need CATransaction to disable it.

UIView addsubview after orientation change: Tell view to resize

I have a UIView as a XIB in Portrait mode.
This view is added programmatically to the viewcontroller like this:
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"InputView" owner:self options:nil];
InputView *inputView = (InputView*)[nibObjects objectAtIndex:0];
[self.view addSubview:inputView];
This view has autoresizing masks set up properly and rotates fine when the orientation changes from Portrait to landscape.
However, if the orientation is already landscape and I create the view after the orientation change, it has its initial portrait orientation.
Is there a way to tell the view to initialize or resize itself to portrait by using its masks?
Thanks in advance for any reply!
EDIT:
Using the suggestions of occulus and Inder Kumar Rathore (thanks guys!), I altered the code to this:
InputView *inputView = (InputView*)[nibObjects objectAtIndex:0];
[self.view addSubview:inputView];
[self.view setNeedsLayout];
[self.view layoutSubviews];
[self.view layoutIfNeeded];
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
[self shouldAutorotateToInterfaceOrientation:orientation];
Unfortunately, there is no change at all.
I think I found someone asking the same question:
When adding a sub view the view does not resize if the app is in landscape mode
The answer identifies the problem correctly, but is not very encouraging...
Sure, I could create two nibs or resize the frame, but this seems so contrary to the idea of auto-resizing.
I find it hard to believe that there is no way to tell a nib after awakening and adding it to a view to use its autoresize features...something that works flawless when the device rotates.
EDIT 2:
The solution of idz works:
InputView *inputView = (InputView*)[nibObjects objectAtIndex:0];
[self.view addSubview:inputView];
inputView.frame = self.view.bounds;
[inputView show];
Thanks!
Often a NIB/XIB file contains a UIViewController that takes care of all of this. In this case, since their is no view controller (in the NIB/XIB) you need to take over its post-load duties.
Calling layoutSubviews directly, or indirectly via setNeedsLayout or layoutIfNeeded won't do you much good because the default implementation does nothing.
Assuming you want input view to fill the bounds of self.view you do the following:
InputView *inputView = (InputView*)[nibObjects objectAtIndex:0];
[self.view addSubview:inputView];
inputView.frame = self.view.bounds;
[inputView show];
All the resize masks of the sub-views must be correctly set for this to work and, obviously, if you don't want to fill the full bounds you may want to adjust the frame.
[self.view addSubview:viewSpinner];
viewSpinner.frame = self.view.frame;
[viewSpinner setNeedsLayout];
This works for me (Y)
I don't know if you still have this issue.
Let's say you have the following architecture:
window
subviewcontroller
(you implemented shouldautorotate correct to answering the wanted orientations)
Into this subviewcontroller you want to add the views of new UIViewControllers by just calling the addSubview function.
Instead of implementing the bounds manipulation in shouldautorotate, you should implement it in
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
self.newUIViewController.view.frame = self.view.bounds;
}
didRotateFromInterface... is called after shouldRotate. In this function the bounds are already setup correctly.
This way you don't need so much manipulation by code.
See this related question:
When do autoresizing masks take effect in iOS?
So after loading your new view from the nib, and adding as a subview to self.view, try calling setNeedsLayout.