I have been unable to find a solution to this problem anywhere.
I am using Xcode 4.5 to write an iOS 6 app using storyboards. It uses a Navigation Controller to jump between several View Controllers with Navigation Bars, including a few that use a UIWebView to display a website. I have added code to the AppDelegate and various ViewController files to restrict the view to Portrait for most scenes in the app (since they really won't look good otherwise), but to allow Landscape view for the websites. And the Info.plist is configured allow all 4 orientations.
Everything works fine in the UIWebView scene; including rotation, scrolling and zooming - except for one thing: when I rotate from Portrait to Landscape, the horizontal dimension of the website stays locked at the horizontal dimension for the Portrait view - resulting in a large white space to the right of the website in the scene (see images below). I fixed a small (1/4") white space at the top of the UIWebView by selecting Layout: Wants Full Screen under View Controller in the Attributes Inspector. But I can't fix this.
I can supply relevant code or Storyboard settings if necessary. Can anyone help? Thank you.
I solved adding this code, when application loads on viewDidLoad method:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
Then add this to your view controller:
- (void) orientationChanged:(NSNotification *)note
{
UIDevice * device = note.object;
switch(device.orientation)
{
case UIDeviceOrientationPortrait:
_displayWeb.frame = CGRectMake (0, 0, 768, 1024);
break;
case UIDeviceOrientationPortraitUpsideDown:
_displayWeb.frame = CGRectMake (0, 0, 768, 1024);
break;
case UIDeviceOrientationLandscapeLeft:
_displayWeb.frame = CGRectMake (0, 0, 1024, 768);
break;
case UIDeviceOrientationLandscapeRight:
_displayWeb.frame = CGRectMake (0, 0, 1024, 768);
break;
default:
break;
};
}
_displayWeb is your IBOutlet UIWebView, by the way this is using Xcode 4.6.1
Related
Anyone knowns how to set round corner to the video frame using AVPlayer?
I'm trying doing this:
- (void)loadVideoWithPlayer:(AVPlayer*)playerVideo
{
dispatch_async(dispatch_get_main_queue(), ^{
AVPlayerLayer *avLayer = [AVPlayerLayer playerLayerWithPlayer: playerVideo];
[avLayer setCornerRadius:20];
[avLayer setMasksToBounds:YES];
[self.playerViewController setPlayer:playerVideo];
[self insertSubview:self.playerViewController.view belowSubview:self.interactView];
[self.playerViewController.player play];
});
}
but it's not working. I can't set round corners to the AVPlayer.playerViewController.view because the video frame could be different.
I was just able to do this. The change could even be animatable, from no rounder corners to rounded corners.
I didn't do anything much different from you. Using iOS 10 at the moment. (Confirmed working on iOS 9.3.5 device also.)
self.viewVideo?.layer.masksToBounds = SHOW ? true : false
self.viewVideo?.layer.cornerRadius = SHOW ? 10 : 0
I should perhaps note that the viewVideo is a subclass of UIView. The only real change there is the layerClass being returned as AVPlayerLayer.self
override static var layerClass: AnyClass {
return AVPlayerLayer.self
}
So btw I do not use AVPlayerViewController etc. I just add my subclass of UIView to my usual UIViewController's view.
I would like when i create all my sprites to get centred in the screen, but that is not the case, i have a sprite when i set it's position to CGPointMake(self.size.width / 2, self.size.height / 2) it gets centred vertically but not horizontally, when i set it to CGPointMake(0, 0) it sets at the bottom of the screen with only half of it's body visible ( which is what you expect) but horizontally it doesn't get positioned right ( half his vertical body appears ) until i set it's X to 300.
How come the sprite's Y position gets set right but the X doesn't ?
scene.scaleMode = .AspectFill
and i haven't set any anchorPoint, 4' screen.
UPDATE:
I'm using Portrait, played around with different scaleMode and found out that the perfect (0, 0) that sets the sprite on the bottom left is:
scene.scaleMode = .ResizeFill
It also works fine with different screen sizes,but (self.size.width / 2) puts it further to the left.Do you think it's the best setting for all SpriteKit Portrait projects?
I tried to reproduce what you are saying, but I couldn't, either using .sks file or not for loading the scene. Also I've produced good results on both 7.1 and 8.1 simulators...The thing is that simulators sometimes could be tricky and not 100% reliable, so you should not trust them much.
I don't know if this will help you, but you should consider it...In Xcode 5 projects scene is programmatically created to have a size of the view. Basically it's done in viewDidLoad method like this:
- (void)viewDidLoad
{
[super viewDidLoad];
// Configure the view.
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
// Create and configure the scene.
GameScene * scene = [GameScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:scene];
}
Or using viewWillLayoutSubviews like LearnCocos2D pointed:
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
// Configure the view.
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
skView.showsDrawCount = YES;
//skView.showsQuadCount = YES;
skView.showsPhysics = YES;
skView.ignoresSiblingOrder = YES;
if(!skView.scene){
// Create and configure the scene.
GameScene * scene = [GameScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:scene];
}
}
But Xcode 6 uses an SKS file:
override func viewDidLoad() {
super.viewDidLoad()
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
// Configure the view.
let skView = self.view as SKView
skView.showsFPS = true
skView.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = true
/* Set the scale mode to scale to fit the window */
scene.scaleMode = .AspectFill
}
}
If you look at the GameScene.sks you can see that the default scene size is 1024x768.
Try to print your scene size as well as view's bounds size to see actuall sizes. You can use something like:
println("view.bounds\(view.bounds), self.size\(self.size)")
I don't know if any of this helped, but I hope it will lead you somewhere. Goodluck!
Here is an example "GLKView Subview" app I wrote, based on the OpenGL Game sample project in Xcode 4.5. It creates a GLKView subview with its delegate set to the File Owner's GLKViewController, so that both OpenGL ES 2 views are controlled by one controller:
http://d-h.st/7R1
Here is a screenshot, I've tinted the subview's background red for contrast:
http://d-h.st/om4
I was excited that I had a straightforward way to add multiple GLKViews under one GLKViewController and EAGLContext (for sharing textures etc), until I realized that the frame size is broken in:
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
NSLog(#"My view frame: %#", NSStringFromCGRect(view.bounds));
float aspect = fabsf(view.bounds.size.width / view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
// Compute the model view matrix for the object rendered with GLKit
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
self.effect.transform.modelviewMatrix = modelViewMatrix;
// Compute the model view matrix for the object rendered with ES2
modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
_normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
_modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
if(view == self.view)
{
glClearColor(0.65f, 0.65f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArrayOES(_vertexArray);
// Render the object with GLKit
[self.effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 36);
// Render the object again with ES2
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glDrawArrays(GL_TRIANGLES, 0, 36);
[self.subview display];
}
else
{
glClearColor(1.0f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArrayOES(_vertexArray);
// Render the object with GLKit
[self.effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 36);
// Render the object again with ES2
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
}
Output in iOS Simulator with iPhone 4" Retina:
2013-04-27 15:50:56.149 GLKView Subview[48136:11903] My view frame: {{0, 0}, {568, 320}}
2013-04-27 15:50:56.152 GLKView Subview[48136:11903] My view frame: {{0, 0}, {248, 100}}
The subview's frame should be {100, 100} but for some reason it's coming out to {248, 100}. I've tried everything I can think of, even embedding it in a UIView, thinking that perhaps its autoresize constraints were getting set wrong if the main GLKView was its parent. As you can see the UIView's size is correct but the child GLKView's size is borked.
As a developer, this seemed like the first thing to try, but Apple generally has other ideas. Without autoresize, GLKView is useless for freeform layouts that work with any device size.
I managed to get multiple GLKViewControllers sharing a single EAGLContext working as child controllers in a different project. But I don't see why we should have to carry the baggage of creating a GLKViewController every time we want to add a GLKView to the screen. My guess is that GLKViewController gets confused when it's a delegate for a GLKView that isn't its own view.
I also managed to get my views working manually by just using glViewport() and after losing two days to GLKView issues, I would probably recommend going that route to anyone reading this (gaining cross platform advantages as well).
I'm hoping there is a simple explanation/fix, even if it's just "you have to make a GLKViewController for every GLKView". Thanks in advance to anyone who manages to get it working. If not, maybe an example of this bug feature will help someone.
I found a workaround. Just use the example project, but turn off the rightmost red bar in the Autosizing adjustment for both the GLKView and its black parent UIView.
Explanation: since the aspect ratio is different going from the 3.5" to 4" iPhone display, the autosizing tries to meet the right margin constraint, which stretches the views horizontally. By telling it to maintain the left margin and the width, but NOT the right margin, it positions and sizes the views correctly within the main view.
Still, something wonky is going on because if you embed another white UIView inside of the black UIView and set all of its size and margin constraints, it autosizes properly within its black parent UIView, while the GLKView fails to do so if you check all of its constraints. The GLKView appears to still be autosizing against the root UIView, which for now appears to be a bug. It could have something to do with setting the GLKView delegate to File's Owner. I've submitted Apple Bug ID# 13777142 that you can refer to if you wish to submit your own bug report.
P.S. I don't see these issues if I embed each GLKView in its own GLKViewController like the other posts on Stack Overflow say to do.
I have a UITextView with a lot of text in it. When the subview containing the UITextView is shown the UITextView only appears after the UITextView has been touched and scrolled.
Is there a limit of how much text can be in a UITextView?
Or is this a bug?
attached is a clip explaining this occurrence.
https://dl.dropbox.com/u/8256776/UITextView%20Bug.MOV
Ok, I have looked into it and it seems to be quite a common issue. It seems that the text view doesn't feel that it has to draw the text, but calling setNeedsDisplay doesn't help. I don't know if there is a "real" solution, but you can force it to draw the text by scrolling programmatically:
disclaimerView.contentOffset = CGPointMake(0, 1);
disclaimerView.contentOffset = CGPointMake(0, 0);
An unrelated thing in your code: In your switchView method you have two animations, one for the menu view and one for the view you are sliding into place. This is unnecessary as you can put both setFrame calls in the same animation:
MenuView = (UIView *)[self.view viewWithTag:100];
appView = (UIView *)[self.view viewWithTag:ViewInt];
[MenuView setFrame:CGRectMake(0, 0, 320, 480)];
[appView setFrame:CGRectMake(321, 0, 320, 480)];
[UIView beginAnimations:#"move buttons" context:nil];
[UIView setAnimationDuration:.5];
[MenuView setFrame:CGRectMake(-320, 0, 320, 480)];
[appView setFrame:CGRectMake(0, 0, 320, 480)];
disclaimerView.contentOffset = CGPointMake(0, 1);
disclaimerView.contentOffset = CGPointMake(0, 0);
[UIView commitAnimations];
And one more thing (and then I will back off :) )
You seem to be quite fond of using tags to retrieve elements. While it does work, it is not very understandable. You don't have that many elements so I would just add each of them as IBOutlet with a meaningful name (like you did with your disclaimerView). Also, have seperate switchView methods for the different views you are moving into place. That way you can easily perform additional stuff you might need for just that view, like the force scroll on disclaimerView.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
UIWebView on iPad size
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationController *naviController = [[UINavigationController alloc]init];
[self.view addSubview:naviController.view];
}
If I add navigation controller in the view, it appears about 20 pixels below status bar.
I want it appears just below status bar. How do I fix this?
I've experienced this same issue.
This discussion was helpful: UIWebView on iPad size
Tony's answer helped me discover this trick:
naviController.view.frame = self.view.bounds;
Turns out setting the view height fixes this problem. You can do it in the nib (xib) file or progammatically when creating the view setting the view.frame = CGRect(0, 0, 320.0 460.0); or whatever it's supposed to be (in your case it looks like it should be 460.0 since you have the status bar on).
The main point is that if the view size is smaller than the height of the screen, there are no guarantees where your controls will show up.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CGRect frame = CGRectMake(0, 0, 320.0, 480.0);
viewController.view.frame = frame;
[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];
return YES;
}
I changed like above. It works. So far so good. If height was 460, there would have been blank line at the bottom. View's absolute coordinate is (0, 20). So, Navigation bar's coordinate is (0, 40). I think that was the problem. I will encounter another problem.
Maybe there is way to change coordinate before displaying navigation view. Thank you.