Scroll View in an Universal Xcode Project - iphone

I am creating an Universal app that has a scroll view.
The app runs fine for both the iPhone and iPad. However the scroll view is set to the iPad dimensions. So when i run the app on the iPhone the scroll view is still set for the iPad.
Any way I can change that?

You could use this:
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
[myScrollView setFrame:CGRectMake(0, 0, 320, 480)];
}else{
[myScrollView setFrame:CGRectMake(0, 0, 768, 1024)];
}
Of course you'll have to make adjustments to the scroll view's content size as well.

Related

Hiding Tabbar while porting from portraid mode to landscape mode in iOS

I am facing one issue with hiding the UITabBar when moving to landscape view.
When I am running my app in Xcode 4.6.1 and iOS 6.1 simulator everything works fine but while running the app in Xcode 5 and iOS 7 simulator I face the following issue.
I am using a tabBarController and 3 tabs are located in it at the bottom of screen.
One of the tabs has the functionality to switch from portrait view to landscape view.
We need to show the tabBars in portrait view but need to hide them in landscape view.
When switching the simulator from portrait to landscape view, tabBar gets hidden but I see a white space at the bottom.
It is confirmed that the white space is due to Tabbar because when I changed the hidden property of tabBar to NO
(self.tabBarController.tabBar.hidden = No;)
I can see the tabBars at the place where the white space was coming earlier in landscape view.
I am sharing the code for shouldAutorotateToInterfaceOrientation, where I am creating the landscape view.
I have tried to use [UIScreen mainScreen].bounds.size.width instead of self.tabBarController.view.bounds.size.width.
Also I have tried hardCoding the value of width, but there is no change in the width of frame.
One more thing to make things clear, If anybody has doubt that why are we removing the landscape view from super view, making it nil and then redrawing it again.
This is required because our app shows weekdays - mon, tue, wed and app also supports changing to different language.
So when user selects a different language, we need to show these weekday labels in corresponding language so we have to remove the view and then redraw it again because UILabes do not get refreshed automatically.
I have read some posts on this issue but not able to trace out actual reason. Please if someone has any idea, do suggest a solution.
First , I am creating a landscape view in viewDidLoad() like this -
_landscapeView = [[MyWeekView alloc]initWithFrame:CGRectMake(0, 0, self.tabBarController.view.bounds.size.height, 320)];
[self.view addSubview:_landscapeView];
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
displayEmpName.frame = CGRectMake(0, 22.0, self.tabBarController.view.bounds.size.width, 34.0);
_portraitView.hidden = YES;
_landscapeView.hidden = NO;
self.tabBarController.tabBar.hidden = YES;
self.navigationController.navigationBar.hidden = YES;
[[self.tabBarController.view.subviews objectAtIndex:0]setFrame:CGRectMake(0, 0, 480,320)];
dayView.hidden = YES;
[self.view bringSubviewToFront:_landscapeView];
self.navigationItem.leftBarButtonItem = nil;
//LABELS IN SCREEN DO NOT CHANGE ON CHANGING LANGUAGE
//RELOAD THE LANDSCAPE VIEW ONCE DEVICE IS CHANGED TO LANDSCAPE MODE
[_landscapeView removeFromSuperview];
_landscapeView = nil;
_landscapeView = [[MyWeekView alloc]initWithFrame:CGRectMake(0, 0, self.tabBarController.view.bounds.size.width, 320)];
[self.view addSubview:_landscapeView];
}

Fade out Launch Image on 4 Inch iPhone screen

On launch, I am fading from my launch image to the application's interface. To achieve this, I am adding a UIImageView with "Default.png" and animating its alpha just before makeKeyAndVisible.
Should Default.png always return the device-specific (or resolution-specific) version of the launch image? Or should I be checking the screen's bounds and scale to pick the right one for the retina vs non-retina and 3.5 vs 4 inch screens?
I expected Default.png to behave much like other image resources - use the #2x version when supported (and the -568h version on the iPhone 5). But my experimentation in the simulator leads me to believe otherwise. Running the 4 inch simulator, the 3.5 inch image is used. This results in a splash image that does not extend to the bottom of the screen. The screenshot below shows the transition mid-animation.
Unfortunately I don't have each device so was unable to confirm if this is just a quirk of the simulator.
In short, I want to be sure that the retina image is used on retina devices, and the 4 inch image is used on 4 inch devices.
This is my code
- (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[self.window makeKeyAndVisible];
[self _startLaunchAnimation];
return YES;
}
- (void)_launchAnimation {
CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height;
UIImageView *launchImageView = (UIImageView*)[self.window viewWithTag:1000];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionNone
forView:self.window
cache:YES];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(startupAnimationDone:finished:context:)];
[launchImageView setAlpha:0.0];
[launchImageView setFrame:CGRectMake(-60.0f, 0.0f, 320.0f, screenHeight)];
[UIView commitAnimations];
}
- (void)_startLaunchAnimation {
CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height;
NSString *imageName = nil;
if (screenHeight == 568.0f) {
imageName = #"Default-568h.png";
} else {
imageName = #"Default.png";
}
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *launchImageView = [[UIImageView alloc] initWithImage:image];
[launchImageView setTag:1000];
[self.window addSubview:launchImageView];
[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:#selector(_launchAnimation)
userInfo:nil
repeats:NO];
}
For the record, this is my version of #agassi_yzh's solution:
//fade from the launch image to the interface
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
NSString *imageFile = (screenHeight == 568.0f) ? #"Default-568h.png" : #"Default.png";
UIImageView *splash = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageFile]];
[self.window.rootViewController.view addSubview:splash];
[UIView animateWithDuration:0.5
animations:^{
splash.alpha = 0;
}
completion:^(BOOL finished) {
[splash removeFromSuperview];
}
];
//display the main window
[self.window makeKeyAndVisible];
The answer is you will have to explicitly load the device specific version of the image. This is custom animation and you cannot rely on Apple's Default whatever loading behavior to achieve what you want.
First make sure that you you are configured properly and the correct default load image is displayed on the devices (dont trust the simulator too much (aka I never even use the simulator its so buggy))
And then as previous commenters suggested load a view with your images.
Remember that the default image is going to be loaded and shown by the cocoa framework. All you can do is show a view afterward, if you try and do some of the admittedly clever hacks with the on load that are on the web you will find that they will always break in some way.
If you need a full screen image animated or not on iPhone 5 you need to load that image explicitly for the device thats all there is to it.
Yes, you provide Default.png and Default#2x.png, you even have to supply Default-568h#2x.png for the iPhone 5 4" screen.
You app will use standard, retina or big retina according to device but note that Apple discourage using the Default launch image as any intro animation sequence.
The trick you could use is to add an image view as the first screen of the app when it's launched and immediately fade it out, this will give the user the impression that the launch image is fading out even though the launch image is gone, and it's your image view taking over.
Look at the Launch image section of the Apple Custom Icon and Image Creation Guidelines:
Supply a launch image to improve user experience.
Avoid using your launch image as an opportunity to provide:
• An “app entry experience,” such as a splash screen
• An About window
• Branding elements, unless they are a static part of your app’s first
screen Because users are likely to switch among apps frequently, you
should make every effort to cut launch time to a minimum, and you
should design a launch image that downplays the experience rather than
drawing attention to it.

Toolbar disappearing when loading page upside down

So this will almost certainly be a simple answer, but I can't for the life of me work it out!
Basically, I want my current app to be viewable in portrait only (for now at least) and either the right way up, or upside down. Everything works fine the right way up and when you rotate the iPad on a page, everything works fine, the page flips up as normal. But if you hold the iPad upside down (home button at the top) and click a button to load a new page, when the page loads the toolbar is not visible! I don't know if for some reason the toolbar is behind the rest of the content or if its not there. If you then rotate the iPad back to portrait, the toolbar appears and all is back to normal again!
Whats weirder is that on the iPhone, the toolbar is there when you load a page with an upside down iPhone!!
I've tried all sorts with the shouldAutorotateToInterfaceOrientation() and didRotateFromInterfaceOrientation() methods and with resizing/positioning on viewDidLoad depending on the orientation. But nothing seems to work at all!!
This is code I have in my viewDidLoad() method:
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
NSLog(#"iPhone");
if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationPortrait)
{
self.view.frame = CGRectMake(0, 0, 320, 460);
}
else if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationPortraitUpsideDown)
{
self.view.frame = CGRectMake(0, 20, 320, 460);
}
}
else
{
NSLog(#"iPad");
if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationPortrait)
{
self.view.frame = CGRectMake(0, 0, 768, 1024);
NSLog(#"iPad Portrait Up");
}
else if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationPortraitUpsideDown)
{
self.view.frame = CGRectMake(0, 20, 768, 1024);
NSLog(#"iPad Portrait Upside Down");
}
}
I've tried similar things in the didRotateFromInterfaceOrientation() method but nothing is working!
Thanks in advance for any help and feel free to ask questions/request more code
Matt
I ran into similar problem and here is what I discovered. When You add a toolbar at the top of the iPad UIView xib file, its autosizing is default to set up as shown in figure below. The toolbar will always stick to the bottom instead of the top.
What I did is change it to stick to top as shown in figure below and it fixed my problem.
If you setup the toolbar programmatically, you need to update the autoresizingMask.

UIImage/UIView Doesn't Adjust Properly To UIInterfaceLandscape Views

I am writing an app that I would like to only be viewed in Landscape Mode. I have set it up so that if the iPhone is held in Portrait Mode, nothing happens and the current image remains in Landscape Mode. The iPhone Simulator starts out in Landscape Mode with the Home Button on the right. If the iPhone is rotated from one Landscape Mode to the other, animation then occurs and the view is adjusted. However, whenever the device is in Landscape Mode with the Home Button on the left, the image is 20 pixels higher than needed, revealing a white line at the bottom of the screen.
In spite of all attempts to logically adjust this such as
self.view.frame = CGRectMake (0,20, self.view.frame.size.width, self.view.frame.size.height)
it doesn't fix the problem. I am accounting for the Status Bar in my calculations.
The .xib file contains an UIImageView on top of a UIView. This is my first experience implementing these methods so I apologize if the solution is relatively easy. Below is the code for the two methods used to implement the Landscape Mode views.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
//set up interface to only be viewed in Landscape
if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft)
return interfaceOrientation;
else if(interfaceOrientation == UIInterfaceOrientationLandscapeRight)
return interfaceOrientation;
else
return NO;
}
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)tointerfaceOrientation duration:(NSTimeInterval)duration {
if(UIInterfaceOrientationLandscapeRight){
self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}
else if (UIInterfaceOrientationLandscapeLeft) {
//shouldn't adjustment to 20 fix the view?
self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}
else return;
}
For UIViews to adjust the subviews properly you will have to take a look at this UIView property: autoresizingMask, and set the mask to autoresize what is needed, if that does not work you will have to override:
- (void)layoutSubviews
From the reference: UIView reference

IPhone 3, iPhone 4, and iPad orientation handling

I have a view with a tableView and a mapView. In portrait mode, I want the mapView to occupy the top 60% of the screen, and the table view, the bottom 40%. In landscape, I want the mapView to occupy 45% of the screen on the right, and the tableView 55% on the left.
Thus, I thought that something like this ought to work:
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
UIScreen* mainscr = [UIScreen mainScreen];
CGSize screenSize = mainscr.currentMode.size;
if(self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft
|| self.interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
tableview.frame = CGRectMake(0, 0 , (screenSize.height*.55), screenSize.width);
mapView.frame = CGRectMake((screenSize.height*.55), 0, (screenSize.height*.45), screenSize.width);
}
else
{
tableview.frame = CGRectMake(0, (screenSize.height*.6) ,screenSize.width, (screenSize.height*.4));
mapView.frame = CGRectMake(0, 0,screenSize.width, (screenSize.height*.6));
}
}
This code works fine on the iphone simulator with version 4 of the OS, but when I try to run it on the iphone 4 simulator or the ipad simulator, the views are completely off (i can only see the about a quarter of the map in portrait and none of the table, and in landscape i can see only the table).
I dont understand why this is the case -- since im simply scaling the views to match the screen size, shouldnt something like the above code work fine regardless of the resolution of the device? I was able to make a 'fix' by scaling using different values for the iphone, iphone 4, and ipad, but the numbers that I used were discovered by trial and error, and they dont appear to make much sense.
can someone please point me towards the correct method for handing these orientation changes for all devices? Thanks so much!
I have done something similar to this. Here is how I would accomplish what you would like to do
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
CGSize screenSize = self.view.bounds.size;
[UIView beginAnimations:#"InterfaceRotations" context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:duration];
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
tableview.frame = CGRectMake(0, 0 , (screenSize.height*.55), screenSize.width);
mapView.frame = CGRectMake((screenSize.height*.55), 0, (screenSize.height*.45), screenSize.width);
} else {
tableview.frame = CGRectMake(0, (screenSize.height*.6) ,screenSize.width, (screenSize.height*.4));
mapView.frame = CGRectMake(0, 0,screenSize.width, (screenSize.height*.6));
}
[UIView commitAnimations];
}