UIWindow addSubview handle events - ios

I want to build a custom alert by UIViewController and add its view as a subview to the current window. The view displays very well, but I can't handle any touch events.
I have tried many times to add a button to this viewcontroller and add a target. I have also tried adding a UITapGestureRecognizer and set view's userInteractionEnabled to true, but this also failed even when I cleared all subviews just left the button.
Have I missed something?
Here is the code:
CustomAlert Viewcontroller:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor clearColor];
backgroundView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
backgroundView.backgroundColor = [UIColor blackColor];
backgroundView.alpha = 0.5;
[self.view addSubview:backgroundView];
backImage = [[UIImageView alloc]initWithFrame:CGRectMake((self.view.frame.size.width - 300) / 2, (self.view.frame.size.height - 250) / 2, 300, 250)];
backImage.image = [UIImage imageNamed:#"AlertBackground"];
[self.view addSubview:backImage];
confirmButton = [[UIButton alloc]initWithFrame:CGRectMake( backImage.frame.origin.x + 100 , backImage.frame.origin.y + 250 - 40, 100, 26)];
[self.view addSubview:confirmButton];
[confirmButton addTarget:self action:#selector(confirmButtonClick:) forControlEvents:UIControlEventTouchUpInside];
confirmButton.backgroundColor = [UIColor redColor];
[confirmButton setTitle:#"click me" forState:UIControlStateNormal];
}
-(void)confirmButtonClick:(UIButton*)sender{
[self.view removeFromSuperview];
}
-(void)show{
UIWindow * window = (UIWindow*)[UIApplication sharedApplication].keyWindow;
[window addSubview:self.view];
}
Method call custom alert:
CustomAlert * alert = [[CustomAlert alloc]init];
[alert show];

Try to rewrite your -show{} method with these
UIWindow * window = (UIWindow*)[UIApplication sharedApplication].keyWindow;
[window.rootViewController.view addSubview:self.view];
UPDATE:
And if previous don't help, try to overwrite
-(void)show{
UIWindow * window = (UIWindow*)[UIApplication sharedApplication].keyWindow;
[window.rootViewController addChildViewController:self];
[window.rootViewController.view addSubview:self.view];
[self didMoveToParentViewController:window.rootViewController];
}
Those three methods establish parent-child relations.

Related

Obj-C: How to fix constraint for PageViewController, PageController and 2 buttons

I followed this link https://www.appcoda.com/uipageviewcontroller-storyboard-tutorial/ to create a 'PageViewController' with 'PageControl' Instead of adding the button at the bottom of the Page Control. I want to add 2 buttons at the left and right of the Page Control.
Problem
I managed to add the button with the following code but the constraint is out. I want to try to set it at Storyboard but not sure where should I do it. Please help.
#implementation RootViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_pageTitles = #[#"", #"", #""];
_pageImages = #[#"4.png", #"5.png", #"4.png"];
// Create page view controller
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"PageViewController"];
self.pageViewController.dataSource = self;
PageContentViewController *startingViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = #[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
// Change the size of page view controller
self.pageViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
btnLogin = [[UIButton alloc]initWithFrame:CGRectMake(0,self.view.frame.size.height-30, self.view.frame.size.width/4, 20)];
btnLogin.backgroundColor = [UIColor colorWithRed:19.0f/255.0f green:147/255.0f blue:182.0f/255.0f alpha:1.0];//%%% buttoncolors
[btnLogin setTitle:#"LOGIN" forState:UIControlStateNormal];
[btnLogin addTarget:self action:#selector(btnLoginClicked:) forControlEvents:UIControlEventTouchUpInside];
btnRegister = [[UIButton alloc]initWithFrame:CGRectMake(self.view.frame.size.width-((self.view.frame.size.width/4)),self.view.frame.size.height-30, self.view.frame.size.width/4, 20)];
btnRegister.backgroundColor = [UIColor colorWithRed:19.0f/255.0f green:147/255.0f blue:182.0f/255.0f alpha:1.0];//%%% buttoncolors
[btnRegister setTitle:#"REGISTER" forState:UIControlStateNormal];
[btnRegister addTarget:self action:#selector(btnRegisterClicked:) forControlEvents:UIControlEventTouchUpInside];
[self addChildViewController:_pageViewController];
[self.view addSubview:_pageViewController.view];
[self.view addSubview:btnLogin];
[self.view addSubview:btnRegister];
[self.pageViewController didMoveToParentViewController:self];
}
Iphone Six is OK
Iphone XSMax is out of constraint
StoryBoard
Try the following solution by OnkarK
UIWindow *window = UIApplication.sharedApplication.keyWindow;
CGFloat bottomPadding = window.safeAreaInsets.bottom;
// Change the size of page view controller
self.pageViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
btnLogin = [[UIButton alloc]initWithFrame:CGRectMake(0,self.view.frame.size.height-30-bottomPadding, self.view.frame.size.width/4, 20)];
**I got the following but how to get rid of the white space **
Thanks #phani, it is really the constraint issue, must always constraint to SuperView, hopefully will help someone in future
As you are adding button programmatically, you need to consider safe area while setting frame. Try this:
UIWindow *window = UIApplication.sharedApplication.keyWindow;
CGFloat bottomPadding = window.safeAreaInsets.bottom;
btnLogin = [[UIButton alloc]initWithFrame:CGRectMake(0,self.view.frame.size.height-30-bottomPadding, self.view.frame.size.width/4, 20)];

when home button pressed view origin changed?

I have this code in viewDidLoad:
[self.navigationController setNavigationBarHidden:YES];
self.edgesForExtendedLayout = UIRectEdgeNone;
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
self.view.backgroundColor = [UIColor whiteColor];
//we need to add white background behind the status bar
CGFloat statusBarHeight = [UIApplication sharedApplication].statusBarFrame.size.height;
UIView* statusBarWhiteBackGround = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, statusBarHeight)];
[statusBarWhiteBackGround setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:statusBarWhiteBackGround];
UIView * redBackGroundColor = [[UIView alloc] init];
[redBackGroundColor setBackgroundColor:[UIColor redColor]];
redBackGroundColor.frame =CGRectMake(0,statusBarHeight , self.view.frame.size.width, self.view.frame.size.height-statusBarHeight);
[self.view addSubview:redBackGroundColor];
statusWhiteBackGround view is used to change the color of the status bar.
here is the result of the above code:
but when the app enter background and then back to foreground, the redBackGroundColor view change it's orging.y as you can see in the bellow picture:
what's the problem ?thanks
Create a UIView programatically on method
-(void)viewDidLayoutSubviews{
screen=[[UIScreen mainScreen] bounds];
//Simple view
self.customView = [[CustomAlertOKView alloc]initWithFrame:CGRectMake(0, 20, screen.size.width, screen.size.height)];
[self.view addSubView:customView];
}
or
Create a view using storyboard and set the x as 0, y value as 20,width and height based on the screen size
#IBOutlet UIView *customView;
set the outlet in the storyboard,
Then set the background color of the custom view to redcolor and main view to white color
self.view.backgroundColor = [UIColor whiteColor];
customView.backgroundColor = [UIColor redColor];

Dismiss custom alert view iOS

I'm setting up a subclass of UIView to roll my own UIAlertView style view. I've got everything set up properly with displaying the view, but I'm at a bit of a loss as to how to dismiss the view properly. Specifically, when a user taps on the button in the view, it needs to animate out of the main view. This is the code for the view itself:
+ (void)showCustomAlertWithTitle:(NSString *)titleString andMessage:(NSString *)messageString inView:(UIView *)view andButton1Title: (NSString *)button1Title andButton2Title: (NSString *)button2Title
{
UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject];
CGRect windowFrame = window.frame;
[view setAlpha:0.5f];
UIColor *buttonColor = [UIColor colorWithRed:0/255.0f green:130/255.0f blue:216/255.0f alpha:1];
UIColor *titleColor = [UIColor colorWithRed:0/255.0f green:153/255.0f blue:102/255.0f alpha:1];
// Shade
UILabel *shadeWindow = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, windowFrame.size.width, windowFrame.size.height)];
shadeWindow.backgroundColor = [UIColor blackColor];
shadeWindow.alpha = 0.50f;
// Define size and origin of alert box
float alertBoxHeight = 225;
float alertBoxWidth = 200;
float alertBoxXorigin = windowFrame.size.width / 2 - (alertBoxWidth / 2);
float alertBoxYorigin = windowFrame.size.height / 2 - (alertBoxHeight / 2);
// Initialize background
UIView *alertBackground = [[UIView alloc] initWithFrame:CGRectMake(alertBoxXorigin, alertBoxYorigin, alertBoxWidth, alertBoxHeight)];
alertBackground.layer.cornerRadius = 5.0f;
[alertBackground.layer setMasksToBounds:YES];
alertBackground.layer.backgroundColor = [UIColor whiteColor].CGColor;
// Title Label
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, alertBoxWidth, 40)];
titleLabel.text = titleString;
titleLabel.textAlignment = NSTextAlignmentCenter;
titleLabel.textColor = titleColor;
titleLabel.layer.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.05f].CGColor;
[titleLabel setFont:[UIFont fontWithName:#"AvenirNext-Bold" size:20.0]];
// Title Divider
UILabel *titleDivider = [[UILabel alloc] initWithFrame:CGRectMake(0, 40, alertBoxWidth, 1.0)];
titleDivider.backgroundColor = [UIColor grayColor];
titleDivider.alpha = 0.5f;
// Alert Message Text
UITextView *alertMessage = [[UITextView alloc] initWithFrame:CGRectMake(0, 40, alertBoxWidth, alertBoxHeight - 90)];
alertMessage.text = messageString;
alertMessage.layer.backgroundColor = [UIColor whiteColor].CGColor;
[alertMessage setFont:[UIFont fontWithName:#"Avenir" size:15.0]];
alertMessage.textAlignment = NSTextAlignmentCenter;
alertMessage.textColor = [UIColor grayColor];
[alertMessage setEditable:NO];
// Button 1
UIButton *button1 = [[UIButton alloc] init];
UIButton *button2 = [[UIButton alloc] init];
[button1 addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
if (button2Title == nil)
{
button1.frame = CGRectMake(10, alertBoxHeight - 50, alertBoxWidth - 20, 40);
}
else
{
button1.frame = CGRectMake(10, alertBoxHeight - 50, (alertBoxWidth / 2) - 20, 40);
button2.frame = CGRectMake(alertBoxWidth / 2 + 10, alertBoxHeight - 50, (alertBoxWidth / 2) - 20, 40);
}
button1.layer.backgroundColor = buttonColor.CGColor;
[button1 setTitle:button1Title forState:UIControlStateNormal];
[button1.titleLabel setFont:[UIFont fontWithName:#"AvenirNext-Bold" size:15.0f]];
button1.layer.cornerRadius = 2.5f;
[button1.layer setMasksToBounds:YES];
// Button 2
button2.layer.backgroundColor = buttonColor.CGColor;
[button2 setTitle:button2Title forState:UIControlStateNormal];
[button2.titleLabel setFont:[UIFont fontWithName:#"AvenirNext-Bold" size:15.0f]];
button2.layer.cornerRadius = 2.5f;
[button2.layer setMasksToBounds:YES];
// Bounce Implementation
alertBackground.transform = CGAffineTransformMakeScale(0.01, 0.01);
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^
{
alertBackground.transform = CGAffineTransformIdentity;
}
completion:^(BOOL finished)
{
// do something once the animation finishes, put it here
}];
[window addSubview:view];
[window addSubview:alertBackground];
[view addSubview:shadeWindow];
[view bringSubviewToFront:alertBackground];
[alertBackground addSubview:button1];
[alertBackground addSubview:titleLabel];
[alertBackground addSubview:titleDivider];
[alertBackground addSubview:alertMessage];
[alertBackground addSubview:button2];
[alertBackground bringSubviewToFront:titleDivider];
/* [[[customAlerts sharedInstance] subViewArray] addObject:alertBackground];
[[[customAlerts sharedInstance] subViewArray] addObject:view];
[[[customAlerts sharedInstance] subViewArray] addObject:window];*/
}
When button1 is tapped, for instance, I need to have it animate the view out of the superView and remove it from the stack. I'm not sure how to handle this. Does anyone have any ideas?
To permanently remove a view, I generally use the UIView instance method removeFromSuperview. followed by a line setting the relevant variable to nil:
[myAlertView removeFromSuperview];
myAlertView = nil;
In your case then, I think you need to move the view off the screen by animating the its bounds property, then use the above couple of lines to remove any references to it.
Just found the answer here:
Dismiss view controller from #selector without creating seperate method
Had to download some custom classes but it worked:
[button1 addEventHandler:^(id sender, UIEvent *event)
{
[UIView animateWithDuration:0.25f animations:^{
[alertBackground setAlpha:0.0f];
[shadeWindow setAlpha:0.0f];
[window setAlpha:0.0f];
}];
} forControlEvent:UIControlEventTouchUpInside];
Custom classes can be found here:
https://github.com/ZeR0-Wu/JTTargetActionBlock

How can I add UIView object to self.view.window in ios7?

I'd like to add a dark view layer that covers the whole screen.
In order to do that, I added UIView object to window property of UIViewController as shown below.I remember I was able to add a view to window like this in ios6. But, it doesn't work in ios7.
How am I able to make it work?
Thanks in advance!!
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *overlayView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
overlayView.backgroundColor = [UIColor blackColor];
overlayView.alpha = 0.8;
[self.view.window addSubview:overlayView];
}
Here's one way of doing what you want:
[[UIApplication sharedApplication].keyWindow addSubview:overlayView];
According to the documentation of UIView, the window property is nil if the view has not yet been added to a window which is the case when viewDidLoad is called.
You can do the same thing in viewDidAppear:(BOOL)animated;
- (void)viewDidAppear:(BOOL)animated; {
UIView *overlayView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
overlayView.backgroundColor = [UIColor blackColor];
overlayView.alpha = 0.8;
[self.view.window addSubview:overlayView];
}
Swift 3
UIApplication.shared.keyWindow?.addSubview(overlayView);
you can try like this
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *overlayView = [[UIView alloc] initWithFrame:self.view.frame];
overlayView.backgroundColor = [UIColor blackColor];
overlayView.alpha = 0.8;
overlayView.center = self.view.center
[self.view addSubview:overlayView];
}
i hope will helpful for you...

creating uiview programmatically?

Creating a view with following code.
- (void)loadView {
paintView=[[UIView alloc]initWithFrame:CGRectMake(0, 50, 320, 430)];
[paintView setBackgroundColor:[UIColor yellowColor]];
self.view = paintView;
[paintView release];
But my problem is whole screen fills with yellow color, but I want with specified frame.
I am creating this view in a view based application.. Am i doing something wrong, Overridind the original view?
You can do it in following way.
- (void)loadView {
/// make a empty view to self.view
/// after calling [super loadView], self.view won't be nil anymore.
[super loadView];
paintView=[[UIView alloc]initWithFrame:CGRectMake(0, 50, 320, 430)];
[paintView setBackgroundColor:[UIColor yellowColor]];
[self.view addSubview:paintView];
[paintView release];
};
UIView *newView = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,35)];
newView.backgroundColor=[UIColor clearColor];
UITextView *mytext = [[UITextView alloc] initWithFrame:CGRectMake(5.0, 0.0, 100.0, 28.0)];
mytext.backgroundColor = [UIColor clearColor];
mytext.textColor = [UIColor blackColor];
mytext.editable = NO;
mytext.font = [UIFont systemFontOfSize:15];
mytext.text = #"Mytext";
mytext.scrollEnabled=NO;
[mytext release];
[newView addSubview:mytext];
[self.view addSubview:newView];
replace self.view =paintView;
by
[self.view addSubview: paintView];
I am Going change Line No 3 in LoadView Method , you should add the subView in main View instead on assiging it Directly.
[self.view addSubview:paintview];

Resources