Animating a view on and off the screen in iOS - 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.

Related

view loading from the bottom doesn't fill whole view

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];

iOS 7 UIScrollView doesn't scroll when presented as modal view controller, works fine otherwise

I have a storyboard in which I have a view controller, (InfoViewController) in which I have an UIScrollView with some labels, uitextviews, etc. this is all created in IB, no code has been written at all. The only thing that is left for me to do is to set the content size, which I do as following:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
CGRect screenRect = [[UIScreen mainScreen] bounds];
[self.scrollView setContentSize:CGSizeMake(screenRect.size.width, 600)];
[self.scrollView setBackgroundColor:[UIColor greenColor]];
}
Whenever I make this view the entry point of my app, it works perfectly. I can see my view, the content size is set, the background color is being set to green.
Now it comes, I created another view controller, and this view controller is now my entry point of the app. I added a button in there, and on this button I did a "modal segue" to the earlier mentioned Info View Controller.
When I now run my app, I press this button, my Info View Controller shows up. The green background color is being set, but it's impossible to scroll. So the code is being executed (otherwise the background color couldn't been green, in the storyboard it's just plain white) but somehow whenever I use this "modal segue", the scroll functionality gets lost.
How can I fix this?
Try to insert a UIView into the scroll view...
Set the UIView with top, bottom, leading and trailing space to super view to 0.
Then insert everything into the UIView rather than into the ScrollView
Then modify the constraint height of the inner UIView instead of the contentsize of the scroll view, it works with iOS7

Scroll View with Navigation Bar within another Scroll View

I have an app with three view controllers that the user can swipe between. The app loads up on the middle view controller. I am trying to create a sort of help screen, made up of a scroll view containing 3 images that the user can swipe between, as well as a navigation bar at the top to allow the user to exit the help screen. This help screen is to be displayed on top of the main scroll view, leaving 20px margin all the way around.
This is my code so far, creating the help scroll view:
if ([[ UIScreen mainScreen ] bounds ].size.height == 568 ) {
NSArray *images = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"Guide Page One.png"], nil];
self.helpScrollView.contentSize = CGSizeMake(280 * 3, 528);
self.helpScrollView.pagingEnabled = YES;
CGFloat xPos = 0.0;
for (UIImage *image in images) {
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(xPos, 0.0, 280, 528);
[self.scrollView addSubview:imageView];
xPos += 280;
// assuming ARC, otherwise release imageView
}
This was me trying to get it to work on the 4" screens. When I ran the simulator, the one image in the scroll view was shown on the far left of the main scroll view, and had no navigation bar.
This is how my xib is set out:
And here is the result:
The main scroll view still scrolls. I do not want this. Basically what I want is for this help scroll view to show up with my images, and allow the user to scroll through them before closing it, and continouing to the main app.
How can I do this?
Your ImageView is added on the top of layer stack when [self.scrollView addSubview:imageView] is executed, so it just hides the NavigationBar
Your helpScrollView seems to be wrong positioned. You may add constraints to properly position it.
If you want main ScrollView not to respond touches you should set mainScrollView.scrollEnabled=NO before displaying help ScrollView and when it hides set nack to YES;

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)];

UIView sliding transition fades

I've got some code inside one of my view controllers that will make sliding transition from one view to another:
-(void)transitionToNewView:(UIView*)newView
{
UIView *superView = [self.view superview];
[superView addSubview:newView];
newView.frame = superView.bounds;
[self.view removeFromSuperview];
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[superView layer] addAnimation:animation forKey:#"keygoeshere"];
}
The sliding transition seems to work correctly, but I'm also seeing the new view fade in from a blank screen in addition to the sliding. I suspect that this is because I'm adding a new view to the super view that wasn't there before. What I'd like to do is the same thing, but without the fading in. How can I do this?
I think the kCATransitionPush transition does a fade at the same time by design. I could swear I remember reading that somewhere.
It would be pretty simple to construct a view-to-view push transition using the method transitionFromView:toView:duration:options:completion:.
Pass in UIViewAnimationOptionTransitionNone for the transition option, and then use an animation block that slides the current view off-screen while sliding the new view on-screen from the opposite direction.
I don't have a straight answer to your issue but one way I found out for handling transition between two views is to add the new view to your superview like you did, take a screenshot of each view, realize the animation and remove the two screenshots views when the transition is done. I explained more in detail what i did here and it works very well. I think it worth a try to resolve the problem you are facing. Any reason otherwise you don't use the animateWithDuration method on UIView?

Resources