简体   繁体   中英

Expand and Collapse View in iOS App smoothly?

I have an UIView inside a UIViewController . I want to expand that UIView and collapse. This feature is same as in iOS OS we drag View from Top, but in iOS it comes upon whole of App but I want to put this inside UIViewController .

LIKE THIS

在此处输入图片说明

I have tried Expand and Collapse, but resizing Frame size but I am unable to Drag it and again up.

What I did is.

- (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 can't expand, or also resize issue in AutoLayout, so have to remove it.

I need it like below...

在此处输入图片说明

Thanks

Bottom To Top:

 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 to Bottom:

     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!");




     }];

I have solved my issue with help of 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 did like 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

在此处输入图片说明

在此处输入图片说明

while when I run, it looks like :)

在此处输入图片说明

在此处输入图片说明

Happy Coding !!!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM