I have a brief for a share page which involves clicking on a share button and a modal view appearing over the top with some share functionality.
My issues is that i'd like the background of the modal view to be semi transparent and therefore show the view beneath. I've set the background properties of the modal layer and as the modal appears the layer beneath is briefly visible - and looks exactly as I require - but as soon as the cover transition is complete the background view is hidden - is there any way around this?
(Using IOS7 by the way)
Cheers
Update - #Tommaso Resti has kindly helped me try and figure this issue out - to explain what I've done so far - my main storyboard contains an unlinked uiview with the identifier 'ShareScreenView' - which I would like to add to my mainView as a transparent modal when clicking on a button. I have linked the button as an IBAction and added the following to my method -
- (IBAction)shareBtn:(id)sender {
NSLog(#"clicked");
/* Create your view off the screen (bottom) */
/* NEW EDIT */
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main_iPhone"
bundle: nil];
UIViewController *myModalController = [mainStoryboard instantiateViewControllerWithIdentifier:#"ShareScreenView"];
[myModalController.view setFrame:CGRectMake(0, 568, 320, 568)];
// [myModalController.view setFrame: CGRectMake(0, [[UIScreen mainScreen].bounds.size.height], [[UIScreen mainScreen].bounds.size.width], [[UIScreen mainScreen].bounds.size.height])];
/* Animate it from the bottom */
[UIView animateWithDuration:.5 animations:^{
CGAffineTransform move = CGAffineTransformMakeTranslation(0, -[UIScreen mainScreen].bounds.size.height);
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
myModalController.view.transform = move; /* UPDATED HERE */
NSLog(#"Atrying");
} completion:^(BOOL finished) {
NSLog(#"Adid try");
if(finished) {
NSLog(#"Animation completed");
}
}];
}
But I get an error on the line -
[myModalController.view setFrame: CGRectMake(0, [[UIScreen mainScreen].bounds.size.height], [[UIScreen mainScreen].bounds.size.width], [[UIScreen mainScreen].bounds.size.height])];
which simply states 'expected identifier' with an arrow pointing at height (see screen shot below)
so I tried adding the properties as follows -
[myModalController.view setFrame:CGRectMake(0, 568, 320, 568)];
now there are no errors - but nothing happens and no errors..
i suggest to use your own method:
something like this:
/* Create your view off the screen (bottom) */
/* NEW EDIT */
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard"
bundle: nil];
UIViewController *myModalController = [mainStoryboard instantiateViewControllerWithIdentifier:#"MyModalController"];
[myModalController.view setFrame: CGRectMake(0, [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
[self.view addSubview: myModalController.view]; /* UPDATED HERE! */
/* Animate it from the bottom */
[UIView animateWithDuration:.5 animations:^{
CGAffineTransform move = CGAffineTransformMakeTranslation(0, -[UIScreen mainScreen].bounds.size.height);
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
myModalController.view.transform = move; /* UPDATED HERE */
} completion:^(BOOL finished) {
if(finished) {
NSLog(#"Animation completed");
}
}];
than remove with this animation:
/* Reset animation */
[UIView animateWithDuration:.5 animations:^{
CGAffineTransform reset = CGAffineTransformIdentity;
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
myModalController.view.transform = reset; /* UPDATED HERE */
} completion:^(BOOL finished) {
if(finished) {
NSLog(#"Reset completed");
[myModalController.view removeFromSuperview];
}
}];
--- EDITED ---
Sorry, i forgot to add ".view " after myViewController.
i never try my code... my fault ;)
The example is updated!
You can create a View, which you slide in from the bottom and then make the view semi transparent.
You can use View Container to create your own ModalViewController and do animation just like #Tommaso Resti says
Related
I've to implement UIPrintInteractionController inside popup. I've implemented -
(UIViewController *)printInteractionControllerParentViewController:(UIPrintInteractionController *)printInteractionController {
UINavigationController* navigationController = [[UINavigationController alloc] init];
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navigationController];
[popover presentPopoverFromRect:address.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[popover.contentViewController.view setBackgroundColor:[UIColor grayColor]];
navigationController.preferredContentSize = CGSizeMake(320, 540);
return navigationController;
}
But it crashes saying :
reason: '-[UIPopoverController initWithContentViewController:] called when not running under UIUserInterfaceIdiomPad.'
Even on testing in ipad simulator. what to do ? I've to implement popup just like .
you can figure out the difference device whether it is iPad or iPhone using below code ..
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// code for iPad here
}else{
// code for iPhone here
}
updated
you can use custom view to popover using below method by passing a uiview to it.
-(void) popOver:(UIView *)view{
view.hidden = NO;
view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001, 0.001); // view to popup
[UIView animateWithDuration:0.3
animations:^{
view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.1, 1.1);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1
animations:^{
view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9,0.9); // custom view
}completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 animations:^{
view.transform = CGAffineTransformIdentity; // custom view to pop
}];
}];
}];
}
this method shows a uiview like popover now will be able to add any of the UI components over it.
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!
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.
I have a View (CupsViewController) with a Label and when it's clicked, TableView (AddressTableController) slides from the bottom of the screen and stays in the lower half.
In TableView, when Ok Buttonis pressed, I want to change value of Labeland remove TableViewwith animation (that is, slide to the bottom).
Here is my code:
CupsViewController
Method called when click on Label
- (IBAction)showPop:(id)sender
{
addressTableController = [[AddressTableController alloc]initWithStyle:UITableViewStyleGrouped];
[addressTableController setDelegate:self];
[[self view] addSubview:[addressTableController myTableView]];
[UIView animateWithDuration:1.0 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
[[addressTableController myTableView] setFrame:CGRectMake(0, kScreenHeight * 0.5, kScreenWidth, kScreenHeight * 0.5)];
} completion:nil];
}
Method called from AddressTableControllerwhen Buttonis pressed
- (void)addressTableController:(AddressTableController *)viewController didChooseValue:(int)value {
direccionLabel.text = [[[[myAppDelegate usuarioActual] cups] objectAtIndex:value] direccion];
[addressTableController.view removeFromSuperview];
}
Image
As you can see, I've tried with removeFromSuperviewbut it does nothing. How can I slide TableViewto the bottom?
It seems that you myTableView property returns a different view, not the one that is referenced in the view property. So you basically add the former as a subview ([[self view] addSubview:[addressTableController myTableView]];), but try to remove the latter ([addressTableController.view removeFromSuperview];).
Just do
[[addressTableController myTableView] removeFromSuperview];
instead of
[addressTableController.view removeFromSuperview];
Here you go. Cheers, mate! :)
P.S.
if you want to animate the view out, you can do it like this
[UIView animateWithDuration:1.0 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
// animation code...
} completion:^(BOOL finished) {
[[addressTableController myTableView] removeFromSuperview];
}];
I'm try to popViewcontroller with transform scale animation
according this code when it begin transform it present the black screen instead of the Parent View
how to fix this ?
[UIView animateWithDuration:0.5f
delay:0.0f
options:UIViewAnimationCurveEaseInOut
animations:^{
self.view.alpha = 1.0f;
self.view.transform = CGAffineTransformMakeScale(0.5f, 0.5f);
} completion:^(BOOL finished) {
[[self navigationController] popViewControllerAnimated:NO];
}];
This is the expected behavior, because the view of the previous controller is not in the view hierarchy until popViewControllerAnimated: method is called and you call it after the animation finishes.
I don't think adding subviews directly to the view of the navigation controller is a good idea, but the following code should work for you.
UINavigationController* navigationController;
CGRect frame;
//keep a reference to the navigation controller as
//[self navigationController] won't work after pop is called
navigationController = [self navigationController];
//remember the frame of the view relative to navigation controller's view
frame = [navigationController.view convertRect:self.view.frame fromView:self.view.superview];
//pop this controller, this will add the view of the
//previous controller into the view hierarchy
[navigationController popViewControllerAnimated:NO];
self.view.frame = frame;
//add this view on top of the previous one
[navigationController.view addSubview:self.view];
[UIView animateWithDuration:0.5f
delay:0.0f
options:0
animations:^{
self.view.alpha = 0.0f;
self.view.transform = CGAffineTransformMakeScale(0.5f, 0.5f);
} completion:^(BOOL finished) {
[self.view removeFromSuperview];
}];
By the way, UIViewAnimationCurveEaseInOut is not a correct constant for the options parameter. You should use the constants that start with UIViewAnimationOption for this method.