21

My goal is to understand and implement feature via Core Animation.
I think it's not so hard,but unfortunately i don't know swift/Obj C and it's hard to understand native examples.


Visual implementation

So what exactly i want to do(few steps as shown on images):
1. Source
2. enter image description here
3. enter image description here
4. enter image description here

And the same steps to hide view(vice versa,from top to bottom) until this :

enter image description here

Also,i want to make this UIView more generic,i mean to put this UIView on my StoryBoard and put so constraints on AutoLayout(to support different device screens).

Any ideas? Thanks!

XTL
  • 1,452
  • 2
  • 17
  • 40
  • The features you want to implement _don't require_ `Core Animation`. It can be done by the simple `UIView animateWithDuration:` APIs. I'll highly _recommend_ reading some tutorials on this topic & try out the implementations first hand. Come up with some code, if its erroneous you can always ask for tweaks around here. :) https://www.raywenderlich.com/2454/uiview-tutorial-for-ios-how-to-use-uiview-animation – ystack Feb 19 '17 at 13:15

5 Answers5

28

You can use like this Extension

extension UIView{
    func animShow(){
        UIView.animate(withDuration: 2, delay: 0, options: [.curveEaseIn],
                       animations: {
                        self.center.y -= self.bounds.height
                        self.layoutIfNeeded()
        }, completion: nil)
        self.isHidden = false
    }
    func animHide(){
        UIView.animate(withDuration: 2, delay: 0, options: [.curveLinear],
                       animations: {
                        self.center.y += self.bounds.height
                        self.layoutIfNeeded()

        },  completion: {(_ completed: Bool) -> Void in
        self.isHidden = true
            })
    }
}
Gowtham Sooryaraj
  • 3,639
  • 3
  • 13
  • 22
12

Assuming the original view is something like:

var view = new UIView(new CGRect(View.Frame.Left, View.Frame.Height - 200, View.Frame.Right, 0));
view.BackgroundColor = UIColor.Clear;

Show:

UIView.Animate(2.0, 0.0,
    UIViewAnimationOptions.CurveLinear,
    () =>
        {
            view.BackgroundColor = UIColor.Blue;
            var height = 100;
            view.Frame = new CGRect(View.Frame.Left, view.Frame.Y - height , view.Superview.Frame.Right, height);
        },
    () =>
        {
            // anim done
        }                                  
);

Hide:

UIView.Animate(2.0, 0.0,
    UIViewAnimationOptions.CurveLinear,
    () =>
        {
            view.BackgroundColor = UIColor.Clear;
            var height = 100;
            view.Frame = new CGRect(View.Frame.Left, view.Frame.Y + height, view.Superview.Frame.Right, 0);

        },
    () =>
        {
            view.Hidden = true;
        }
);

enter image description here

SushiHangover
  • 73,120
  • 10
  • 106
  • 165
  • Thanks!!! Exactly what i need and works fine. But why when i'm trying to use my own UIView that was created in storyboard,its not working well,i mean its showing full view Height? https://i.stack.imgur.com/fuVhy.gif please see this .gif animation. Also,i tried to put parameter "height" as "View.Frame.Height" and it take real Height of view,but won't work :(. – XTL Feb 19 '17 at 14:51
  • Also,i have no idea,but constraints on AutoLayout seems that won't work in Xamarin.iOS designer(Storyboards). Do you have same behaviour ? I think ill create a new question about it... – XTL Feb 19 '17 at 15:00
  • @VetaLio If you are using constraints via a storyboard/xib, you will not want to animate the `Frame` height, but animate the constraint height. Add an outlet for the height constraint and do something like `this.HeightCon.Constant = 100;` in the animate Action. ref: outlet creation: https://developer.xamarin.com/guides/ios/user_interface/controls/part_1_-_creating_user_interface_objects/ – SushiHangover Feb 19 '17 at 15:13
  • i have no idea,but i cant write to you via "@" . So i have tried,but it didn't worked,so tomorrow ill try again. Btw,i will mark your answer as solution asap,but need to fix my problem :). – XTL Feb 19 '17 at 23:04
  • @SushiHangover, pls can you help with this on Swift 4 – Israel Meshileya May 20 '19 at 16:02
  • For Swift5 UIView.animate(withDuration: 2.0, delay: 0.0, options: AnimationOptions.curveLinear, animations: { view.backgroundColor = UIColor.blue view.frame = CGRect(x: view.frame.minX, y: view.frame.minY - height, width: view.superview!.x, height: height) }, completion: ({ _ in // Done })) – User18474728 Jan 20 '21 at 00:48
2

See my view case was opposite i am directly doing changes in that , test if it is working for you,

Show Logic

//Add your view on storyBoard / programmatically bellow tab bar

[self.view bringSubviewToFront:self.miniMenuView];

CGRect rectformedicationTableViewcell;// = CGRectZero;

rectformedicationTableViewcell = CGRectMake(0.0f, self.view.frame.size.hight, self.view.frame.size.width, 150.0f);

self.miniMenuView.frame = rectformedicationTableViewcell;

if([self.miniMenuView superview]) {
    self.miniMenuView.hidden = YES;
}
self.miniMenuView.hidden = NO;

[UIView animateWithDuration:0.3f
                      delay:0.0f
                    options:UIViewAnimationOptionBeginFromCurrentState
                 animations:^{
                       [self.miniMenuView setFrame:CGRectMake(0.0f, self.view.frame.size.hight - 150.0f, self.view.frame.size.width, 150.0f)];

                 }
                 completion:nil];

Hide Logic

[self.view sendSubviewToBack:self.miniMenuView];

[UIView animateWithDuration:0.3f
                      delay:0.0f
                    options:UIViewAnimationOptionBeginFromCurrentState
                 animations:^{

                                                 [self.miniMenuView setFrame:CGRectMake(0.0f, self.view.frame.size.hight, self.view.frame.size.width, 150.0f)];


                 }
                 completion:^(BOOL completed){
                     if([self.miniMenuView superview]) {
                         self.miniMenuView.hidden = YES;
                     }

                 }];

Consider this as basic idea do changes as per your requirements Best luck.

Mukesh Lokare
  • 2,159
  • 26
  • 38
1

Update answer from @SushiHangover in swift 4.x

Assuming the original view is something like:

yourView.frame = CGRect(x: 0, y: 900, width: yourView.frame.width, height:  yourView.frame.height)

Show:

    UIView.animate(withDuration: 0.5, delay: 0.2, options: .curveLinear, animations: {
        let height:CGFloat = 280;
        self.yourView.frame = CGRect(x: 0, y: self.yourView.frame.minY - height, width: self.yourView.frame.width, height: self.vBaseView.frame.height)
    }) { finished in
        // animation done
    }

Hide
Just add the height

self.yourView.frame.minY + height
Abdul Karim
  • 4,359
  • 1
  • 40
  • 55
0

I have also faced the issue like https://i.stack.imgur.com/fuVhy.gif commented https://stackoverflow.com/users/4793465/xtl for the above solution.

Am using the view at the bottom of web-view to show and hide like safari mobile browser.

attached the sample code below UIView *viewV; UILabel *label;

and viewdidload

-(void)viewDidLoad {
[super viewDidLoad];
WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init];
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:theConfiguration];
webView.navigationDelegate = self;
webView.UIDelegate = self;
webView.scrollView.delegate = self;
NSURL *nsurl=[NSURL URLWithString:@"https://www.google.com/"];
NSURLRequest *nsrequest=[NSURLRequest requestWithURL:nsurl];
[webView loadRequest:nsrequest];
[self.view addSubview:webView];

viewV = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height - 50, self.view.frame.size.width, 50)];
viewV.backgroundColor = [UIColor blueColor];
[webView addSubview:viewV];}

and scroll view delegate

-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGPoint velocity = [[scrollView panGestureRecognizer] velocityInView:scrollView.superview];
if (velocity.y == 0) {
    return;
}
if (velocity.y < -1) {
    // Scrolling left
    NSLog(@"Top");
    if (viewV.frame.origin.y != self.view.frame.size.height - 50) {// if already hidden, don't need to hide again
        return;
    }
    [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        viewV.backgroundColor = [UIColor clearColor];
        viewV.frame = CGRectMake(0, viewV.frame.origin.y + 50, self.view.frame.size.width, 0);

    } completion:^(BOOL finished) {

    }];
} else if (velocity.y > 1) {
    // Scrolling Right
    NSLog(@"Bottom");
    if (viewV.frame.origin.y != self.view.frame.size.height) { // if already shown, no need to do show again
        return;
    }
    [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        viewV.backgroundColor = [UIColor blueColor];
        viewV.frame = CGRectMake(0, viewV.frame.origin.y - 50, self.view.frame.size.width, 50);

    } completion:^(BOOL finished) {
    }];
}}

This worked for me.

Murugan M
  • 175
  • 3
  • 8