Thursday 29 September 2016

Custom view controller transition and animation

iOS7 introduced a way by which we can customise the transition from one view controller to other. For example say if we  navigate from one view controller to another  , we push a view controller on another and to return back to initial view controller we pop the view controller.
With iOS7 now we can change the animation according to out requirement. We can reverse the direction of navigation controller. Even we can change the direction of the presenting view controller .
For creating custom transitioning we have to perform following steps:

1) Create a class that implements the UIViewControllerAnimatedTransitioning protocol . In this class we code to customise the animation . In this class we implements the two delegate method of the above protocol , which is as:

-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
    return 1.5;

}

-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{}

2) In view controller class (a view controller from which we navigate or transition to another  view controller), implements the following:

       If we are presenting a view controller modally, then view controller have to implement UIViewControllerTransitioningDelegate . UIviewController has a property named transitionDelegate set it to self in order to return the custom animation for transitioning .
In delegate method (animationControllerForPresentedController) return the instance of the class which implements the  UIViewControllerAnimatedTransitioning .

      If we are navigating from one view controller to another , the view controller have to implement UINavigationControllerDelegate . The set the view controller as delegate of the navigation controller . And implement the required methods .
For customising the push and pop operation , we can create the two classes one for push animation and another for pop operation which implements the UIViewControllerAnimatedTransitioning . 
And then  from the delegate method of the navigation controller we can check the type of operation (push or pop)and return the  designated custom animator instance .

- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{
}

With this way we can create the custom animation as we want. The core part of this process is to code the custom animation . And return the instance of the  custom animation objects.

Thursday 22 September 2016

Show download progress of the content

In iOS when we download any content , there may be a need to show the progress of the download. It's easy in iOS. We can download the data with NSURLConnection. 

First of all create a UIProgressBar in your view and initially make it hidden. Lets say we have a progress bar outlet named  progressBar .


1) Create NSURLConnection object

NSURL *url = [NSURL URLWithString:@"Your_url"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url         cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:80];

   NSMutableData *dataReceived = [[NSMutableData alloc] initWithLength:0];
    NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self     startImmediately:YES];


2) Now implement the delegate methods of the NSURLConnection

 In this method we receive the response of the download, from which we get the expected content length.Also we make the progress bar unhidden here.

- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
     self.progressBar.hidden = NO;
    [dataReceived setLength:0];
    long long  expectedDataBytes = [response expectedContentLength];
}


In didReceiveData:(NSData*)data method we get the downloaded data chunks, here we append the data to dataReceived object . And also set the progress bar by download progress .

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [dataReceived appendData:data];
    float downloadProgress = (float)[dataReceived length] / (float) expectedDataBytes;
     [self.progressBar setProgress: downloadProgress];
    
}

When downloading is complete the connectionDidFinishLoading:(NSURLConnection*)connection method is called. Here we can save the downloaded content to the document directory.

- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
   
}
    
Here I make the expectedDataBytes and dataReceived object local .You have to declare them to interface section of the file to use them in all methods.

Reference:

Thursday 15 September 2016

Custom AVPlayer

In iOS application development some time we may have situation where we want to show our own controls on AVPlayer. Suppose user want to show the playback slider on the bottom of the screen and two buttons on the left and right side of the screen  to control the speed of the video .



To implement this  we can create a view with required buttons and slider and assign action to designated view controller. The steps are as follows:

1) Create a view controller and then design the xib as per the need and create necessary outlets and action of the objects .

2) Then in implementation file create an instance of AVPlayerItem .

NSURL *url  =[NSURL URLWithString:@"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"];
    //create player item

AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url];

3)  Initialize AVPLayer with the AVPlayerItem instance

   AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];

4)  Create an AVPLayerLayer instance

   AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];

5) Now insert the playerLayer to the view's layer hierarchy

    [self.view.layer insertSublayer:playerLayer atIndex:0];

That's all our design is done. 

Now our job is to run the slider, speed the video when user tap on button and  play and pause the video .To implement these all feature we can register observer .

6) To check the status of the playing item we can register for key path observing like this :

[playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];

Then implement the method

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
}

This method is core method of KVO(Key-value-observing) and is called every time when any changes occur in the property of the registered object .In this method we can check for different key path and take action accordingly like this :

if ([keyPath isEqualToString:@"status"]) {
 }

7)To track the buffering of the video register for key path playbackLikelyToKeepUp

[playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];

8) We can register an observer to listen for when the video is ended :

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(playerDidEndVideo) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];

Thursday 8 September 2016

Slide down a UIView on a button action


In iOS app, we may have a requirement like, when a user tap on a button , a UIView slide down with animation . To implement this we can create a button and UIView on the top of button and make it hidden . Then in action method of the button change the frame of the UIView with animation  according to our requirement . To make it hide again with animation like slide top, reverse the operation .

Here is an example in which we will make a UIView slide down when a user tap on the button.

1) Create a UIButton

2) Then create a UIView on the top of UIButton  and make it hidden . Lets say we named it myView

3) Then in action method of UIButton , check if button is hidden or not and act accordingly:

if([myView isHidden]){

 First unhide the button

myView.hidden = NO;
 
Get the frame of the btn

CGRect frame  = myView.frame

Now change the y origin of the  frame

frame.origin.y += 30;

Now set animation to change the frame of the myView

[UIView animateWithDuration:0.7 delay:0.0
options:UIViewAnimationOptionCurveLinear animations:^{

      myView.frame  = frame

} completion:nil];


That's all . Now if we want to slide top the myView again ,when user tap on the button then change the frame of the myView to its original size .