I use keyWindow to add a subView, it add success but did not shows in the front of the screen hierarchy.
The deep gray view is my added view:
My code is:
#interface ViewController ()
{
LMLUpspringView *pop_v;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
pop_v = [[LMLUpspringView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
UIWindow *keywindow = [[[UIApplication sharedApplication] delegate] window];
[keywindow addSubview:pop_v];
//[keywindow bringSubviewToFront:pop_v];
//[self.view addSubview:pop_v];
}
I have tried use [keywindow bringSubviewToFront:pop_v] to bring to front.But do not work.
And if I use [self.view addSubview:pop_v], it shows in the front.
You run into this issue, is caused by you do not know the difference between the viewDidLoad method and the viewDidAppear: method.
viewWillAppear:
Called before the view is added to the windows’ view hierarchy
viewDidAppear:
Called after the view is added to the view hierarchy
The controller's view add to the window's view hierarchy is betweenviewWillAppear: and viewDidAppear:, the viewDidLoad is in front of viewWillAppear:, so you can not do that. you should in viewDidAppear: add your view.
You can solve this problem using appdelegate's Windows :
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.window addSubview:pop_v]
Use this:
#interface ViewController ()
{
LMLUpspringView *pop_v;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
pop_v = [[LMLUpspringView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
UIWindow *keywindow = [[UIApplication sharedApplication] keyWindow];
[keywindow addSubview:pop_v];
//[keywindow bringSubviewToFront:pop_v];
//[self.view addSubview:pop_v];
}
Related
I want to display a UIView on top of other views, no matter what view is currently displayed. So I created the following method in custom class that is not related to any views:
- (void) showLoading {
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(100,100, 100, 100)];
[redView setBackgroundColor:[UIColor redColor]];
[[appDelegate window] addSubview: redView];
}
The view is not displayed when the method is called. However it is displayed if I rotate device, so screen orientation is changed. I guess that I should reload view somehow, but at this point I'm stuck. Could you please help me?
Thank you, dtrotzjr, for good question. The problem was that the method was called from background thread. Here is the solution:
dispatch_async(dispatch_get_main_queue(), ^{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(100,100, 100, 100)];
[redView setBackgroundColor:[UIColor redColor]];
[[appDelegate window] addSubview:redView];
});
Sorry for bothering.
You can create a AlertViewController and present that on top of any view controller, you can even make this AlertViewController to be transparent.
self.parentVC = someVC;/*this should be the VC over which you want to present the alert VC */
self.modalPresentationStyle = UIModalPresentationCustom;
[self setTransitioningDelegate:someDelegate];
dispatch_async(dispatch_get_main_queue(), ^{
[self.parentVC presentViewController:self
animated:YES
completion:^{
}];
});
I've been developing for iOS for quite a while now, but I always got problems with custom alerts / popups, I just don't know what is the right way to add a custom view as a popup on top of all other views in app.
I've checked online and there are several ways to do it, but what is the best way for creating those custom alerts / popups?
There is a CustomViewController class and this is how I've created it and add it as a popup:
Create a new UIViewController
Add a UIView inside the UIViewController's XIB file as a child of self.view (This will hold the popup elements inside)
Add this method inside the UIViewController for presenting the view:
- (void)presentViewController
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.windowLevel = UIWindowLevelStatusBar;
self.window.screen = [UIScreen mainScreen];
[self.window makeKeyAndVisible];
UIWindow *mainWindow = [[[UIApplication sharedApplication] delegate] window];
[mainWindow setUserInteractionEnabled:NO];
[self.window addSubview:self.view];
self.view.alpha = 0.0f;
self.backgroundImage.image = [self takeSnapshot];
[UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.view.transform = CGAffineTransformIdentity;
self.view.alpha = 1.0f;
} completion:nil];
}
Add this method inside the UIViewController for removing the view:
- (void)dismissShareViewController
{
[UIView animateWithDuration:DEFAULT_ANIMATION_DURATION
animations:^{
self.view.alpha = 0.0f;
} completion:^(BOOL finished) {
[self.view removeFromSuperview];
self.window = nil;
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
UIWindow *mainWindow = [[[UIApplication sharedApplication] delegate] window];
[mainWindow setUserInteractionEnabled:YES];
}];
}
Usage:
Creating a property for the UIViewController
#property (strong, nonatomic) CustomViewController *viewController;
Initialize and present
- (void)showCustomViewController
{
self.viewController = [[CustomViewController alloc] init];
[self.viewController presentViewController];
}
The problem is that I always get a Received Memory Warning. Also I've added a - (void)dealloc method inside the CustomViewController to know if the UIViewController is releasing properly, but for some reason the dealloc method is getting called right after the presentViewController and not after the dismissShareViewController as it should.
Another thing that I want to achieve: This CustomViewController has no UIStatusBar and when I try to present MFMailComposeViewController, I always get the MFMailComposeViewController to show without a UIStatusBar or with white status bar, but I can't change it to default back again. I've tried several question here on StackOverflow but without any luck, it just won't change.
Putting a UIView or UIWindow above Statusbar
Please, for once and for all, someone will help me with it.
UIAlertView is a subclass of UIView. If you wanted to create a custom alert view, I would also subclass UIView so that it is easy to swap out your existing UIAlertView's with your new custom view.
You can place your custom alert view atop your topmost UIWindow to cover everything.
#interface MyAlertView : UIView
- (void)duplicateAllTheFunctionsOfUIAlertViewHere;
#end
#implementation MyAlertView : UIView
- (id)initWithFrame:(CGRectMake)frame {
// add your custom subviews here
// An example of a custom background color:
self.backgroundColor = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:0.5];
}
- (void)duplicateAllTheFunctionsOfUIAlertViewHere {
//re-implement all the functionality in your custom ways
}
- (void)show
{
UIView* superview = [UIApplication sharedApplication].keyWindow;
self.frame = superview.bounds;
[superview addSubview:self];
// Do an animation if you want to get fancy
}
#end
Usage in a view controller:
- (void)showAlertView
{
UIView* alertView = [[MyAlertView alloc] initWithTextAndButtons:#"blah"];
[alertView show];
}
I am trying to create a shared iADBannerView across multiple View Controllers in a Tabbed Application. I have tried different ways to create this, including Apple's iAdSuite but have been unsuccessful.
Currently with my code, which works but I have received errors such as:
"The operation couldn’t be completed. Ad was unloaded from this banner"
App Delegate .h
#import <iAd/iAd.h>
#interface AppDelegate : UIResponder <ADBannerViewDelegate>{
BOOL bannerIsVisible;
}
#property BOOL bannerIsVisible;
#property (nonatomic, strong) ADBannerView *adView;
App Delegate .m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
return YES;
}
View Controller .m
- (void)viewDidLoad
{
...
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
appDelegate.adView.delegate = self;
appDelegate.adView.frame = CGRectOffset(appDelegate.adView.frame, 0, self.view.frame.size.height);
[appDelegate.adView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[self.view addSubview:appDelegate.adView];
appDelegate.bannerIsVisible = NO;
}
-(void)bannerViewDidLoadAd:(ADBannerView *)banner
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (!appDelegate.bannerIsVisible){
[UIView beginAnimations:#"animateAdBannerOn" context:NULL];
banner.frame = CGRectOffset(banner.frame, 0, -50);
[UIView commitAnimations];
appDelegate.bannerIsVisible = YES;
}
}
-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (appDelegate.bannerIsVisible){
[UIView beginAnimations:#"animateAdBannerOff" context:NULL];
banner.frame = CGRectOffset(banner.frame, 0, 50);
[UIView commitAnimations];
appDelegate.bannerIsVisible = NO;
}
}
If anyone has implemented shared iAds, help would be appreciated, thanks in advance!
Edit: Found a solution by following this video
This is possible, all you have to do is make a master UIViewController with the ad and then use a container view controller with the Tab stuff. See the following links:
Apple documentation on container views:
https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html
This is an awesome library that does all the management for you.
https://github.com/tomohisa/JTCAdBaseViewController
I'm attempting to use a UINavigationController that utilizes a custom subclass of UINavigationBar. However, I'm running into a problem with initWithFrame. When initWithFrame is called, I print out the dimensions and it shows a 0.0 width and 0.0 height. But, when I print out the same frame in -(void) layoutSubviews inside of the UINavigationBar subclass, the frame is correctly set. Why is initWithFrame receiving a zero-sized frame, and what can I do to fix this? It doesn't sound correct to be manually calling initWithFrame or anything like that, since UINavigationController should take care of that. Here is the relevant code:
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UINavigationController *navController = [[UINavigationController alloc] initWithNavigationBarClass:[CustomNavigationBar class] toolbarClass:nil];
CoolViewController *vc = [[CoolViewController alloc] init];
[navController pushViewController:vc animated:YES];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
CustomNavigationBar.m
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
NSLog(#"initWithFrame with frame: %f, %f", frame.size.width, frame.size.height); // This prints "initWithFrame with frame: 0, 0"
}
return self;
}
Thank you!
I believe the navigation controller doesn't actually set the frame size to a specified value. Instead, it asks the navigation bar for its sizeThatFits: and uses that. By definition, that can't be done and passed to initWithFrame:. So, you want to use a combination of sizeThatFits:, setFrame: and layoutSubviews to add, size and reset your navigation bar content.
I have problems with displaying view as subview on navigationController.view on Ipad . I need to display view with transparent background on my viewController(with navBar),but while i change orientation my navBar become visible on foreGround of my view;
I created simple view based app.
Here code i added to project:
AppDelegate.h:
UINavigationController *_navController;
#property (strong, nonatomic) UINavigationController *navController;
AppDelegate.m:
_navController = [[[UINavigationController alloc] initWithRootViewController:self.viewController] autorelease];
self.window.rootViewController = _navController;
ViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *view = [[[UIView alloc] initWithFrame:self.view.frame] autorelease];
[view setBackgroundColor:[UIColor redColor]];
[self.navigationController.view addSubview:view];
}
try pushing view to Navigation Controller
YourAppDelegate *del = (YourAppDelegate *)[UIApplication sharedApplication].delegate;
[del.navigationController pushViewController:nextViewController animated:YES];
or
UINavigationController* navigation = [[UINavigationController alloc] init];
iVkViewController *overviewViewController = [[iVkViewController alloc] init];
overviewViewController.title = #"First";
[navigation pushViewController:overviewViewController animated:NO];