Expand and collapse view in iOS app smoothly?

I have a UIView inside a UIViewController . I want to expand this UIView and collapse. This function is the same as in iOS OS, we drag View from Top, but in iOS this is for the whole app, but I want to put this inside a UIViewController .

LIKE THIS

enter image description here

I tried expanding and collapsing, but resizing the frame, but I can't drag it and up again.

I did it.

- (IBAction)expandCollapseView:(UIButton *)sender {
    NSLog(@"Hello");


    if (!_isExpended) {
        NSLog(@"IF ");

        _isExpended = YES;

        [UIView beginAnimations:@"animationOff" context:NULL];
        [UIView setAnimationDuration:1.3f];
        [_expandableView setFrame:CGRectMake(0, 0, 768, 40)];
        [UIView commitAnimations];
    } else {
        NSLog(@"ELSE");
        _isExpended = NO;

        [UIView beginAnimations:@"animationOff" context:NULL];
        [UIView setAnimationDuration:1.3f];
        [_expandableView setFrame:CGRectMake(0, 0, 768, 489)];
        [UIView commitAnimations];
    }



}

      

// But this code is useless in my sense. as I cannot expand or resize the question in AutoLayout so it needs to be removed.

I need it like below ...

enter image description here

thank

+3


source to share


2 answers


I solved my problem with some stack questions and forums.

In my VSViewController class, I did something like below

//
//  VSViewController.h
//  Veer
//
//  Created by Veer Suthar on 27/08/2014.
//  Copyright (c) 2014 Veer. All rights reserved.
//

#import <UIKit/UIKit.h>

#import "VSCategoryTableViewCell.h"
#import "VSSourcesTableViewCell.h"

@interface VSViewController : UIViewController <UIGestureRecognizerDelegate>

// Views
@property (nonatomic, strong) IBOutlet UIView *swipeableView;
@property (nonatomic, strong) IBOutlet UIView *dragableView;
@property (nonatomic, strong) IBOutlet UIView *revealableView;

// Frames
@property (nonatomic) CGRect swipeableViewFrame;
@property (nonatomic) CGRect dragableViewFrame;
@property (nonatomic) CGRect revealableViewFrame;

// State
@property (nonatomic, getter=isDragging) BOOL dragging;
@property (nonatomic, getter=isRevealableViewShowing) BOOL revealableViewShowing;

// Gesture recognizers
@property (nonatomic, strong) UIPanGestureRecognizer *drag;

// Drag and swipe logic
- (void)hideRevealableView;
- (void)showRevealableView;
- (void)offsetFrames:(CGFloat)offset;

- (void)handleDrag:(UIPanGestureRecognizer *)gestureRecognizer;

@end

      

While in .m I liked below

//
//  VSViewController.m
//  Veer
//
//  Created by Veer Suthar on 27/08/2014.
//  Copyright (c) 2014 Veer. All rights reserved.
//

#import "VSViewController.h"

#define UITABLEVIEW_CATEGORIES 1
#define UITABLEVIEW_SOURCES 2


@interface VSViewController ()

@property (weak, nonatomic) IBOutlet UITableView *table_categories;
@property (weak, nonatomic) IBOutlet UITableView *table_sources;

@property (nonatomic, retain) NSMutableArray *array_category;
@property (nonatomic, retain) NSMutableArray *array_sources;

@end

@implementation VSViewController

@synthesize swipeableView = _swipeableView;
@synthesize dragableView = _dragableView;
@synthesize revealableView = _revealableView;
@synthesize swipeableViewFrame = _swipeableViewFrame;
@synthesize dragableViewFrame = _dragableViewFrame;
@synthesize revealableViewFrame = _revealableViewFrame;


@synthesize drag = _drag;
@synthesize dragging = _dragging;
@synthesize revealableViewShowing = _revealableShowing;

- (void)viewDidLoad
{
    [super viewDidLoad];
    //CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;

    _array_category = [[NSMutableArray alloc] init];

    _array_sources= [[NSMutableArray alloc] init];

    for (int x = 0; x<6; x++) {
        NSString *str = [NSString stringWithFormat:@"Category %d", x];
        [_array_category addObject:str];
    }

    for (int x = 0; x<5; x++) {
        NSString *str = [NSString stringWithFormat:@"Source %d", x];
        [_array_sources addObject:str];
    }

    [_table_categories reloadData];
    [_table_sources reloadData];

    //Area where all the other views, buttons will show, which will hide and show
    self.swipeableViewFrame = CGRectMake(0.0f, 0.0f, 786.0f, 382.0f);

    //Area we will hold and drag up and down
    self.dragableViewFrame = CGRectMake(365.0f, 382.0f, 38.0f, 40.0f);


    //Area for logic, handled at backend. white, so user can't see.
    self.revealableViewFrame = CGRectMake(0.0f, 424.0f, 768.0f, 1.0f);

    // Add our gesture recognizers on dragableViewFrame so user can drag up and down.
    self.drag = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleDrag:)];
    [self.dragableView addGestureRecognizer:self.drag];
    [self.drag setDelegate:self];
    [self.drag setCancelsTouchesInView:NO];


}

- (void)viewDidUnload
{
    [super viewDidUnload];

    // Release any retained subviews of the main view.
    self.swipeableView = nil;
    self.dragableView = nil;
    self.revealableView = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (void)hideRevealableView
{
    [self offsetFrames:0.0f];
    //Change image if your put image view, for arrow UP
}

- (void)showRevealableView
{
    [self offsetFrames:-self.swipeableViewFrame.size.height];
    //Change image if your put image view, for arrow UP

}

- (void)offsetFrames:(CGFloat)offset
{
    // Grab our views and drag them
    self.swipeableView.frame = CGRectOffset(self.swipeableViewFrame, 0.0f, offset);
    self.dragableView.frame = CGRectOffset(self.dragableViewFrame, 0.0f, offset);
    self.revealableView.frame = CGRectOffset(self.revealableViewFrame, 0.0f, offset);
}


- (void)handleDrag:(UIPanGestureRecognizer *)gestureRecognizer
{
    if (self.isDragging && gestureRecognizer.state == UIGestureRecognizerStateEnded) {
        // Reset isDragging
        self.dragging = NO;

        // If it is over, we check the velocity of the drag
        // to see if we want to finish dragging it up or down
        CGPoint origin = [gestureRecognizer velocityInView:self.view];
        CGFloat velocity = origin.y;
        CGFloat vertical;
        NSTimeInterval duration;

        // If the y value is negative, we are moving up and so attach the view
        if (velocity < 0) {
            // Calculate how many points we have to go before we hit our destination
            vertical = self.revealableView.frame.origin.y - self.view.frame.origin.y;
            duration = MIN(ABS(vertical / velocity), 1.0f);


            [UIView animateWithDuration:duration
                             animations:^
             {
                 [self showRevealableView];
             }
                             completion:^(BOOL finished)
             {
                 self.revealableViewShowing = YES;
             }
             ];
        }
        else {
            // Otherwise, at a standstill or moving back, we want to retract the view
            vertical = self.revealableView.frame.origin.y - self.dragableView.frame.origin.y;
            duration = MIN(ABS(vertical / velocity), 1.0f);


            [UIView animateWithDuration:duration
                             animations:^
             {
                 [self hideRevealableView];
             }
                             completion:^(BOOL finished)
             {
                 self.revealableViewShowing = NO;
             }
             ];


        }
    }
    else if (self.isDragging) {
        //[self performSegueWithIdentifier:kRevealShadeViewSegueIdentifier sender:nil];
        // Keep track of where we are
        CGPoint origin = [gestureRecognizer locationInView:self.view];

        // As long as we aren't going above the top of the view, have it follow the drag
        if (CGRectContainsPoint(self.view.frame, origin)) {
            // Only allow dragging to a certain point. Don't let drag further down.
            CGPoint translatedPoint = [gestureRecognizer translationInView:self.view];

            // Our offset is different depending on if the revealable view is showing or not
            CGFloat offset = (self.isRevealableViewShowing) ? self.swipeableViewFrame.size.height : 0.0f;

            if (translatedPoint.y < offset) {
                // Track the drag
                [self offsetFrames:translatedPoint.y - offset];
            }
            else {
                // Stick to the bottom
                [self hideRevealableView];
            }
        }
    }
    else if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
        // Now, we are dragging
        self.dragging = YES;
    }
}



- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.

    if (tableView.tag == UITABLEVIEW_CATEGORIES) {
        return [_array_category count];
    }else if (tableView.tag == UITABLEVIEW_SOURCES){
        return [_array_sources count];
    }else
        return 0;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Configure the cell...

    NSLog(@"Hello Cell or row");

    if (tableView.tag == UITABLEVIEW_CATEGORIES) {

        VSCategoryTableViewCell *cell =NULL;

        NSString *identifier=@"VSCategoryTableViewCell";

        cell = (VSCategoryTableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
        NSString *str = [_array_category objectAtIndex:indexPath.row];

        [cell.button1 setTitle:str forState:UIControlStateNormal];
        [cell.button2 setTitle:str forState:UIControlStateNormal];
        [cell.button3 setTitle:str forState:UIControlStateNormal];


        return cell;
    }else if (tableView.tag == UITABLEVIEW_SOURCES){

        VSSourcesTableViewCell *cell =NULL;

        NSString *identifier=@"VSSourcesTableViewCell";

        cell = (VSSourcesTableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];

        NSString *str = [_array_sources objectAtIndex:indexPath.row];

        [cell.button1 setTitle:str forState:UIControlStateNormal];


        return cell;
    }
    return 0;

}


-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    NSLog(@"did select");

}

@end

      

My storyboard looks low below



enter image description here

enter image description here

when i run it looks like this :)

enter image description here

enter image description here

Happy coding !!!!

+1


source


Down below:

 CGRect basketTopFrame = _loginViewBack.frame; // _loginViewBack is UIView you Need to Animated View.
 basketTopFrame.origin.y = 100;

    [UIView animateWithDuration:0.25
                          delay:0.0
                        options: UIViewAnimationOptionTransitionCurlDown
                     animations:^{
                         _loginViewBack.frame = basketTopFrame;

                     }
                     completion:^(BOOL finished)
     {




     }];

      



Top down:

     CGRect basketTopFrame = _loginViewBack.frame;
     basketTopFrame.origin.y = 305;

    [UIView animateWithDuration:0.25
                          delay:0.0
                        options: UIViewAnimationOptionTransitionCurlUp
                     animations:^{
                         _loginViewBack.frame = basketTopFrame;

                     }
                     completion:^(BOOL finished)
     {
         //NSLog(@"Done 1233!");




     }];

      

0


source







All Articles