view loading from the bottom doesn't fill whole view - ios

I am using this code to load a view when I touch a button in Xcode.
UIStoryboard *storyboard = self.storyboard;
UIViewController *svc = [storyboard instantiateViewControllerWithIdentifier:#"FirstCar"];[self presentViewController:svc animated:YES completion:nil];
The view loads from the bottom, which I wish it didn't but loaded from the side instead. The main problem is that when it finish loading there is a gap at the top of about 1/2 inch. I have used this code to load it above the top depending screen size.
backgroundView = [[UIImageView alloc] initWithFrame:CGRectMake(-20, -20, 454, 776)];
It used to work ok but now for some reason it doesn't. And when I top/hold on an object to move it using "DragView", the object moves jerkily but the whole view moves up and down. I can even make the views contents completely disappear by swiping down. It doesn't go the the previous view just totally blank black. I don't know if that is related but something is weird.
Does anyone have any ideas what I am doing wrong.
Thanks in advance.

What you are describing is the default behavior of a presented view controller in iOS 13 - presented VCs slide in from the bottom and leave a gap at the top (indicating that the user can dismiss by dragging down).
You can remove the gap (and swipedown behavior) by setting the presented VC's modalPresentationStyle to fullscreen like this:
svc.modalPresentationStyle = UIModalPresentationFullScreen;
Add that line before calling present (or you can set that value in your storyboard) and you should see it cover the screen. You can find documentation of other presentation styles in the Apple docs
As for the right-to-left animation you mentioned, a sideways slide in is usually associated with UINavigation controller pushes rather than modal presentations, but as mentioned in this post, you can achieve the sideways animation on a modal using a custom transition.
Here's the relevant code in that post:
CATransition *transition = [[CATransition alloc] init];
transition.duration = 0.5;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
[transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[self.view.window.layer addAnimation:transition forKey:kCATransition];
[self presentViewController:svc animated:false completion:nil];

Related

iOS - Semi-transparent modal view controller

I want to present a view controller with a slightly transparent background modally over the current view, such that the first view is slightly visible under the modal view.
I set the alpha value of the modal view controller and set the modalPresentationStyle to UIModalPresentationCurrentContext, as suggested in another post.
The result is that the view background is transparent when animating up, but when view controller is in place it changes to opaque black. It goes back to being transparent while animating the dismissal.
How can I get it to be transparent when active ?
I have tested in iOS 6 and 7. The code I am using follows:
MyModalViewController *viewController = [[MyModalViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
[navController setNavigationBarHidden:YES];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self.navigationController presentViewController:navController animated:YES completion:NULL];
iOS 8 added a new modal presentation style specifically for this purpose:
presentedViewController.modalPresentationStyle = UIModalPresentationOverFullScreen
From the spec:
UIModalPresentationOverFullScreen
A view presentation style in which the presented view covers the screen. The views beneath the presented content are not removed from the view hierarchy when the presentation finishes. So if the presented view controller does not fill the screen with opaque content, the underlying content shows through.
If you are targeting ios 8 and above you can set the modal presentation style to "over current context" and you are done.
If ios 7 and below, you would have to create a custom transition style so that the presenting screen doesn't go blank after transition. That is rather complicated.
The solution I present offers a lot of flexibility: make a screenshot before showing the modal dialog and set that as the background image for the application window. By default, that background is black (that is what you see when the back view controller dissapears). Change the background to the screenshot of the app. Make the screenshot in the viewWillAppear or viewDidLoad method of your transparent view. This works even with push segues, not only modal dialogs, but you should avoid animations. In general, avoid animations which affect the position of the background view because those will make it seem like it snaps back into place when transition finishes. It is a good idea to reset the background to its previous black image on viewDidDissapear to avoid unwanted effects.
You can maintain a stack of such background images and you can do multiple "transparent" push seques. Or have some complex/deep menu which appears on top of some main screen. For these many reasons I think this solution is better than rolling your own transitioning code. It is more flexible and easier to implement, and you don't have to deal with the animations yourself.
The reason that the BG view controllers disappear after a modal is shown is that the default transition in iOS 7 removes the BG view after animation completed. If you define your own transition and you set your BG view not to be removed (just changing its alpha) then you will have the transparent modal view.
Same problem occured to me. I have solved it by looking at the following url about a custom alert controller. I managed to get it working even with a UINavigationController.
Swift
let viewController = UIViewController()
viewController.providesPresentationContextTransitionStyle = true
viewController.definesPresentationContext = true
viewController.modalPresentationStyle = .overCurrentContext
viewController.modalTransitionStyle = .crossDissolve
DispatchQueue.main.async {
self.navigationController?.present(viewController, animated: true, completion: nil)
}
Objective C
UIViewController *viewController = [UIViewController new];
viewController.providesPresentationContextTransitionStyle = true;
viewController.definesPresentationContext = true;
viewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
viewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
dispatch_async(dispatch_get_main_queue(), ^{
[self.navigationController presentViewController:viewController animated:true completion:nil];
});
Here is a solution.
Create your presenting view controller. Add a backView to this view controller's main view. Name this as backView.
In SecondViewController.m
-(void)viewDidLoad
{
// Make the main view's background clear, the second view's background transparent.
self.view.backgroundColor = [UIColor clearColor];
UIView* backView = [[UIView alloc] initWithFrame:self.view.frame];
backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
[self.view addSubview:backView];
}
Now you have a view controller with half transparent background. You can add anything you want to the self.view , the rest will be half transparent.
After that, in FirstViewController.m
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:secondViewController animated:YES completion:nil];
My solution is this:
Create a custom transparent overlay UIView that comes over any view, navigationbar and tabbbar.
-In the navigation controller (or tabbar controller) that your view controller is embedded in I create a custom view with it's frame equal to the frame of the navigation controller's view.
-Then I set it offscreen by setting it's origin.y to navigationController.view.height
-Then I create 2 functions -(void)showOverlay and -(void)hideOverlay that animate the overlay view on and off screen:
- (void)hideOverlay{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
CGRect frm = self.helpView.frame;//helpView is my overlay
frm.origin.y = self.offscreenOffset; //this is an Y offscreen usually self.view.height
self.helpView.frame = frm;
[UIView commitAnimations];
}
- (void)showOverlay{
[self.view bringSubviewToFront:self.helpView];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
CGRect frm = self.helpView.frame;
frm.origin.y = self.onscreenOffset;
self.helpView.frame = frm;
[UIView commitAnimations];
}
-In my view controller I can just call
[(MyCustomNavCtrl *)self.navigationController showOverlay];
[(MyCustomNavCtrl *)self.navigationController hideOverlay];
And that's about it.
FYI: The syntax is now:
childVC.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen
Why don't you try setting this in AppDelegate
self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
then changing the alpha on the view being presented

objective-c CATransition issue

that code blocks for storyboard viewcontrollers animation and its working but not what i want.. iwant left to right animation bu its doing "left bottom" corner to top right corner. not left to right why?
and second how can i stop animation?
UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UIViewController *destinationController = (UIViewController*)[self destinationViewController];
CATransition* transition = [CATransition animation];
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromRight;
[destinationController.view.layer addAnimation:transition forKey:kCATransition];
[sourceViewController presentViewController:destinationController animated:YES completion:nil];
You need to wrap the code in a CATransaction.
You need to turn off the default animation (animated:NO)
For the animation to have effect, it must be added to the superview's layer. In case of presented controllers, the window layer would be a smart choice.
"Move In" animation "from Right" won't be a "left to right" animation.
Note that it most cases you have to modify the animation direction depending on current interface orientation.
Sidenote: changing the animation of modal controllers is "frowned upon". You will simplify the problem greatly if you just use a child view controller.
I believe the "left to right" animation you are looking for may be the push animation of a UINavigationController. This may also be achievable with the kCATransitionPush transition type. Also, presentViewController triggers a "modal" animation (from bottom), so maybe using NO for the animated parameter in presentViewController might help also if you are not using a UINavigationController.

iOS - properly animate between two UIViews using CATransition

I have a UIView already on my screen and i wish to "slide in" a new UIView from one of the four directions(left, right, up, down) depending on what kind of swipegesture that i detect. Getting the swipegesture info is already done and not a problem but now, lets say if I swipe to the left then i want another UIView instance to "slide in" from the right.
Specifically, as the new UIView is sliding in from the right, the old UIView starts to slide out of view sliding to the left until it is out of the view completely. In other words, i would like to have the effect taht you can see both UIViews during the animation until the original UIView is no longer visible. The same type of effect can be seen on your iPad, for example, as you are on your home screen and you swipe to the left - which slides in another screen of app icons from the right as your home screen slides out of view to the left. The only caveat that I would like to achieve would be that you cannot stop the transition midstream.
Anyway here is the code that i have so far - I think that i am close but would like to get some help on perhaps finishing what i need to accomplish here:
UIView *newView = [[UIView alloc] init];
newView.frame = CGRectMake(0, 0, TileView.frame.size.width, TileView.frame.size.height);
[TileView addSubView:view];
CATransition *transitionAnimation = [CATransition animation];
[transitionAnimation setDuration:1];
[transitionAnimation setType:kCATransitionPush];
[transitionAnimation setSubtype:kCATransitionFromRight];
[transitionAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
The UIView TileView is a subview of my viewController. Is there any other setting up to do for newView so that everything matches as far as screen placement? I think that the KCATransitionPush is the type of animation I am looking for but not 100% sure.
Any help to what I am missing here would be helpful.
try to set these two property also....
transitionAnimation.fromValue=[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0.0, 0.0, 0.0)];
transitionAnimation.toValue=[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(excursion, 0.0, 0.0)];

iOS - CATransition and transitionWithView issues

Whenever I use either CATransition or transitionWithView to "push" one view from the right, there is a brief moment where the view that's getting pushed in fades in from black (or whatever the background color is), and the view that's getting pushed away fades out to black.
This might be the intended effect, but it looks messy on my app, and was wondering if anyone knows of a way to prevent this "fade out/in" effect?
Here is the CATransition code I am using to present the new view:
myView = [[MyView alloc] initWithNibName:#"MyView" bundle:nil];
[myView setDelegate:self];
[[mainView layer] addAnimation:pushRightTransition forKey:nil];
// Add the view:
[mainView addSubview:[myView view]];

Animating a view on and off the screen in iOS

I am trying to create a list of data displayed to the user. When they click the next or previous button, or swipe on the scrollview, the view should transition off the screen from left to right or right to left depending on which button they press or the direction they swipe. I have it working except that the view slides across the whole screen (meaning it slides over top of the buttons).
Here is the code to do the transition. My scrollview is just a plain old view, but it is in the middle of the page, It's coordinates are (40,54,240,311) so I would like it to disappear at 280 and reappear at 40. Like I said, it currently comes onto the screen at 0 and exits the screen at 320 (in normal portrait mode).
//Animate the scrollview across the screen
CATransition* animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[self.scrollView layer] addAnimation:animation forKey:nil];
I would really like this to work like the Kindle App on the iPhone, where the user can drag the view left or right to show the next page. I have looked into maybe making it a scroll view. So the above code slides my scrollview across the screen, and inside my scrollview I simply have some label and an image I set.
//set the content of the screen
self.imageView.image = [UIImage imageNamed: #"image1.png"];
self.labelNumber.text = #"1";
self.labelText.text = #"Test";
A few initial ideas I have are that I need two scrollviews, and I have to transition between them, or I should make one really wide scrollview and have the data for the next or previous fact to the left or right. But both of these seem to be bad because I have to have a bunch of duplicate controls, outlets etc on the screen.
PS this is my first time posting on this site. woot.
You need to create a new blank UIView that is the super view of your scroll view and the same size as your scroll view. Then you need to call clipsToBounds:YES on this new super view.
Something like:
UIView *blankView = [[UIView alloc] initWithFrame:CGRectMake(40, 54, 240, 311)];
[newView setClipsToBounds:YES];
[scrollViewsParentView addSubview:blankView]
UIScrollView *yourScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 54, 311)];
[blankView addSubview:yourScrollView];
Notice the change in coordinates for "yourScrollView"? It's because its parent is now blankView.
Also, I've done your exact idea of using two UIScrollViews to show a transition between them. You have an on screen (showing) UIScrollView and an offscreen (not showing) UIScrollView and then do your animation to show the transition. In this case they would have the same parent (blankView).
You also might want to check out these UIView methods:
animateWithDuration:animations:
animateWithDuration:animations:completion:
animateWithDuration:delay:options:animations:completion:
Hope this answers your question.

Resources