how to show Container View ViewController and hide Container view ViewController - ios

I want to show ContainerView's view controller as like this
I use the following Code and it shows as i want
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration: 0.8];
if (_addLinkQuestionView.isHidden == YES)
{
_addLinkQuestionView.hidden = NO;
_addLinkQuestionView.alpha = 1.0;
}
else
{
_addLinkQuestionView.alpha = 0.0;
_addLinkQuestionView.hidden = YES;
}
[UIView commitAnimations];
but Upon a click on blurr area, i want to hide container view. that area is the UIButton. I use the following code, but it does nothing.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration: 0.8];
_addLinkQuestionView.alpha = 0.0;
_addLinkQuestionView.hidden = YES;
[UIView commitAnimations];
Any Help. Thanx in advance.

Essentially it seems you need to show a alertview behaviour where all the ui from app is disabled while only the content in the dialog is enabled.
Add a public method like showOverlayView:(UIView*)v to your app delegate
On this method create a view, set alpha and add it to keywindow.
Now add the passed view to keywindow and calculate and set
its center property.
Alternatively you could use a library like MJPopupViewController or SLPopupViewController to do the job for you.

The correct way to do this :
1- New File -> UIView -> rename it to addLinkQuestionView
2- New File -> obj c class -> rename it to addLinkQuestionView
Now u have a xib,a .h and a .m
3- Go to the xib and in file's owner select your addLinkQuestionView u created in step 2
4- Design the xib as the picture link you posted and link up appropriate outlets to addLinkQuestionView.h
5- For initialization of your uiview in .h do this :
#import "addLinkQuestionView.h"
#implementation addLinkQuestionView
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// Initialization code.
[[NSBundle mainBundle] loadNibNamed:#"addLinkQuestionView" owner:self options:nil];
self.vuComplete.frame = CGRectMake(self.vuComplete.frame.origin.x, self.vuComplete.frame.origin.y, self.frame.size.width, self.frame.size.height);
[self addSubview:self.vuComplete];
self.vuContainer.layer.cornerRadius = 5.0;
self.vuContainer.layer.borderWidth = 1.0/[UIScreen mainScreen].scale;
self.vuContainer.layer.borderColor = [[UIColor clearColor]CGColor];
self.vuContainer.alpha = 0.0;
[self layoutIfNeeded];
}
return self;
}
-(void)awakeFromNib
{
}
- (IBAction)onBackgroundTapDismissView:(id)sender {
[UIView animateWithDuration:0.5
animations:^{self.vuContainer.alpha = 0.0;}
completion:^(BOOL finished){ }];
[self removeFromSuperview];
}
Note : - (IBAction)onBackgroundTapDismissView can be a accomplished by dropping a uitapgesturerecognizer on your addLinkQuestionView's greyed background uiview so that tapping it can dismiss the entire uiview (vuComplete)
6- Then add this in your main view controller that is presenting this pop up like this :
A- import addLinkQuestionView.h first
B- add this code on your button action that you're clicking for presenting addLinkQuestionView:
addLinkQuestionView *popup = [[addLinkQuestionView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[UIView animateWithDuration:0.25
animations:^{popup. addLinkQuestionView.alpha = 1.0;}
completion:^(BOOL finished){ }];
[self.view addSubview:popup];
Have fun!

Related

Custom UI: Popup in iOS Objective-C

I want to create a custom popup and I want to generate a code dynamically without using UI drag and drop.
The view should look like:
I am using the following code to call the popup :
CustomPopUp *cp = [[CustomPopUp alloc]init];
cp.view.frame = CGRectMake(0.0, 0.0, 300, 300);
KLCPopup* popup = [KLCPopup popupWithContentView:cp.view];
[popup show];
The custom popup code looks like:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.gaScreenName = #"Login";
if (firstPageLoad) {
return;
}
LinearLayoutPageHeading *heading = [[LinearLayoutPageHeading alloc] initWithText:#"Sign in." maxWidth:[LayoutValues getMaxWidthClipped]];
[self.topContainerContent addObject:heading];
NSString *content = #"New patient? Register here.";
LinearLayoutLinksViewItem *contentItem = [[LinearLayoutLinksViewItem alloc] initLinksViewWithText:content font:[PPFonts genericParagraphFont] maxWidth:[LayoutValues getMaxWidthClipped] links:nil];
[self.topContainerContent addObject:contentItem];
LinearLayoutTextInputAndLabel *emailField = [[LinearLayoutTextInputAndLabel alloc] initWithLabelText:#"EMAIL ADDRESS" maxWidth:[LayoutValues getMaxWidthClipped]];
emailField.textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
LinearLayoutButton *continueButton = [[LinearLayoutButton alloc] initWithText:#"SIGN IN" maxWidth:[LayoutValues getMaxWidthClipped] url:nil type:#"primary"];
[self.topContainerContent addObject:continueButton];
LinearLayoutLinksViewItem *noticesPar = [[LinearLayoutLinksViewItem alloc] initLinksViewWithText:#"By clicking Sign In you agree to our Consent to Telehealth, Consent to Request Medical Services, Privacy Policy and Terms of Use." font:[PPFonts signInTermsParagraph] maxWidth:[LayoutValues getMaxWidthClipped] links:nil];
noticesPar.padding = CSLinearLayoutMakePadding(0, noticesPar.padding.left, 10, noticesPar.padding.right);
[self.topContainerContent addObject:noticesPar];
[self renderPageContainers];
firstPageLoad = YES;
}
#end
I am using custom created view controller but am getting a blank popup.
Is there a way to get the above layout using standard UIViewController? I am new to iOS development and have not dynamically generated UI views so far.
If CustomPopUp is a viewcontroller, you need to instantiate it with a storyboard vc or a xib, something like this:
//For xib:
let a = UIViewController(nibName: "CustomPopUp", bundle: NSBundle.mainBundle()) as! CustomPopUp
//For storyboard
let b = UIStoryboard(name: "main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("CustomPopup") as! CustomPopUp
Not totally sure how you are dealing with this, but I recommended you to create a custom view, not a custom viewcontroller, easier to create and use
Create a custom View with xib and add subview of your current view contoller.
make property instance of popupView
in your viewController.h
#property (strong,nonatomic) YourPopUpViewClass *popupView;
in your viewController.m
setUp Popup View
self.popUpView.hidden = YES;
self.popUpView.frame = [UIScreen mainScreen].bounds;
self.popUpView.alpha = 0.0;
self.popUpView.delegate = self; // for hide PopupView and Other Functinality if you need
[self.view addSubview:self.popUpView];
Now Display On Button Click With Animation
-(void)showPopupView{
self.popUpView.hidden = No;
[UIView animateWithDuration:0.0 delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^ {
self.popUpView.alpha = 0.0
}completion:^(BOOL finished) {
[UIView animateWithDuration:0.3
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^ {
self.popUpView.alpha = 1.0
}completion:^(BOOL finished) {
}];
}];
}
And Hide like this
-(void)hidePopupView {
self.popUpView.hidden = No;
[UIView animateWithDuration:0.3 delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^ {
self.popUpView.alpha = 0.0
}completion:^(BOOL finished) {
self.popUpView.hidden = Yes;
}];
}
hope this will help you.
Here is the good example for custom popup. Custom PopUP View. Just add your container in it.
Found a feasible solution. I used a third party library to achieve the result KLCPopup
However I have a new question. My popup does have a custom view but it comes from a separate class (view). How do I make my current view change based on input to the popup view? Can I have links to a few useful documents. I do not need code, just need to be pointed in the right direction.

UIView block animation not working

I have a custom view (which draws callouts/bubbles) that I currently add as a subview to a UIImageView. It works as intended but I would like to animate the operation with a spring-like effect. I am using the below code but it does not work (the block gets executed but without animation):
/* ViewController */
UIImageView *iv = self.imageView;
ZGCBubbleView *bubbleView = [[ZGCBubbleView alloc] init];
bubbleView.hidden = YES;
[iv addSubview:bubbleView];
// UIView animation test
[UIView animateWithDuration:2.0
delay:0
usingSpringWithDamping:0.5
initialSpringVelocity:0.5
options:UIViewAnimationOptionAllowAnimatedContent & UIViewAnimationOptionLayoutSubviews
animations:^{
bubbleView.hidden = NO;
[self.view layoutIfNeeded]; // tried this
}
completion:nil];
I have tried to animate both the hidden property as well as the alpha properties but same result. I have also tried animating the addSubview method, no difference. I started out with a more simple animation as proof of concept but that didn't work either.
The above code is executed within a method which is called during the (void)viewDidAppear:(BOOL)animated cycle. Does this have anything to do with this in that the animation is being executed during the main thread? I have read something to that effect but unsure. Also, I am using auto layout for the UIImageView but didn't think that would matter in this case since the animation is being applied to a custom subview of the UIImageView.
Any help appreciated.
Better use alpha.
UIImageView *iv = self.imageView;
ZGCBubbleView *bubbleView = [[ZGCBubbleView alloc] init];
bubbleView.alpha = 0;
// bubbleView.hidden = YES;
[iv addSubview:bubbleView];
// UIView animation test
[UIView animateWithDuration:2.0
delay:0
usingSpringWithDamping:0.5
initialSpringVelocity:0.5
options:UIViewAnimationOptionAllowAnimatedContent & UIViewAnimationOptionLayoutSubviews
animations:^{
// bubbleView.hidden = NO;
bubbleView.alpha = 1;
//[self.view layoutIfNeeded]; // tried this
}
completion:nil];
Try with this.
UIButton *catchButton = (UIButton *)sender;
[UIView animateWithDuration:1.0
delay:0.0
options:UIViewAnimationOptionCurveEaseInOut//UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat |
animations:^{
catchButton.alpha = 0.4;
catchButton.enabled = NO;
}
completion:NULL];

Custom Segue doesn't animate

I have set up a custom dialog to appear via a custom segue when a button in a container view controller is pressed, the perform function is being called and everything appears to work just fine except for the animation.
Here is the segue on the storyboard:
Here is the button:
Here is the code for the segue:
#import "TimerDialogSegue.h"
#implementation TimerDialogSegue
-(void)perform
{
UIViewController *dst = [self destinationViewController];
//Doesn't appear work with the Timer View Controller as the source
// so I use the parent Home View Controller
UIViewController *src = [self sourceViewController];
src = src.parentViewController;
// set the view frame
CGRect frame;
frame.size.height = src.view.frame.size.height;
frame.size.width = src.view.frame.size.width;
frame.origin.x = src.view.bounds.origin.x;
frame.origin.y = src.view.bounds.origin.y;
dst.view.frame = frame;
// add the view to the hierarchy and bring to front
[src addChildViewController:dst];
[src.view addSubview:dst.view];
[src.view bringSubviewToFront:dst.view];
[UIView animateWithDuration:0.3f
animations:^
{
dst.view.alpha = 1.0f;
}];
}
#end
Here is the code from the Dialog that dismisses it, this part animates just fine
- (IBAction)cancelButtonPressed:(id)sender
{
[self dismiss:sender];
}
- (IBAction)dismiss:(id)sender
{
[UIView animateWithDuration:0.3f
animations:^
{
self.view.alpha = 0.0f;
}
completion:^(BOOL finished)
{
[self.view removeFromSuperview];
[self removeFromParentViewController];
}];
}
To summarize the Dialog appears and operates correctly the only issue is there is no animation when it appears. It does animate when it disappears. Anyone know how I might fix this or a workaround to animate this Dialog when it appears?
Thanks in advance for any help.
You are saying:
[UIView animateWithDuration:0.3f
animations:^
{
dst.view.alpha = 1.0f;
}];
But dst.view.alpha is 1 already so nothing happens. You can only animate a change.
For example, when you dismiss, you animate this:
self.view.alpha = 0.0f;
That works because self.view.alpha was 1 so there is actually a change to animate.

How to Show and Hide UIPickerView like iOS Keyboard?

I have this code to hide UIPickerView by default:
- (void)viewDidLoad
{
[super viewDidLoad];
[_memberList setAlpha:0];
}
and this code to show UIPickerView when a button tapped :
- (IBAction)buttonChooseMember {
[UIView animateWithDuration:0.6 delay:0. options:UIViewAnimationOptionCurveEaseInOut animations:^{
[_memberList setAlpha:1];
} completion:nil];
}
and the last thing is this, to hide keyboard when user tap anywhere :
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UIView * txt in self.view.subviews){
if ([txt isKindOfClass:[UITextField class]]) {
[txt resignFirstResponder];
}else if ([txt isKindOfClass:[UIPickerView class]]) {
[UIView animateWithDuration:0.6 delay:0. options:UIViewAnimationOptionCurveEaseInOut animations:^{
[_registerMLMList setAlpha:0];
} completion:nil];
}
}
}
but all of this just give me 'appear' animation, because it's only changing Alpha value from 0 to 1 (and vice versa). not slide-up or slide-down just like iOS keyboard.
I tried to use this animation below to have iOS keyboard look and feel on my UIPickerView :
- (IBAction)hidePicker {
UIPickerView *pickerView = [[UIPickerView alloc] init]; // default frame is set
float pvHeight = pickerView.frame.size.height;
float y = _screen.bounds.size.height - (pvHeight * -2); // the root view of view controller
[UIView animateWithDuration:0.5f delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.picker.frame = CGRectMake(0 , y, pickerView.frame.size.width, pvHeight);
} completion:nil];
}
- (IBAction)showPicker {
UIPickerView *pickerView = [[UIPickerView alloc] init]; // default frame is set
float pvHeight = pickerView.frame.size.height;
float y = _screen.bounds.size.height - (pvHeight); // the root view of view controller
[UIView animateWithDuration:0.5f delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.picker.frame = CGRectMake(0 , y, pickerView.frame.size.width, pvHeight);
} completion:nil];
}
I like this animation, it looks like iOS keyboard animation, but the problem with this animation is... when my app is loaded, the UIPickerView is already shows up. how to hide it when it loads up for the first time?
thank you.
All UIResponder objects have an inputView property. The inputView of a UIResponder is the view that will be shown in place of the keyboard when the responder becomes the first responder.
So if you want a UIPickerView to show up instead of the keyboard, you could simply do it by making your UIResponder (like a UITextField) have a UIPickerView as its inputView.
(As a caveat: you probably won't want a bare UIPickerView as the inputView, because you also need to account for when the keyboard would change size, like when you rotate. But this is the general idea.)
In viewDidLoad take one boolean variable and set it's value as TRUE and also set the UIPickerView's frame so that UIPickerView is invisible for first time.Based on the boolean value handle the frame animations to show or hide the picker view.
hidepicker and showpicker method idea is good, and the problem of "UIPicker is visible when the app is loaded" can be overcome by just setting the frame of UIPickerView while initiating it to the position such that it should not be visible...after that you can call the showpicker method to show the picker view.

How to reverse a UIVIew animation on second uibutton press?

I have a method that drops down a UIView. That works fine. How would I go about having it slide back up when the button is touched a second time?
I also need to deactivate it somehow so that it doesn't repeat the animation if it's already displayed.
- (void)slideDownTableView {
self.tableViewCities = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
self.tableViewCities.frame = CGRectMake(0,0,300,180);
self.tableViewCities.autoresizingMask = ( UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth );
self.tableViewCities.dataSource = self;
self.tableViewCities.delegate = self;
self.tableViewCities.backgroundColor = [UIColor whiteColor];
UIView *myview=[[UIView alloc] initWithFrame: CGRectMake(10, 0,300,180)];
myview.backgroundColor=[UIColor redColor];
[myview addSubview:self.tableViewCities];
[self.view addSubview:myview];
myview.frame = CGRectMake(10, 0,300,-180); // offscreen
[UIView animateWithDuration:0.5
animations:^{
myview.frame = CGRectMake(10, 0,300,180); // final location move
}];
}
iOS provides autoreverse property by which animation reverses automatically.
UIViewAnimationOptionAutoreverse will give you an effect as the animation reverses .
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionAutoreverse
animations:^{
// do whatever animation you want, e.g.,
someView.frame = someFrame1;
}
completion:NULL];
Using BeginFromCurrentState option worked for me.
if(!enabled){
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationTransitionCurlUp
animations:^{
myview.frame = CGRectMake(10, 0,300,180);
}
completion:nil];
enabled=YES;
}
else{
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationTransitionCurlUp
animations:^{
myview.frame = CGRectMake(10, 0,300,-180);
}
completion:nil];
enabled=NO;
}
With a simple BOOL to store the current state of the sliding UIView you can achieve this.
The initial state is not visible if I understand well? So initially the BOOL citiesVisible is set to N0, then the button's action check its value, and performs a different animation accordingly. Simple.
Finally, I also disable the button during the animation to prevent the user to trigger a second animation while a first one is already performing.
I rewrote a bit your code to follow some best practices, and improve readability/maintainability:
Setting up the views beforehand because the button's action responsibility shouldn't be to setup the views, but only to animate them.
Changed the signature of the target action, that's my personal style guide to state in the sender's name and the ControlEvent, it makes it more tidy when you have multiple buttons/actions ;). Also per Apple guidelines, methods receiving actions should have one "id" parameter, the sender.
Store the frames in variables (you could also have them as #define, that'd be even better I think), so you don't have to hard-code them twice, it reduces the risk of breaking the animation by having a view sliding to different positions...
Code update:
#interface ViewController ()
#property (nonatomic, strong) UIButton *showCitiesButton;
#property (nonatomic, strong) CGRect citiesInitialFrame;
#property (nonatomic, strong) CGRect citiesVisibleFrame;
#property (nonatomic, strong) UITableView *tableViewCities;
#property (nonatomic, strong) UIView *citiesContainer;
#property (nonatomic, strong) BOOL citiesVisible;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Setting up the cities view
self.citiesInitialFrame = CGRectMake(10, -180, 300, 180);
self.citiesVisibleFrame = CGRectMake(10, 0, 300, 180);
self.tableViewCities = [[UITableView alloc] init ...];
self.citiesContainer = [[UIView alloc] init ...];
// ...
self.citiesVisible = NO;
[self.showCitiesButton addTarget:self
action:#selector(showCitiesButtonDidTouchUpInside:)
forControlEvents:UIControlEventTouchUpInside];
}
- (void)showCitiesButtonDidTouchUpInside:(id)sender
{
[self.showCitiesButton setEnabled:NO];
if (self.citiesVisible)
{
// Cities view is visible, sliding it out of the screen
[UIView animateWithDuration:0.5
animations:^{
self.citiesContainer.frame = self.citiesInitialFrame;
} completion:^(BOOL finished) {
self.citiesVisible = NO;
[self.showCitiesButton setEnabled:YES];
}];
}
else
{
// Cities view is not visible, sliding it in
[UIView animateWithDuration:0.5
animations:^{
self.citiesContainer.frame = self.citiesVisibleFrame;
} completion:^(BOOL finished) {
self.citiesVisible = YES;
[self.showCitiesButton setEnabled:YES];
}];
}
}
#end
You can reverse UIView animation with this code:
if (isMarked) {
[UIView animateWithDuration:3
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:(void (^)(void)) ^{
self.transform=CGAffineTransformMakeScale(1.1, 1.1);
}
completion:nil];
} else {
[UIView animateWithDuration:3
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:(void (^)(void)) ^{
self.transform=CGAffineTransformIdentity;
}
completion:nil];
}

Resources