I have UITabBarController with 2 tabs. One resizes just fine, when StatusBar size changes (emulator "Toggle In-Call Status Bar" menu item). The other one doesn't.
The problematic tab item contains a static view, which dynamically loads one or another view depending on certain things. While getting this setup working I discovered that main tab view did NOT automagically send e.g. viewWillAppear and viewWillDisappear messages to my dynamic subviews.
Apple docs explained this was because dynamically added views were not recognized by the system.
#interface MyTabViewController : UIViewController
{
UIView *mainView;
FirstViewController *aController;
SecondViewController *bController;
}
...
if (index == 0)
{
self.aController = [[FirstViewController alloc]
initWithNibName:#"FirstViewController" bundle:nil];
[self.mainView addSubview:aController.view];
[self.aController viewWillAppear:YES];
}
How can I get StatusBar size changed event into my dynamic subviews? The "didChangeStatusBarFrame" doesn't work, as documented elsewhere.
Have you taken a look at this question?
Also, can we see your App Delegate code using application:didChangeStatusBarFrame:?
You could program a resize yourself, but usually this is done by using "auto resizing masks". (UIView has a property autoresizingMask).
I'm not sure about it but since your were adding those views programmatically maybe you forgot to set the autoresize mask. Without it the view won't resize automatically when the status bar frame changes.
[newView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
I hope it helps.
Related
In my app start delegate I have the following code:
[window addSubview:[myTabBarController view]];
UIImageView *banner =
[[[UIImageView alloc] initWithFrame:CGRectMake(0,381,320,50)] autorelease];
banner.backgroundColor = [UIColor redColor];
[window addSubview:banner];
[window makeKeyAndVisible];
This works as expected. The tab bar is visible and also my UIImageView is visible.
I need to modify that UIImageView everywhere in my app (I have the TabBarController, a NavigationController, UITableView, etc)
For example, I want to change the background color when I click in a UITableCell.
I tried everything: self.window.view.subviews, atObjectIndex, neither seems to get the current background color.
first you do not need an UIImageView if its just to set a background-color. A UIView is sufficient.
to solve your problem, you can keep a reference to the view who's background-color you want to change in you AppDelegate. you can then access you AppDelegate (and the the reference to your view) from anywhere in your app like so:
((YouAppDelegateName*)[UIApplication sharedApplication].delegate).yourViewReferenceProperty
Are you sure you want to do that?
It's usually best to arrange your app so that the only object manipulating a view controller's view hierarchy is that view controller. If other objects want to change something, they either change the data model or send a message to the view controller. So, you might give your view controller a 'backgroundColor' property, and its setter would update the appropriate view. Setting the background color indirectly through the view controller makes it easier to make changes to your view hierarchy in the future and generally keeps things better organized.
I have an app that has a login screen and splash screen. I want these screens to show up one after the other, and as such I have resulted to adding them as subviews to the app delegate's window property.
[window addSubview:mainViewController.view];
[window addSubview:loginViewController.view];
[window addSubview:splashScreenViewController.view];
The problem is that each subsequent subview that is added seems to appear in a weird manner(the orientation of the nib file is not obeyed). I know my nib files are not at fault, because if I only include one view, no matter which view it is, it shows up right. Furthermore, if I add the views as subviews to the main view controller's view(as opposed to app delegates) view, i dont get this issue. However, there is a 20px gap at the bottom of the screen because I guess UIWindow accounts for the status bar, and normal UIView's do not.
Does anyone have any idea what the problem might be? Is UIWindow doing something special? Am I not supposed to add several subviews to UIWindow? If anyone has tips regarding how to do splash screens, that would be much appreciated.
I suggest you use a UIView in the middle...
UIView view = [[UIView alloc] init];
[view addSubview:mainViewController.view];
[view addSubview:loginViewController.view];
[view addSubview:splashScreenViewController.view];
[window addSubview:view];
[view release];
After what if you what to animate as a splash screen, take a look at one of my post :
how to open a new uiview like a popup?
You should only have 1 view controller at a time.
You should use the -(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController delegate function to check which tab was clicked. If it's your second view (which it should be if there are only 2 tabs) then call a custom method in your splashscreencontroller that pops up the modal. If that splash screen is only supposed to show once, make sure to set a flag afterwards to make sure it doesn't pop up again.
A TabBarController loads all the views before displaying them, so there's no lag when a user switches between tags.
I've got an iPad app with a “drawer” table displayed in a popover. The user can tap-and-hold on an item in the drawer to drag that item out of it and into my main view. That part works fine; unfortunately, the view being dragged appears under the popover, and is too small to be visible until it's dragged out from underneath it. If I add the view as a subview of the view controller in the popover, it gets clipped by the popover's frame, and as I can't access the UIPopoverController's view, I can't disable its layer's masksToBounds—and that probably wouldn't be a great idea anyway. I suspect that I could use an additional UIWindow with a high windowLevel value to force the dragged view to appear on top of the popover, but this seems like overkill. Is there a better solution?
Got it. UIWindow works fine. Code:
// when drag starts
draggingView = [[UIWindow alloc] initWithFrame:CGRectMake(0,0,100,100)];
draggingView.windowLevel = UIWindowLevelAlert;
draggingView.center = [gestureRecognizer locationInView:self.view.window];
[draggingView makeKeyAndVisible];
// when drag ends
[draggingView release];
draggingView = nil;
Adding the Swift Version:
let windows: [UIWindow] = UIApplication.shared.windows
let firstWindow: UIWindow = windows[0]
firstWindow.addSubview(loadingView)
firstWindow.bringSubview(toFront: loadingView)
EDIT to admin: thanks for the review – deleted my other answer in duplicate How to show a UIView OVER a UIPopoverController
I've created a sub class of UITableViewController named LoginViewController with the XIB file using XCode. Then I opened the XIB file with IB and set the table's style to grouped. Finally I wrote the following code:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
LoginViewController *loginViewController = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:[NSBundle mainBundle]];
[window addSubview: loginViewController.view];
window.backgroundColor = [UIColor blueColor];
[window makeKeyAndVisible];
[window layoutSubviews];
}
I set the window's background color to blue for you to see what the problem is.
I put a link to the screenshot
As you can see in the screenshot the table view is not display correctly because a margin between the bottom of the main window and the table view is being set and I don't know why.
If I don't use the table style grouped the problem does not occur
The UITableView inside your .xib file probably has a negative vertical offset (i.e. y-axis), which would mean you need to adjust the origin (likely to 0,0) and the frame (to, say, 320x400, or whatever your parent view height is).
this is the common problem while working with the IBOutlet...
Try to create a UITableView programatically by writing code for it.
dont do drang and drop...
specify the framesize of UITableView manually in coding...
specify datasource and delegate manually in coding...
you will deffinatly solved your problem...
even if any problem leave a comment...and accept answer by clicking correct sign if you get resolved....
enjoy the day...
I wanted to add a view to the bottom of my screen. The controller is a UITableViewController, how do I shrink the tableView and add a extra view at the bottom of the tableview?
I've tried setting the frame of self.tableView in different places (viewDidLoad, viewWillAppear etc) but nothing happens. The tableView is created by IB and not programtically.
I've tried added a footer to my table view but that's not what I want, because the footer actually scrolls up, I want a static non moving View at the bottom of the screen.
I'm not saying you can't do it otherwise, but you may not want a UITableViewController for this situation. You can still have your view controller implement UITableViewDelegate and UITableViewDataSource, but place a vanilla UIView in your nib, into which you place a UITableView. Then just make sure to set the view outlet to the UIView containing your table. This has the effect of allowing you to create your additional view within IB. I just tried this and it appeared to work.
I'm guessing you're using a UINavigationController. When you push a controller onto your navigation stack, UINavigationController resizes its view to full screen, ignoring the geometry and autoresizing behavior you've defined in IB.
This resizing seems to happen after viewWillAppear:. In the past I've had some success resizing a table view and adding a sibling view in viewDidAppear:, after calling [super viewDidAppear:]. This is a bit risky though, since Apple could break it by changing how UINavigationController works behind the scenes.
A safer option is to push a view controller onto your navigation stack that controls a wrapper view. Then add your UITableView and its sibling as subviews of that wrapper view. The annoying thing about this option is that you'll probably want to use a nested UITableViewController to manage your non-full screen table view, but the documentation for UIViewController says it's designed to manage full screen views only. If you decide to ignore this admonition and nest your view controllers anyway, you'll find that viewWill/DidAppear/Disappear don't get called on the nested controller, so you'll have to manually delegate those methods from your wrapper view controller. This lack of support for nested controllers is one of my biggest pet peeves about UIKit, and I've gone to great lengths to engineer around it.
If you want to toe the line and use view controllers only for full screen views, you can push a normal view controller that controls your full screen wrapper view, manually implement all the UITableViewDataSource and UITableViewDelegate methods in your view controller, and set it as the delegate for your table view.
you want to change the -loadView method. Not viewDidLoad or viewWillAppear. This will allow you to make additional configurations with your tableview even if it is created in IB.
- (void)loadView {
[super loadView];
CGRect titleRect = CGRectMake(0, 0, 300, 40);
UILabel *tableTitle = [[UILabel alloc] initWithFrame:titleRect];
tableTitle.textColor = [UIColor blueColor];
tableTitle.backgroundColor = [self.tableView backgroundColor];
tableTitle.opaque = YES;
tableTitle.font = [UIFont boldSystemFontOfSize:18];
tableTitle.text = [curTrail objectForKey:#"Name"];
self.tableView.tableHeaderView = tableTitle;
[self.tableView reloadData];
[tableTitle release];
}
I don't know how to do it in IB but the way to do it in code is with this:
- (void) loadView
{
UITableView *tv = [[UITableView alloc] initWithFrame: rect
style: UITableViewStyleGrouped];
// finishg configuring table view
self.view = tv;
[tv release];
}
Trying to do it in two stages -- style first and then frame or frame first and then style -- neither of them works.