implement Facebook messenger style pan to full screen view similar effect
Asked Answered
F

2

9

I have implemented UIPageviewContoller to support multiple viewcontoller view at half bottom of my screen. now my question is how to support Facebook style panning effect to on of this subview on my pageview controller.

I want to achieve Facebook message style effect which they have applied in camera, in that with pan of finger we can make view as full screen. and when we pan down the same view it will adjust within original from of view.. Ihave attached some of screen for better understanding.

subview have pan gesture pan up to full screen pandown to minimize after pan down reset to original postion

and it should support integrative pop gesture to.

ienterative pop

I could able to get similar effect but for that i have added view to main window so view can pan to full screen but by this approach i am not able to achieve interactive pop iOS default gesture and this approach is not good with my current pageviewcontoller implementation.

and if view is added in window than if user pressed back button than window element will not move it will remain in window so windows approach is not good.

is there any other way to get similar effect? Does UIViewControllerInteractiveTransitioning may help for this ??

Thanks in advance. I know i will get better approach from you guys which will more stable for this than adding subview to window.

Ferrara answered 4/11, 2014 at 18:13 Comment(2)
I am trying to implement something similar. Can you give me a suggestion how you implemented the above using the PageViewController? Thanks.Durarte
I have added controller's view in window and with pan gesture to re-size y frame to window. you can try to add is according to your need like addsubview in navigation viewcontroller's view or window or viewcontroller. Than UIEdgesture(leftedge) recognizer will help you to set frame if interactive backswipe will perfom to set x postion. i am out of my desk right now so can't give you code. will post you after few days let me know if you are not able to do that,Ferrara
S
1

Have you tried adding swipe gesture to your subview A?

UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(didSwipeScreen:)];
swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
[yourSubViewA addGestureRecognizer:swipeUp];

and it's handling -

- (void)didSwipeScreen:(UISwipeGestureRecognizer *)gesture {
switch (gesture.direction) {
    case UISwipeGestureRecognizerDirectionUp: {
        [UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
            [yourSubViewA setFrame:desiredFullScreenFrame];
        } completion:^(BOOL finished) {
        }];
    }
        break;
    default:
        break;
    }
}

To bring back to default position you can add another swipe gesture with UISwipeGestureRecognizerDirectionDown or maybe just a tap gesture. And for side menu MFSideMenu is nice one.

Stibnite answered 13/11, 2014 at 9:26 Comment(2)
Actuly i dnt want slide menu . I similar effect is alredy impented by pan gesture but i want a effect like you subview will expand on pan to full window.Ferrara
Ok, then UISwipeGestureRecognizer will work on UISwipeGestureRecognizerDirectionUp event.Stibnite
E
0
Here, i used same code for my app for video sharing (same as facebook messenger media sharing)  

 Create one Uiview  Name as ViewCamera with one labelHoldText and three buttons
    and download SCRecoder from github

import SCRecoder class here in (.h) file and do same as below

        #import <UIKit/UIKit.h>
        #import "SCRecorder.h"
        #import "SCAudioTools.h"
        #import "SCRecorderFocusView.h"
        #import "SCRecordSessionManager.h"
        #import "SCTouchDetector.h"


        @protocol VideoRecordDelegate <NSObject>

        @optional

        -(void)VideoRecorded:(NSURL *)assetUrl;

        @end

        typedef enum : NSInteger {

            NOTRECORDING = 0,
            RECORDING=1,
            RETAKE,

        } ENUMRecordType;

        @interface ChatScreen : UIViewController<ChatCellDelegate,SCRecorderDelegate,UITableViewDataSource,UITableViewDelegate,,UIGestureRecognizerDelegate>
        {
            IBOutlet UIView *viewbottomForCamera;

            __weak IBOutlet UIButton *btnViewCameraChange;
            __weak IBOutlet UIButton *btnViewFullScree;
            __weak IBOutlet UIButton *btnVideoSend;


            PDColoredProgressView  *progressView;
            NSTimer *timerForVideoSend;
            CGFloat progressValue;
            UILabel *lblHoldtext;
            UILabel *lblCount;
            BOOL isCanceled,isOpen;

            IBOutlet UIView *viewCamera;



            //new

             UIView *previewView;
            CALayer *layerQ;

            SCRecorder *_recorder;
            UIImage *_photo;
            SCRecordSession *_recordSession;
            ENUMRecordType enumRecordType;


        }
        - (IBAction)btnInstantVideoTapped:(id)sender;
        - (IBAction)btnViewCameraTapped:(id)sender;
        - (IBAction)btnViewSendTapped:(id)sender;
        - (IBAction)btnViewFullScreenTapped:(id)sender;

        @property (strong, nonatomic) SCRecorderFocusView *focusView;
        @property (nonatomic) float  progress;
        @property (nonatomic, strong) CAShapeLayer *progressLayer;
        @property (nonatomic,strong) id<VideoRecordDelegate> deleagte;

        @end

            - (void)viewDidLoad {

            [super viewDidLoad];

//lbl hold text for = @"@"Hold send button for video, tap for photo""
            lblHoldtext =[[UILabel alloc]init];
            lblHoldtext.adjustsFontSizeToFitWidth = YES;
            [lblHoldtext setTextAlignment:NSTextAlignmentCenter];

            progressValue = 0;

              // pan for swipable camera view on touch      
            UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
            [panRecognizer setMinimumNumberOfTouches:1];
            [panRecognizer setMaximumNumberOfTouches:1];
            [viewCamera addGestureRecognizer:panRecognizer];

             //for video sharing on hold button       
            UILongPressGestureRecognizer *longGestureForSendImageORVideo = [[UILongPressGestureRecognizer alloc] init];
            [longGestureForSendImageORVideo addTarget:self action:@selector(LongPressForSendVideo:)];
            [longGestureForSendImageORVideo setMinimumPressDuration:1.0];
            [btnVideoSend addGestureRecognizer:longGestureForSendImageORVideo];

            [btnVideoSend.layer setBorderColor:[UIColor whiteColor].CGColor];
            //        UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"2Chat"]];
            [lblHoldtext setFrame:CGRectMake(20, 10, SCREENWIDTH-40, 20)];
            [lblHoldtext setText:@"Hold send button for video, tap for photo"];
            [viewCamera setFrame:CGRectMake(0, SCREENHEIGHT, SCREENWIDTH, viewCamera.frame.size.height)];
            [lblHoldtext setTextColor:[UIColor whiteColor]];
            [viewCamera addSubview:lblHoldtext];
            [viewCamera setBackgroundColor:[UIColor grayColor]];

            [self.navigationController.view addSubview:viewCamera];
            progressView = [[PDColoredProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
            progressView.frame =CGRectMake(0,viewCamera.frame.size.height-32, SCREENWIDTH, viewbottomForCamera.frame.size.height);
            [progressView.layer setMasksToBounds:NO];
            [progressView setTrackTintColor:[UIColor clearColor]];
            progressView.progress = 0.0;

            lblCount = [[UILabel alloc]initWithFrame:CGRectMake(40,15, 50, 30)];
            [lblCount setTextColor:[UIColor whiteColor]];
            [progressView addSubview:lblCount];

            //video recording
            _recorder = [SCRecorder recorder];
            _recorder.sessionPreset = AVCaptureSessionPresetMedium;//[SCRecorderTools bestSessionPresetCompatibleWithAllDevices];
            _recorder.maxRecordDuration = CMTimeMake(VIDEODURATIONLIMIT, 1);
            _recorder.delegate = self;
            _recorder.autoSetVideoOrientation = YES;

            self.focusView = [[SCRecorderFocusView alloc] initWithFrame:viewCamera.bounds];
            self.focusView.recorder = _recorder;

            [viewCamera addSubview:self.focusView];

        //    UIView *previewViewDemo = previewView;
            _recorder.previewView = viewCamera;
            [_recorder.videoConfiguration setSizeAsSquare:YES];
            //[_recorder.videoConfiguration setSize:CGSizeMake(SCREENWIDTH/2, SCREENHEIGHT/2)];
            _recorder.initializeRecordSessionLazily = YES;



            [_recorder openSession:^(NSError *sessionError, NSError *audioError, NSError *videoError, NSError *photoError) {

                //NSLog(@"==== Opened session ====");
                //NSLog(@"Session error: %@", sessionError.description);
                //NSLog(@"Audio error : %@", audioError.description);
                //NSLog(@"Video error: %@", videoError.description);
                //NSLog(@"Photo error: %@", photoError.description);
                //NSLog(@"=======================");
                [self prepareCamera];
            }];



        }
        - (void)layoutSubviews {
            // resize your layers based on the view's new bounds
            previewLayer.frame = viewCamera.bounds;
        }

        - (void)didReceiveMemoryWarning {
            [super didReceiveMemoryWarning];
        }

        -(void)viewWillAppear:(BOOL)animated
        {
            [super viewWillAppear:YES];    

        }
        -(void)viewWillDisappear:(BOOL)animated
        {
            [super viewWillDisappear:YES];
            [ShareObj setIsChtScreenPresent:NO];
            [self.view endEditing:YES];
            [viewCamera removeFromSuperview];
            [_recorder endRunningSession];

            [[NSNotificationCenter defaultCenter] removeObserver:self];
        }

        -(void)viewDidAppear:(BOOL)animated
        {
            [super viewDidAppear:YES];
            [_recorder startRunningSession];

        }
        - (IBAction)btnInstantVideoTapped:(id)sender {

        [self.view endEditing:YES];
        if (!isOpen) {

            isOpen = YES;
            [UIView animateWithDuration:0.5 animations:^{


                [_recorder.previewView setFrame:CGRectMake(0, SCREENHEIGHT-258,SCREENWIDTH,258)];
                _recorder.previewLayer.frame = _recorder.previewView.bounds;
                layerQ.frame = _recorder.previewView.bounds;
                [chatBottomView setFrame:CGRectMake(0,_recorder.previewView.frame.origin.y-chatBottomView.frame.size.height*2-12, SCREENWIDTH, chatBottomView.frame.size.height)];
                NSLog(@"hide frame = %@",NSStringFromCGRect(chatBottomView.frame));
                demoFrame=chatBottomView.frame;

                UISwipeGestureRecognizer *panView=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)];
                [_recorder.previewView addGestureRecognizer:panView];
                [_recorder.previewView bringSubviewToFront:viewbottomForCamera];
                [viewbottomForCamera bringSubviewToFront:btnViewFullScree];
                [viewbottomForCamera bringSubviewToFront:btnViewCameraChange];
                [self.navigationController.view addSubview:viewCamera];


            }completion:^(BOOL finished) {


            }];

        }
        else
        {
            isOpen = NO;

            [UIView animateWithDuration:0.5 animations:^{
                CGRect frame = chatBottomView.frame;
                frame.origin.y = SCREENHEIGHT-frame.size.height-NAVBARHEIGHT;
                [chatBottomView setFrame:frame];
                [_recorder.previewView setFrame:CGRectMake(0, SCREENHEIGHT, SCREENWIDTH, viewCamera.frame.size.height)];
                [tblChatMessage setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
                [tblChatMessage setScrollIndicatorInsets:UIEdgeInsetsMake(0, 0, 0, 0)];


                NSLog(@" hide frame = %@",NSStringFromCGRect(frame));
            } completion:^(BOOL finished) {
                [viewCamera removeFromSuperview];
            }];
        }
    }

        #pragma mark Gesture Event is called here..
    -(void)LongPressForSendVideo: (UILongPressGestureRecognizer*)recognizer
    {

       CGPoint pointOfTouch = [recognizer locationInView:viewbottomForCamera];

        if (recognizer.state == UIGestureRecognizerStateEnded) {

            [progressView setProgress:0.0 animated:YES];
            progressValue=0.0;
            [progressView removeFromSuperview];
            [timerForVideoSend invalidate];
            timerForVideoSend =nil;
            [layerQ removeFromSuperlayer];
            [btnViewCameraChange.layer setOpacity:1];
            [btnViewFullScree.layer setOpacity:1];

            [lblHoldtext setText:@"Hold send button for video, tap for photo"];

        }
        else if (recognizer.state==UIGestureRecognizerStateChanged)
        {
            if ( CGRectContainsPoint(btnVideoSend.frame, pointOfTouch ) ) {
                // inside
                [lblHoldtext setText:@"To cancel, drag your finger off send button"];

                NSLog(@"inside");
                [progressView setTintColor: [UIColor colorWithRed: 43.0/255.0 green: 134.0/255.0 blue: 225.0/255.0 alpha: 1]];
                [layerQ setBackgroundColor:[UIColor clearColor].CGColor];

            } else {
                // outside
                NSLog(@"outside");
                [lblHoldtext setText:@"Let go to delete and start over"];

                [progressView setTintColor:[UIColor redColor]];
                [layerQ setBackgroundColor:[UIColor colorWithRed:255.0/255.0 green:0/255.0 blue:0/255.0 alpha:0.2].CGColor];



            }

        }
        else if (recognizer.state==UIGestureRecognizerStateBegan)
        {
            layerQ = [[CALayer alloc]init];
            [layerQ setFrame:_recorder.previewLayer.frame];
            [viewCamera.layer addSublayer:layerQ];
            [btnViewCameraChange.layer setOpacity:0.3];
            [btnViewFullScree.layer setOpacity:0.3];
            [lblHoldtext setText:@"To cancel, drag your finger off send button"];

            [progressView setProgress:0.0 animated:YES];
            progressValue=0.0;
            if (timerForVideoSend == nil) {
                timerForVideoSend = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(progressChange) userInfo:nil repeats:YES];
            }
            [progressView setTintColor: [UIColor colorWithRed: 43.0/255.0 green: 134.0/255.0 blue: 225.0/255.0 alpha: 1]];
            [viewCamera addSubview:progressView];
            [viewCamera bringSubviewToFront:viewbottomForCamera];

        }

    }
    -(void)progressChange
    {
        progressValue = progressValue + 0.0065;
        [viewCamera bringSubviewToFront:lblCount];
        [lblCount setText:[NSString stringWithFormat:@"%.1f",progressValue]];
        [progressView setProgress:progressValue animated:YES];
    }
    - (void)handlePan:(UIPanGestureRecognizer*)recognizer
    {
        CGPoint vel = [recognizer velocityInView:viewCamera];
        CGFloat velocityFrame = (vel.y/70);

        if (vel.y > 0)
        {
            // user dragged towards the right
            NSLog(@" down");


                velocityFrame = velocityFrame;


            NSLog(@"velocity%f",velocityFrame);

            if (_recorder.previewView.frame.size.height >= 256) {

                    _recorder.previewView.frame=CGRectMake(0, _recorder.previewView.frame.origin.y+velocityFrame, SCREENWIDTH, _recorder.previewView.frame.size.height-velocityFrame);
                    [viewbottomForCamera setBackgroundColor:COLOR_WITH_RGBA(0, 0, 0, 0)];
                    CGFloat alphacolor = _recorder.previewView.frame.size.height/2000;
                    [viewbottomForCamera setFrame:CGRectMake(0, _recorder.previewView.frame.size.height-65, SCREENWIDTH, 65)];
                    [viewbottomForCamera setBackgroundColor:COLOR_WITH_RGBA(37, 37, 38, alphacolor)];
                    [lblHoldtext setFrame:CGRectMake(0, 0, 0, 0)];
                    [progressView.layer setFrame:viewbottomForCamera.frame];
            }

        }
        else
        {

            velocityFrame = -(velocityFrame);
            velocityFrame = velocityFrame;

            NSLog(@"velocity%f",velocityFrame);
            NSLog(@"up");
            if (_recorder.previewView.frame.origin.y >5) {


                [UIView animateWithDuration:0.2 animations:^{


                    _recorder.previewView.frame=CGRectMake(0, _recorder.previewView.frame.origin.y-velocityFrame, SCREENWIDTH, _recorder.previewView.frame.size.height+velocityFrame);
                    _recorder.previewLayer.frame = self.navigationController.view.bounds;
                    [viewbottomForCamera setFrame:CGRectMake(0,_recorder.previewView.frame.size.height-65, SCREENWIDTH, 65)];
                    CGFloat alphacolor = viewCamera.frame.size.height/1000;
                    [lblHoldtext setFrame:CGRectMake(0, 0, 0, 0)];
                    [progressView.layer setFrame:viewbottomForCamera.frame];


                    if (alphacolor <= 0.6) {
                        [viewbottomForCamera setBackgroundColor:COLOR_WITH_RGBA(37, 37, 38, alphacolor)];
                    }
                    [lblHoldtext setFrame:CGRectMake(0, 0, 0, 0)];

                } completion:^(BOOL finished) {

                }];
            }

        }

        if(recognizer.state == UIGestureRecognizerStateEnded)
        {
            if (vel.y < 0) {

                [UIView animateWithDuration:0.2 animations:^{

                    _recorder.previewView.frame=CGRectMake(0, 0, SCREENWIDTH, SCREENHEIGHT);
                    [viewbottomForCamera setFrame:CGRectMake(0, _recorder.previewView.frame.size.height-65, SCREENWIDTH, 65)];
                    CGFloat alphacolor = _recorder.previewView.frame.size.height/1000;
                    if (alphacolor <= 0.6) {
                        [viewbottomForCamera setBackgroundColor:COLOR_WITH_RGBA(37, 37, 38, alphacolor)];

                    }
                    [progressView.layer setFrame:viewbottomForCamera.frame];



                } completion:^(BOOL finished) {
                    _recorder.previewLayer.frame = _recorder.previewView.bounds;

                    [lblHoldtext setFrame:CGRectMake(20, viewbottomForCamera.frame.origin.y-30, SCREENWIDTH-40, 20)];

                }];


            }
            else
            {

                [UIView animateWithDuration:0.1 animations:^{
                    [_recorder.previewView setFrame:CGRectMake(0, SCREENHEIGHT-258,SCREENWIDTH,258)];
                    [viewbottomForCamera setFrame:CGRectMake(0, _recorder.previewView.frame.size.height-65, SCREENWIDTH, 65)];
                    [viewbottomForCamera setBackgroundColor:COLOR_WITH_RGBA(0, 0, 0, 0)];
                    [progressView.layer setFrame:viewbottomForCamera.frame];




                }completion:^(BOOL finished) {
                    _recorder.previewLayer.frame = _recorder.previewView.bounds;

                    [lblHoldtext setFrame:CGRectMake(20, 10, SCREENWIDTH-40, 20)];

                }];
            }
        }
    }
    -(IBAction)btnViewCameraTapped:(id)sender
    {

    }
    //take image
    - (IBAction)btnViewSendTapped:(id)sender {

    //    AVCaptureConnection *videoConnection = nil;
    //    
    //    for (AVCaptureConnection *connection in stillImageOutput.connections) {
    //        
    //        for (AVCaptureInputPort *ports in [connection inputPorts]) {
    //            
    //            if ([[ports mediaType] isEqual:AVMediaTypeVideo]) {
    //                videoConnection = connection;
    //                break;
    //            }
    //        }
    //        if (videoConnection) {
    //            break;
    //        }
    //    }
    //    
    //    [stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
    //       
    //        if (imageDataSampleBuffer !=nil) {
    //            
    //            NSData *imagedata = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
    //            UIImage *image =[UIImage imageWithData:imagedata];
    //        }
    //    }];
    }
    //open/Close view
    - (IBAction)btnViewFullScreenTapped:(id)sender {

        [lblHoldtext setFrame:CGRectMake(0, 0, 0, 0)];
    //    [lblHoldtext setText:@"To cancel, drag your finger off send button"];
    //    [lblHoldtext setText:@"Let go to delete and start over"];

        if (_recorder.previewView.frame.size.height >= SCREENHEIGHT/2+100) {

            [UIView animateWithDuration:0.5 animations:^{

                [viewCamera setFrame:CGRectMake(0, SCREENHEIGHT-256,SCREENWIDTH,258)];
                [lblHoldtext setFrame:CGRectMake(20, 10, SCREENWIDTH-40, 20)];
                [viewbottomForCamera setFrame:CGRectMake(0, _recorder.previewView.frame.size.height-65, SCREENWIDTH, 65)];
                [viewbottomForCamera setBackgroundColor:COLOR_WITH_RGBA(0, 0,0,0)];
                [progressView.layer setFrame:viewbottomForCamera.frame];


            }completion:^(BOOL finished) {
                _recorder.previewLayer.frame = viewCamera.bounds;

            }];
        }
        else
        {
            [UIView animateWithDuration:0.5 animations:^{
                viewCamera.frame=CGRectMake(0, 0, SCREENWIDTH, SCREENHEIGHT);
                _recorder.previewLayer.frame = viewCamera.bounds;
                [viewbottomForCamera setFrame:CGRectMake(0, _recorder.previewView.frame.size.height-65, SCREENWIDTH, 65)];
                CGFloat alphacolor = _recorder.previewView.frame.size.height/1000;
                [progressView.layer setFrame:viewbottomForCamera.frame];

                if (alphacolor <= 0.7) {
                    [viewbottomForCamera setBackgroundColor:COLOR_WITH_RGBA(37, 37, 38, alphacolor)];

                }


            } completion:^(BOOL finished) {

                [lblHoldtext setFrame:CGRectMake(20, viewbottomForCamera.frame.origin.y-30, SCREENWIDTH-40, 20)];

            }];

        }
    }
Euphemia answered 24/9, 2015 at 9:23 Comment(2)
Hey Mega its actually answer I think but he should give either description or comments in code.....Celadon
@MegaTron hey it's answer and for more description please go through comments(//) in my code, it's perfectly work for me and it's work same as fb messenger :)Euphemia

© 2022 - 2024 — McMap. All rights reserved.