Iphone SDK - Multiple subviews and shouldAutorotateInterfaceOrientation - iphone-sdk-3.0

The iPhone Application Programming Guide shows an example labelled "Listing 2-1 Creating a window with views" (see below). This shows how to create and add two subviews to a window.
I am using a similar pattern=. This works correctly, both windows get displayed.
The problem I am having is to get it to recognize and do rotation. I have added the shouldAutorotateInterfaceOrientation methods to do a return YES. These are being seen. But only one of the views gets rotated.
More specifically the last view to be added gets rotated and the previous one does not. I can get either to rotate by having it as the second addsubview. But cannot get both to rotate. (Testing in the Iphone simulator.)
Any suggestions on what is needed to get both views to rotate correctly?
Here is Apples sample code.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Create the window object and assign it to the
// window instance variable of the application delegate.
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
window.backgroundColor = [UIColor whiteColor];
// Create a simple red square
CGRect redFrame = CGRectMake(10, 10, 100, 100);
UIView *redView = [[UIView alloc] initWithFrame:redFrame];
redView.backgroundColor = [UIColor redColor];
// Create a simple blue square
CGRect blueFrame = CGRectMake(10, 150, 100, 100);
UIView *blueView = [[UIView alloc] initWithFrame:blueFrame];
blueView.backgroundColor = [UIColor blueColor];
// Add the square views to the window
[window addSubview:redView];
[window addSubview:blueView];
// Once added to the window, release the views to avoid the
// extra retain count on each of them.
[redView release];
[blueView release];
// Show the window.
[window makeKeyAndVisible];
}

This question was abandoned, sadly...
I would love to find the answer to that, as it causes alot of problems on the iPad SDK... adding more than 1 subview at a forced landscape mode, will only make one rotated view.
Causing alot of confusion, something is very wrong with the system.
~ Natan.

Related

SafeArea in iOS 11: how add view on main screen with custom navigationBar without safeArea from code in objective-c

In my project on Objective-C mainScreen with Custom NavigationBar (created from code):
mainNavigationController = [[NavigationController alloc] initWithRootViewController:mainMenuViewController];
mainNavigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
mainNavigationController.delegate = self;
mainNavigationController.navigationBar.tintColor = [UIColor whiteColor];
UIWindow* window = self.window;
window.backgroundColor = [UIColor whiteColor];
window.rootViewController = mainNavigationController;
[window makeKeyAndVisible];
I change self.view like size [UIScreen mainScreen].applicationFrame]:
UIView* mainView = [[[MainViewControllerView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] autorelease];
self.view = mainView;
In mainScreenView I add scrollView:
scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
scrollView.autoresizesSubviews = YES;
scrollView.autoresizingMask = UIViewAutoresizingNone;
scrollView.backgroundColor = [UIColor clearColor];
scrollView.bounces = NO;
And add some subView inside scrollView:
[scrollView addSubview:myLogoView];
[scrollView addSubview:littleScrollView];
[scrollView addSubview:firstButton];
[scrollView addSubview:secondButton];
[scrollView addSubview:thirdButton];
[scrollView addSubview:fouthButton];
[scrollView addSubview:fifthButton];
[scrollView addSubview:sixthButton];
[scrollView addSubview:seventhButton];
[scrollView addSubview:activityIndicatorView];
https://www.dropbox.com/s/ttrkolgnch80kr9/safeArea.png?dl=0
If use XCODE 8 and iOS <= 10, all view place correct on mainScreen (myLogoView place ignore size of custom NavigationBar and have coordinate Y == 20.0 in absolute value coordinates of device screen),
but if use XCode 9 and iOS 11 myLogoView have place under my custom navigationBar (height == 44) myLogoView Y == 64.0 in absolute value coordinates of device screen, in iOS 10 (under xCode9) all working good - added view on mainScreen placed in start coordinates of screen and ignore height of custom NavigationBar.
In swift and storyboard I know how it fixed in iOS11 easy remove safeArea top line, but how remove safeArea from code in Objective-C.
How fix this trouble?
Safe area in iOS 11 is replacement of top & bottom layout and apple provide more detail on this like below :
The layout guide representing the portion of your view that is
unobscured by bars and other content. In iOS 11, Apple is deprecating
the top and bottom layout guides and replacing them with a single safe
area layout guide.
So base on this now top & bottom layout replaced with single safe area but agin if you are not using default NavigationBar so you can disable safe area in storyboard like below :
You can Uncheck safe area and it will revert to top & bottom layout.
Ref Before & After uncheck safe area:
Before or default :
Uncheck Safe area or old behavior :
Hope this will help to understand new iOS 11 update related to top & bottom layout and change your code as per this layout change.
Also here is one good blog to explain more on Safe area layout : Safe area

Centre a view in its parent, when in landscape

I've search and found a few questions about this, but none containing an answer that worked for me.
This code centres a subview in the current view, if the device is in portrait, but not if it's landscape. How do I make the centring work in landscape?
UIView *redView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];
redView.backgroundColor = [UIColor redColor];
redView.center = [self.view convertPoint:self.view.center fromView:self.view.superview];
[self.view addSubview:redView];
Rather try using
redView.center = [self.view convertPoint:self.view.center fromView:nil];
Works for me.
Note from the docs:
The view with point in its coordinate system. If view is nil, this
method instead converts from window base coordinates. Otherwise, both
view and the receiver must belong to the same UIWindow object
(should be called in viewDidAppear, not in viewDidLoad)

How to display a UIWindow based dimmed background like UIAlertView?

Here's my problem: I tried to display a UIWindow with a subview that displays a radial gradient. I wanted to put the window on the UIWindowLevelAlert. I had this all figured out before and it was working, but now I'm trying to reproduce it wasting hours...
This is the code I've got (the background is not a gradient because I wanted to keep it simple, then add a view that really is like the one of an UIAlertView):
- (IBAction)buttonPressed {
UIWindow *backgroundWindow = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
backgroundWindow.windowLevel = UIWindowLevelAlert;
UIView *backgroundView = [[UIView alloc]initWithFrame:[UIScreen mainScreen].bounds];
backgroundView.backgroundColor = [UIColor blackColor];
backgroundView.alpha = 0.5;
[backgroundWindow makeKeyAndVisible];
[backgroundWindow addSubview:backgroundView];
backgroundWindow.hidden = NO;
}
When a UIWindow is dealloc'd, it will be removed from the screen. Since you don't keep a reference to your UIWindow, I believe it is getting released and dealloc'd, and therefore it won't show.
The solution is to keep a reference to the window somewhere. Can you store it as a property in the class you're working in?

UIPickerView takes up all horizontal space on iPhone, but not on iPad?

I noticed something that has never been a problem before.
I did a project for iPad where I used several UIPickerView positioned next to each other, horizontally. Here they respect the CGRect frame I initialize them with, meaning placing other elements on either side of them was no problem.
Now I am trying to do this on an iPhone project and here a UIPickerView insists on being the only element. It sizes it self to fill the screen horizontally, with the "around" graphics.
I tried different approaches, place the UIPickerView inside a different view then sizing that super view, that just leads to clipping, not resizing. Another thing is that the UIPicker insists on being placed in the center of the screen. This basically means that when a UIPickerView is added to the screen, even though its single component is only 70 px wide, those 320 px of the screen is used up.
What I am trying to accomplish is to have a UIPicker on the right side of the screen and a button to the left of it.
Am I overlooking something obvious here? Hope someone could lend a hand, thanks in advance:)
Nothing more complicated than this:
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 250.0f, 165.0f)];
UIPickerView *picker = [[UIPickerView alloc] initWithFrame:container.frame];
[picker setDelegate:self];
[picker setDataSource:self];
[container addSubview:picker];
the frame I set, is not respected. It takes up all horizontal space.
I tried your code with the same result.
However, you can set the frame after the picker has been created and added to your container, and the new size is respected. Here's my test case, which works for me using SDK 4.2, in the iPhone simulator:
- (void)viewDidLoad {
[super viewDidLoad];
UIPickerView* pv = [[[UIPickerView alloc] initWithFrame: CGRectMake(160, 100, 100, 216) ] autorelease];
pv.delegate = self;
pv.dataSource = self;
[self.view addSubview: pv];
pv.frame = CGRectMake(10, 10, 100, 216);
}

UISplitViewController: remove divider line

When using UISplitViewController on the iPad there's a black vertical divider line between the root and detail view. Is there any way to remove this line?
Thanks
Excellent answer by #bteapot. I tested this and it works, even gets rid of the line between master/detail nav bars.
You can do this in storyboard by adding the "gutterWidth" key path and the value 0 to the USplitViewController runtime attributes.
Actuly I have some modification to answer of (Dylan)'s answer
in the appDelegate we need to add image in spliteview controller rather then window
self.splitViewController.view.opaque = NO;
imgView = [[UIImageView alloc] initWithImage:
[UIImage imageNamed:#"FullNavBar.png"]];
[imgView setFrame:CGRectMake(0, 0, 1024, 44)];
[[self.splitViewController view] insertSubview:imgView atIndex:0];
[[self.splitViewController view] setBackgroundColor:[UIColor clearColor]];
here self is object of AppDelegate.
now Apply the answer of this thread : iPhoneOS SDK - Remove Corner Rounding from views (iPad problem) answer by (abs)
edit in above post's answer is
-(void) fixRoundedSplitViewCorner {
[self explode:[[UIApplication sharedApplication] keyWindow] level:0];
}
-(void) explode:(id)aView level:(int)level
{
if ([aView isKindOfClass:[UIImageView class]]) {
UIImageView* roundedCornerImage = (UIImageView*)aView;
roundedCornerImage.hidden = YES;
}
if (level < 2) {
for (UIView *subview in [aView subviews]) {
[self explode:subview level:(level + 1)];
}
}
imgView.hidden = FALSE;
}
** make imgView.hidden to FALSE
declare imgView to the AppDelegate.h file**
and dont forget to call this
-(void)didRotateFromInterfaceOrientation:
UIInterfaceOrientation)fromInterfaceOrientation
{
[yourAppDelegate performSelector:#selector(fixRoundedSplitViewCorner)
withObject:NULL afterDelay:0];
}
chintan adatiya answer covers only the corners and the navigation bar, but I found an trick how to cover the line between the Master and the Detail view.
It is not nice but it works like a charm.
First create an image which is 1 px wide and 704 pixels high.
In the didFinishLaunchingWithOptions add the following code:
UIView *coverView = [[UIView alloc] initWithFrame:CGRectMake(320, 44, 1, 704)];
[coverView setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"divider_cover.png"]]];
[splitViewController.view addSubview:coverView];
And done.
When you want a background image which is continues create 3 images:
Master: width: 320, height: 704
Detail: width: 703, height: 704
Divider:width: 1, height: 704
First post here, hi everyone.
I discovered how to do it accidentally... when I tried to find why I had LOST the divider line. Here's how to hide it, if you're still interested:
1) In your Detail (right-side) view, make sure you have a subview that spans the whole view.
2) Offset this subview view to (-1, 0).
3) Make sure that the Detail View has its "Clip Subviews" option unchecked.
VoilĂ , enjoy.
You can mostly get rid of it by setting another image behind it in the main window's views. This is from the app delegate didFinishLaunchingWithOptions
// Add the split view controller's view to the window and display.
splitViewController.view.opaque = NO;
splitViewController.view.backgroundColor = [UIColor clearColor];
[window addSubview:splitViewController.view];
[window insertSubview:bgImageView belowSubview:splitViewController.view];
[window makeKeyAndVisible];
But it still leaves two visual artifacts at the top and the bottom that appear to be custom drawn by the splitviewcontroller.
Interestingly, In the app that I'm working on I want a black background color for both views in the UISplitViewController. I'd like to change the color of the divider line to white (so that you can see it). Making both background colors black is one way to get rid of (make invisible) the dividing line but that's probably not a solution for most people.
Tested on iOS10 (probably will work on iOS9 too).
splitviewController.view.backgroundColor = UIColor.white
it removes divider. Apparently divider is just a gap between master and detail container.
I looked around for a while, and came to the conclusion that theres no way to do this, other than to create your own custom split view.
Try the MGSplitViewController by Matt Gammell
http://mattgemmell.com/2010/07/31/mgsplitviewcontroller-for-ipad
I may be late here, but I DO have a solution that works. It even works for the iOS 8+ splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible; and seamlessly slides in and out when you press the Full Screen toggle button.
Here is the trick :
first Subclass UISplitViewController.m
In the header add the follwing :
#property (strong, nonatomic) UIView *fakeNavBarBGView;
In the viewDidLoad method add the following code :
CGFloat fakeNavBarWidth = 321; // It is important to have it span the width of the master view + 1 because it will not move when the split view slides it's subviews (master and detail)
CGFloat navbarHeight = self.navigationController.navigationBar.frame.size.height + 20;
self.fakeNavBarBGView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, fakeNavBarWidth, navbarHeight)];
self.fakeNavBarBGView.backgroundColor = [UIColor redColor];
// Add Fake navbar to back of view
[self.view insertSubview:self.fakeNavBarBGView atIndex:0];
// SplitView Controller
UISplitViewController *splitViewController = self;
DetailViewController *detailVC = [navigationController.viewControllers lastObject];
detailVC.fakeNavBarSubView = self.fakeNavBarBGView;
detailVC.SVView = self.view;
In the DetailViewController.h add the following :
#property (strong, nonatomic) UIView *SVView;
#property (strong, nonatomic) UIView *fakeNavBarSubView;
Now here is the final trick : in the DetailViewController.m, add the following in the viewDidLoad method (called every time you click the Master table) :
[self.SVView sendSubviewToBack:self.fakeNavBarSubView];
[self.SVView bringSubviewToFront:self.view];
Run it and watch the magic ;-)
Private API (can cause App Store rejection):
[splitViewController setValue:#0.0 forKey:#"gutterWidth"];
I did this accidentally by setting the backgroundColor property of the first viewController's view - possibly to clearColor, I don't remember now.
UIManager.put("SplitPaneDivider.draggingColor", new Color(255, 255, 255, 0));