addSubview not working - iphone

// Create and add a sub view
CGRect viewRect = CGRectMake(0, 0, 200, 200);
UIView *a_sub_view = [[UIView alloc] initWithFrame : viewRect];
[window addSubview : a_sub_view];
After adding the above 3 lines of code, xcode produces no errors or warnings. But the sub-view is not showing at all. The sample program seems to be running exactly as before. Hope that somebody knowledgable could help.

I find it useful to set the background color so I know where the view is and the boundaries.
a_sub_view.backgroundColor = [UIColor redColor];
In your example, you're create an empty view so you won't 'see' anything.

window expects a viewcontrollers view to be added.
you can then add subviews to the current view.
so in your example use:
[self.view addSubview:a_sub_view];

I am using this in order to "find" the window:
UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
[window addSubview:myView];
This also worked for me, but it is a bit uglier:
[self.navigationController.tabBarController.view addSubview:myView];
To explain the second one, I had to "follow" the controllers back up to the "top" view. (My application has a tab bar with a navigation controller inside the current tab.)

If you are working with iOS 5 & above , you have to do as below:
[self.window.rootViewController.view addSubView:viewObject];

[self.view addSubView: a_sub_view];

Related

Screen rotation from device orientation and a new UIView

What is the safest and most effective way place a new UIView within the bounds of the App's UIWindow on the top of the view stack when a screen rotation from Portrait to Landscape occurs? Also, when returning from Landscape to Portrait, to remove this subview.
Basically the App is created as most are:
-UIWindow:
--UIView
---All subviews (including a tabview controller)
I would like to create:
-UIWindow:
--UIView (new, to be placed on top)
--UIView
---All subviews (and triggered by a view controller in here)
Is this wrong? There is surprisingly little documentation to help do this.
If you create a view controller to hold all of your subviews you can just use the rotation functions that will be called for you:
willRotateToInterfaceOrientation:duration:
and
didRotateFromInterfaceOrientation:
So lets say you use didRotateFromInterfaceOrientation you check
if(UIInterfaceOrientationIsLandscape(orientation))
{
[yourView removeFromSuperView];
}
else
{
[self.view addSubView: yourView];
}
See my answer here: https://stackoverflow.com/a/4960988/202451
It should bring you closer to doing custom things like that
I found the a working solution. Might you offer a better one?
ArtsDayAppDelegate *appDelegate = (ArtsDayAppDelegate*)[[UIApplication sharedApplication] delegate];
UIView *landscapeView;
if (!landscapeView) {
landscapeView = [[UIView alloc] initWithFrame: frame];
}
[landscapeView setBackgroundColor:[UIColor blackColor]];
..add various views..
[appDelegate.window.rootViewController.view addSubview:landscapeView];

Setting modal image view?

In the Epic Win iPhone app, they seem to have some sort of image view in the front of another view. How does one implement this?
Example:
All you have to do is to create a new view and add it to the window. You can do that like this:
UIView *overlayView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
overlayView.backgroundColor = [UIColor colorWithWhite:0 alpha:.5];
[overlayView addSubview:<#imageView#>];
[self.view.window addSubview:overlayView];
[overlayView release];
Let me know if that works for you.
From above example it seems that they just added Imageview on self.view and they decrease alpha of self.view. It doesn't seems something triky.
That's very simple and there are probably a few ways to do it.
The simplest is probably to just add an image view as subview of the window.
Check out this CustomAlert Class. Shows you how to change the background of a UIAlertView.

Transparent NavgationBar on iPhone

I'm trying to display transparent UINavigationBar on top of Scrollview.
This is actual result of code that I have written...
where as I'm expecting view to be displayed like below image, which happens after I slightly scroll the image.
Code :
- (void) loadView {
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
pagingScrollView.pagingEnabled = YES;
pagingScrollView.backgroundColor = [UIColor blackColor];
pagingScrollView.showsVerticalScrollIndicator = NO;
pagingScrollView.showsHorizontalScrollIndicator = NO;
pagingScrollView.contentSize = CGSizeMake(pagingScrollViewFrame.size.width * [self imageCount],
pagingScrollViewFrame.size.height);
pagingScrollView.delegate = self;
self.wantsFullScreenLayout = YES;
pagingScrollView.scrollsToTop = YES;
self.view = pagingScrollView;
}
question is how do I make view to load as I expected without user interacting to it?
any suggestion or help is appreciated..
EDIT: I'm creating view totally from CODE
It seems like you're trying to do this in code not in the IB. If so, you have to put your code in the viewDidLoad of the Application Delegate (e.g. MyProgramAppDeligate class or whatever). If you want it in some certain views, put it in the viewDidLoad of the UINavigationController class/subclass.
Does this satisfy your requirement?
self.navigationController.navigationBar.translucent = YES;
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
And to make your statusbar translucent.
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:YES];
[self setWantsFullScreenLayout:YES];
I have this inside my willWillAppear and I reset it in my viewWillDisappear.
You have to set
self.navigationController.navigationBar.translucent = YES;
As soon as you do this, the 0,0 coordinate is behind your navigation bar not below it and your view shifts behind the bar.
It may be a conflict between IB and your code. I would add the line of code suggested by Ortwin in the viewDidLoad method and then double check you've set the navBar to translucent in IB.
The code you have posted has nothing to do with the opacity of the navigation bar. Show where you are setting the configuration of the components of the view. There you could just set the alpha of the navigation bar. Alternatively if you are using nibs, just set the alpha in IB.
Since you say that it works fine after the user (you) slightly scrolls the image, the problem might be that the UINavigationBar's drawRect: method does not get called after the UIScrollView is loaded.
Suggestion: Can you explicitly call setNeedsDisplay on the navigation bar after the view is loaded?
Have you tried setting the frame of the scroll view with an Y origin of 0 after setting the nav bar to transparent?
EDIT: I mean, you don't say what's the frame used in your code.
In viewDidLoad, try moving the origin up 32 pixels and grow the height by 32 pixels as well:
pagingScrollView.frame = CGRectMake(pagingScrollView.frame.origin.x, pagingScrollView.frame.origin.y-32, pagingScrollView.frame.size.width, pagingScrollView.frame.size.height+32);
In viewWillAppear scroll the content to the correct location.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIScrollView *scrollView = (UIScrollView *)self.view;
[scrollView setContentSize:CGSizeMake(320,568)];
[scrollView scrollRectToVisible:CGRectMake(0, 548, 320, 20) animated:NO];
}

iPhone UIViewController goes under status bar

I have a UIView and a UIController view. My is standard a 320x460 view. In applicationDidFinishLaunching I do:
[window addSubview:[controller view]];
The weird thing is that the UIView goes under the status bar (like there's missing outlet). However, if I rotate iPhone to the side and then back, it shows up ok.
Is this an expected behavior (I bet I can fix it by setting offset) or am I doing smth wrong?
I ran into this issue when displaying a UIViewController via presentModalViewController.
You can get around it by manually resizing the controller's view after the view has appeared:
- (void) viewDidAppear: (BOOL) animated {
//manually adjust the frame of the main view to prevent it from appearing under the status bar.
UIApplication *app = [UIApplication sharedApplication];
if(!app.statusBarHidden) {
[self.view setFrame:CGRectMake(0.0,app.statusBarFrame.size.height, self.view.bounds.size.width, self.view.bounds.size.height - app.statusBarFrame.size.height)];
}
}
I think your problem is that when you add a view to a window, you need to be aware of the state of the status bar and compensate for it:
if showing the status bar :
[controller view].frame = CGRectMake(0, **20**, 320, 460);
else
[controller view].frame = CGRectMake(0, 0, 320, **480**);
this is why IB shows you a dummy status bar.
I add this issue today. It turned out that I had "Wants Full Screen" checked in the ViewController's Attribute inspector.
Turning off "Wants Full Screen" resolved the problem.
Finally, I got to this solution. Works well for both iPhone & iPad:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Allocate view controller and load nib file
if (isIPhone) {
self.mainViewController = [[[tfdMainViewController_iPhone alloc] initWithNibName:#"tfdMainViewController_iPhone" bundle:nil] autorelease];
} else {
self.mainViewController = [[[tfdMainViewController_iPad alloc] initWithNibName:#"tfdMainViewController_iPad" bundle:nil] autorelease];
}
// Offset correction (iPhone bug?)
CGRect r = self.mainViewController.view.frame;
r = CGRectOffset(r, 0, [UIApplication sharedApplication].statusBarFrame.size.height);
[self.mainViewController.view setFrame:r];
[window addSubview: self.mainViewController.view];
[self.window makeKeyAndVisible];
return YES;
}
P.S. For some reason view has correct height:
480 (screen height in iPhone Portrait mode) - 20 (status bar) = 460,
but failed to set vertical offset. It is pretty strange behavior, looks like bug.
Fixes to the window didn't work for me as I had a modal view. A UIModalPresentationCurrentContext modal view. OK, here's what worked for me. I've been searching the web up and down before getting this to work.
I'm unable to move the view.frame from the parent. However in the viewWillAppear I'm able to move it down:
- (void)viewWillAppear:(BOOL)animated
{
// Move down to compensate for statusbar
CGRect frame = parentView.navCon.view.frame;
frame.origin.y = [UIApplication sharedApplication].statusBarFrame.size.height;
parentView.navCon.view.frame = frame;
}
If you are using Interface Builder's "Simulated User Interface Elements", then you also need to make sure that you have set the flag for "Resize View From NIB" in your MainWindow nib.
This appears to be a bug in iOS 5. One fix would be to use wantsFullScreenLayout in whatever view controller needs to present modally and manually layout the view always below the status bar.
http://www.cocoanetics.com/2012/06/radar-view-frame-inconsistency-using-presentviewcontroller-wantsfullscreenlayout-yn/
http://openradar.appspot.com/radar?id=1758406
Are you manually setting the application bar hidden property AFTER adding the subview? I don't imagine this is the case, but if it's set to none when you first load the view it will layout as if there isn't one, and if you then set the status bar to not hidden it will pop up on top of your view.
A possible solution is to use [[controller view] setNeedsLayout]; after adding the subview, or possibly [window layoutSubviews];. I've never had a lot of success using those to fix layout problems, but since it works after a rotation it's worth a shot.
Even me too got the same issue. When we are using some coding for device orientation we have wrote some coding in app delegate or in our view controller. There we need to change the condition to use the orientation return YES or NO. That solved our issue.
I prefer to use UINavigationController to wrap the UIViewController you, after that, set the NavigationBarHidden to the UINavigationController. It's perfect solution cause UINavigationController do handle the height of status bar in iOS 7.
Here is my code and my screen capture.
UINavigationController *wrapNavController = [[UINavigationController alloc] initWithRootViewController:yourViewController] ;
[wrapNavController setNavigationBarHidden:YES] ;
The Xcode 6, iOS7/8 solution is in to uncheck the "Under Top Bars" checkmark in the "Extend Edges" section of the View Controller section of the Attributes Inspector.
For Xamarin.iOS it would be:
if (UIApplication.SharedApplication.StatusBarHidden == false)
{
var statusBarHeight = UIApplication.SharedApplication.StatusBarFrame.Height;
View.Frame = new CoreGraphics.CGRect(0, statusBarHeight, View.Frame.Width, View.Frame.Height - statusBarHeight);
}

iPhone Modal View Smaller that the screen

I'm trying to do something that shouldn't be that complicated, but I can't figure it out.
I have a UIViewController displaying a UITableView. I want to present a context menu when the user press on a row. I want this to be a semi-transparent view with labels and buttons.
I could use an AlertView, but I want full control on the format of the labels and buttons and will like to use Interface Builder.
So I created my small view 250x290, set the alpha to .75 and create a view controller with the outlets to handle the different user events.
Now I want to present it.
If I use presentModalViewController two (undesired) things happen
1) the view covers all of the screen (but the status bar).
2) It is semi-transparent, but what I see "behind" it its not the parent view but the applications root view.
Ive tried adding it as a subview, but nothing happens, so Im not doing something right:
RestaurantContextVC* modalViewController = [[[RestaurantContextVC alloc] initWithNibName:#"RestaurantContextView" bundle:nil] autorelease];
[self.view addSubview:modalViewController.view];
Is it possible to do what I want?
Thanks in advance.
Gonso
I'm coding similar thing. My approach include.....
Not using dismissModalViewControllerAnimated and presentModalViewController:animated.
Design a customized full sized view in IB. In its viewDidLoad message body, set the background color to clearColor, so that space on the view not covered by controllers are transparent.
I put a UIImageView under the controllers of the floating view. The UIImageView contains a photoshoped image, which has rounded corners and the background is set to transparent. This image view serves as the container.
I uses CoreAnimation to present/dismiss the floating view in the modal view style: (the FloatingViewController.m)
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor clearColor]];
[UIView beginAnimations:nil context:nil];
[self.view setFrame:CGRectMake(0, 480, 320, 480)];
[UIView setAnimationDuration:0.75f];
[self.view setFrame:CGRectMake(0, 0, 320, 480)];
[UIView commitAnimations];
}
wangii
Thats pretty much the solution I found.
I load the view with loadNibNamed and then just add it on top with addSubView, like this:
//Show a view on top of current view with a wait indicator. This prevents all user interactions.
-(void) showWaitView{
NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:#"WaitView" owner:self options:nil];
#ifdef __IPHONE_2_1
waitView = [ nibViews objectAtIndex: 0];
#else
waitView = [ nibViews objectAtIndex: 1];
#endif
CGFloat x = self.view.center.x - (waitView.frame.size.width / 2);
CGFloat y = self.view.center.y - (waitView.frame.size.height / 2);
[waitView setFrame:CGRectMake(x,y,waitView.bounds.size.width,waitView.bounds.size.height)];
[self.view addSubview:waitView];
}
Could you elaborate on points 3 and 4?
What I did to give the view the round rect aspect is put it inside a round rect button.
This code will actually allow you to have a small floating view, but if the view is smaller that its parent, the user could interact with the visible part of the parent.
In the end I create my view with the same size, but kept the code just in case.
Gonso
I would strongly consider using a navigation controller to slide in your subview instead of overlaying it. This is the expected model and any small benefit you may think you'll get by doing it your own way will be greatly offset by the principle of (least) surprise.
If you really really have to do it this way, I believe the trick is to add the first table view as a subview of a transparent "holding" view that the view controller maintains. Then add your new sub view as another subview of that.
Again, if you really want to do this, instead of adding a transparent "holding" view, since this pop-up is essentially modal, I would make it a subview directly of the window.
You might want to put in a transparent black shield behind it to prevent touches on the background and focus input on the popup.
But seriously, consider either popping a controller on the stack or using that alert view. Unless you've hired a $$ designer, it's probably not going to look appropriate on the iPhone.
What I did was create a UIViewController on top of my UINavigation controller in my app delegate and made it a property of a singleton object for convenience:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//--- create root navigation controller
self.window.rootViewController = self.navigationController;
//--- create view controller for popups:
popupViewController = [[BaseViewController alloc] init];
popupViewController.view.backgroundColor = [UIColor clearColor];
popupViewController.view.hidden = true; //for rendering optimisation
[self.window addSubview:popupViewController.view];
[AppState sharedInstance].popupViewController = self.popupViewController;
//--- make all visible:
[self.window makeKeyAndVisible];
return YES;
}
At any point in my app, I can then call e.g.
MyViewController * myVC = [[UIViewController alloc] init];
//... set up viewcontroller and its view...
// add the view of the created view controller to the popup view:
[AppState sharedInstance].popupViewController.view.hidden = false;
[[AppState sharedInstance].popupViewController.view addSubview:myVC.view];
The BaseViewController used on the top just inherits from UIViewController and sets up a full-screen view:
//----- in BaseViewController implementation
- (void)loadView {
//------- create root view:
CGRect frame = [[AppState sharedInstance] getScreenFrame];
rootView = [[VCView alloc] initWithFrame:frame];
rootView.backgroundColor = [UIColor whiteColor];
self.view = rootView;
}