Friday, 26 August 2016

Custom Navigation Transition



One of the cool feature introduce by Apple in iOS7 is custom view controller transitions which make it possible for developer to create own animated transition from one view controller to next view controller.
By default UINavigationController provide right to left animation transition switching one view controller to next view controller and left to right animation transition for back to parent view controller.

But from iOS7, we can add  better interface experience within the app and can give own animation transition for switching one view controller to another view controller.

Here we will create a simple project and  use custom  transition for switching between view controller using UINavigationController Delegate.

Create a new project and embed storyboard in UINavigationController.

Create a new class, subclass of UIVIewController(named ImageCollectionViewController)
ImageCollectionViewController display collection of images in UICollectionView, so switch to ImageCollectionViewController.xib file and add UICollectioView.

Go to main storyboard add a button and set IBAction method
import ImageCollectionViewController to ViewController class and define Button IBAction method.
inside IBAction method  write the code for push to ImageCollectionViewController.

Go to ImageCollectionViewController.h file and add following delegates.
1. UICollectionViewDelegate
2. UICollectionViewDataSource

also add a IBOutlet property for UICollectionView and a property of NSArray for containing all images.



Switch to ImageCollectionViewController.xib file and connect UICollectionView outlet.

Now, go to ImageCollectionViewController.m file

inside viewDidLoad() method set navigationController delegate.
and add images to collectionArrray.

viewDidLoad() will be look like this

Implement UICollectionViewDataSource methods.



Now run the app, we can see the all images.

next step is add another UIViewController subclass(named DetailViewController)
within this class we will display selected image in full screen
Switch to DetailViewController.h file add property for UIImageView and for a UImage.


 go to DetailViewController.xib a add UIImageView and set outlet.

Switch to ImageCollectionViewController.m class, import newly created controller.

Now add UICollectionView Delegate method didSelectItemAtIndexPath:  

Run the app and click on any images we can switch to next view controller(DetailsViewController) with default navigation.

Now go to ImageCollectionViewController.h file and add another delegate UINavigationControllerDelegate 

Add new class , subclass of NSObject(named CustomTransition)
We will add our whole transition code in this class.
UIViewControllerAnimatedTransitioning protocol implement the animations for a custom view controller transition.

Switch to CustomTransition.m file and add delegate methods of UIViewControllerAnimatedTransitioning.

1. set the duration for the transition animation.
-(NSTimeInterval) transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
    return 0.4;
}


 add another another delegate method animateTransition:()
Its perform the transition animations for switching between view controllers.
-(void) animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
   
   
}



Transition context object is created by the system and contain both controller details.

Now its time to add our own code for custom transition
it will be better to write present and dismiss transition inside two different methods.
so add a method for present animation


Above code will perform custom transition for presenting next view controller
Let's go over this step by step
1. get controller to present after transition.
2. get current controller
3. get the view in which the animated transition should take place.
4. Set frame for next controller view
5.add next controller view to animation container view.
6. Scale next controller view to 0.1, so its reduce the size of view 10 times, so it will look too small when transition will start.
7. Animation block for transform next view to original scale.
  after completion the transition remove parent controller view and call method complete transition.

call the presentWithContextTransitioning: from animateTransition:  methos.


Now time to execute our own custom transition, go to ImageCollectionViewController.m file and import our CustomTransition class and add UINavigationControllerDelegate method
-(id<UIViewControllerAnimatedTransitioning>) navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{
     return [[CustomTransition alloc] init];
}
and in viewDidLoad() set navigation controller delegate
Now run the app and check own cool stuff for switching between two controller.

In the same way we can writer custom transition for dismiss a controller
Here code snap


declare another method in CustomTransition.h and a BOOL variable
@interface CustomTransition : NSObject<UIViewControllerAnimatedTransitioning>
{
    BOOL isReverse;
}
-(instancetype) initWithReverse:(BOOL)value;
@end

define the method inside CustomTransition.m file
-(instancetype) initWithReverse:(BOOL)value;{
    self = [super init];
    if (self) {
        isReverse = value;
    }
    return self;
}

Update animateTransition: method with the following code:

-(void) animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
    if (isReverse == YES) {
        [self dismissWithContextTransitioning:transitionContext];
    }
    else{
        [self presentWithContextTransitioning:transitionContext];
    }
}

Now switch to ImageCollectionViewController and update UINavigationController delegate method



Now run the App and check.

Click here for complete project.


Saturday, 20 August 2016

QRCode Scanner

One of the great feature of AVFoundation framework is the ability of discover  and read bar Codes in real time.
Here i am mainly going to interact (discover and read ) with QR code.

QR(Quick Response) code is a type of matrix barcode or two dimensional barcode uses four standardized encoding mode (numeric, alphanumeric, byte/binary and kanji) to store data (like URLs, Text, Numbers). For more details Click here

For more details about AVFoundation Framework Click here.

Create a new Project
import AVFoundation Framework.

Now go to main storyboard and add a view(Subclass of UIView), a label and a button.

A view will be  display what camera is recording in the form of image.
Label is used for display resultant string data after scanning  QRcode (or the data store in QR code).
And button is for start and stop scanning.

 Now go to ViewController.h file and declare properties.

@property (nonatomic, weak) IBOutlet UIView *previewView;
@property (weak, nonatomic) IBOutlet UILabel *statusLabel;
@property (weak, nonatomic) IBOutlet UIButton *scanButton;


also declare two more properties
@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;


Back to main storyboard and connect outlets.

Switch to ViewController.m file and add following code inside viewDidLoad method

   //set button corner radious and border color
    self.scanButton.layer.borderColor = [UIColor lightGrayColor].CGColor;
    self.scanButton.layer.borderWidth = 0.7;
    self.scanButton.layer.cornerRadius = 3;
    self.scanButton.clipsToBounds = YES;


    //setting lable color and border
    self.statusLabel.layer.borderColor = [UIColor lightGrayColor].CGColor;
    self.statusLabel.layer.borderWidth = 0.7;
    self.statusLabel.layer.cornerRadius = 2;
    self.statusLabel.clipsToBounds = YES;


In the above code we are just adding border color and corner radius on label and button.

Add new method with the name startReading()

-(Void) startReading{
   
    NSError *error;
    

//1. Define capture device
    //For Front Camera
//    AVCaptureDevice *captureDevice = [AVCaptureDevice deviceWithUniqueID:@"com.apple.avfoundation.avcapturedevice.built-in_video:1"];
   
    //For Default Camera
    AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    

//2.Define Capture Device
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
    if (!input) {
        NSLog(@"Error = %@", error.localizedDescription);
        NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
        [[[UIAlertView alloc] initWithTitle:@"Camera Unavailable" message:[NSString stringWithFormat:@"The %@ has not been given a permission to your camera. Please check the Privacy Settings: Settings -> %@ -> Privacy -> Camera", appName, appName] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil] show];
        return NO;
    }
    //3.Initialize session
    self.captureSession = [[AVCaptureSession alloc] init];
    [self.captureSession addInput:input]; //add input device to session   
 

 //4.Set metadata output
    AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
    [self.captureSession addOutput:captureMetadataOutput];// Add output data to session
   
    //5. set delegate
    dispatch_queue_t dispatchQueue;
    dispatchQueue = dispatch_queue_create("myQueue", NULL);
    [captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue]; //set delegate 
 

 //6.set the type of metadata objects to process
     [captureMetadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
    

//7.Add video preview layer
    self.videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
    [self.videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    self.videoPreviewLayer.frame = self.previewView.bounds;
    [self.previewView.layer addSublayer:self.videoPreviewLayer];
 

//8.Start session  
 [self.captureSession startRunning];
}


1.Capture Device: 

An AVCaptureDevice represents a physical device that provides realtime input media data, such as video and audio. A input device can be the camera or microphone.

2.Capture Device Input:

AVCaptureDeviceInput is a concrete subclass of AVCaptureInput that provides an interface for capturing media from an AVCaptureDevice.

3. Capture Session:
AVCaptureSession is the central hub of the AVFoundation capture classes.To perform a real-time capture, a client may instantiate AVCaptureSession and add appropriate.

4. Capture Metadata Output
AVCaptureMetadataOutput is a concrete subclass of AVCaptureOutput that can be used to process metadata objects from an attached connection. Instances of AVCaptureMetadataOutput emit arrays of AVMetadataObject instances such as detected faces, barcodes.

5.SetDelegate
Sets the receiver's delegate that will accept metadata objects and dispatch queue on which the delegate will be called. A serial dispatch queue must be used to guarantee that metadata objects will be delivered in order.

6. Set metadataObjectTypes:
Specifies the types of metadata objects that the receiver.

7.Preview:
AVCaptureVideoPreviewLayer quickly render the raw data collected by the camera on the screen, means we can also say, AVCaptureVideoPreviewLayer  is display a preview of what the camera is capturing.
AVCaptureVideoPreviewLayer is a subclass of CALayer that we add as a sublayer of preview view's layer.

8.Start the session
 startRunning to start the flow of data from inputs device to outputs data.

Now add delegate method for receive output data.
-(void) captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
   
    if (metadataObjects != nil && [metadataObjects count]>0) {
        id metadataObj= [metadataObjects objectAtIndex:0];
        if ([metadataObj isKindOfClass:[AVMetadataMachineReadableCodeObject class]]) {
            

            AVMetadataMachineReadableCodeObject *barCodeObject;
            barCodeObject = (AVMetadataMachineReadableCodeObject *)[self.videoPreviewLayer transformedMetadataObjectForMetadataObject:(AVMetadataMachineReadableCodeObject *)metadataObj];
          
           
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"metadata readable object count = %d   \n Meta Data = %@",(int)metadataObjects.count,metadataObjects);
                self.statusLabel.hidden = NO;
                [self.statusLabel performSelectorOnMainThread:@selector(setText:) withObject:[metadataObj stringValue] waitUntilDone:NO];
                [self stopReading];
                [self.scanButton setTitle:@"Scan" forState:UIControlStateNormal];
                self.scanButton.enabled = YES;
            });
        }
      
    }
}


add another method for stop reading

-(void) stopReading{
    [self.captureSession stopRunning];
    self.captureSession = nil;
}


Now we have enough code for reading a QRcode, we just need to digger our code.

Add one more method for start and stop reading with user interaction.

Declare a  IBAction method in ViewController.h file
-(IBAction)buttonAction:(id)sender
Go to ViewController.h file and define IBAction method

-(IBAction)buttonAction:(id)sender{
   
    if ([self.captureSession isRunning] == YES) {
        self.statusLabel.hidden = YES;
        self.statusLabel.text = @"";
        [self stopReading];
        [self.scanButton setTitle:@"Scan" forState:UIControlStateNormal];
    }
    else{
        if ([self startReading]) {
            self.statusLabel.hidden = NO;
            self.statusLabel.text = @"Scanning...";
            [self startReading];
            [self.scanButton setTitle:@"Stop" forState:UIControlStateNormal];
        }
       
    }
} 


Now go to main storyboard file and connect IBAction method to button click  event.

Now run the App and scan a QR code, you can see the encoded data in QR code on label.

Click here for complete project.

Saturday, 6 August 2016

Create Custom Camera



iOS provide UIIMagePickerController for getting an image from photo library and for capturing a new image. But iOS also provide a cool feature for creating custom camera. We can create custom camera using AVFoundation framework, which give direct access to the camera and microphone.
This process is managed through AVCaptureSession which coordinate the flow of data from input devices (such as camera, microphone) to outputs (Such as image and movie file).

Minimally we need:

1) An instance of AVCaptureDevice to present the input device, such as a camera and microphone.
2) An instance of a concrete subclass of AVCaptureInput to configure the ports from the input device.
3) An instance of a concrete subclass of AVCaptureOutput to manage the output to a movie file or  still image.
4) An instance of AVCaptureSession to coordinate the data flow from input to output.
5) An instance of AVCaptureVideoPreviewLayer to display a preview of what the camera is recording.



Start session:

    self.session = [[AVCaptureSession alloc] init]; //initialize an instance of AVCaptureSession
    [self.session setSessionPreset:AVCaptureSessionPresetHigh];
//Indicates the session preset currently in use by the receiver.

Capture Device: 

An AVCaptureDevice represents a physical device that provides realtime input media data, such as video and audio. A input device can be the camera or microphone.
       
AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

 Capture Device Input:

AVCaptureDeviceInput is a concrete subclass of AVCaptureInput that provides an interface for capturing media from an AVCaptureDevice.

       self.captureDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error];

Now add capture device input to session
      if ( [self.session canAddInput:self.captureDeviceInput] )
            [self.session addInput:self.captureDeviceInput];


Preview:

AVCaptureVideoPreviewLayer quickly render the raw data collected by the camera on the screen, means we can also say, AVCaptureVideoPreviewLayer  is display a preview of what the camera is capturing.
AVCaptureVideoPreviewLayer is a subclass of CALayer that we add as a sublayer of preview view's layer.

AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
    [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
   
    CALayer *rootLayer = [[self view] layer];
    [rootLayer setMasksToBounds:YES];
    [previewLayer setFrame:CGRectMake(0, 0, rootLayer.bounds.size.height, rootLayer.bounds.size.height)];
    [self.PreviewView.layer insertSublayer:previewLayer atIndex:0];


Now, Its enough for display camera recording on screen.

Start the session

[self.session startRunning];

Run the app and check.


Now add a UIButton to the view for capture rendered raw data as a image.

and, for manage the output to a still image create an instance of AVCaptureStillImageOutput and add to session.
AVCaptureStillImageOutput is a concrete subclass of AVCaptureOutput that can be used to capture high-quality still images with accompanying metadata.

AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
    if ([self.session canAddOutput:stillImageOutput])
    {
        [stillImageOutput setOutputSettings:@{AVVideoCodecKey : AVVideoCodecJPEG}];
        [self.session addOutput:stillImageOutput];
        [self setStillImageOutput:stillImageOutput];
    }


(Add above code before start the session)

Now add button method for capture image,

-(IBAction)captureButtonAction:(id)sender{
    //capture preview image
    [[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
       
        if (imageDataSampleBuffer)
        {
            //get image data from buffer
            NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
            UIImage *image = [[UIImage alloc] initWithData:imageData];
        

//save image to photo library (if you want to save captured image)
            [[[ALAssetsLibrary alloc] init] writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:nil];
        }
    }];
}


Now its time to capture fresh image.
Run the app and capture image.


Now Add another method for swap camera(front to back and back to front)
#pragma mark -
-(IBAction) changeCameraAction:(id)sender{
    //disable button
    self.captureButton.enabled = NO;
    self.swapButton.enabled = NO;
    //get current input device
    AVCaptureDevice *currentDevice = self.captureDeviceInput.device;
    AVCaptureDevicePosition preferredPosion = AVCaptureDevicePositionUnspecified;
    AVCaptureDevicePosition currentPosition = currentDevice.position
    ;
    //get new preferred position
    switch (currentPosition) {
        case AVCaptureDevicePositionUnspecified:
            break;
        case AVCaptureDevicePositionBack:
            preferredPosion = AVCaptureDevicePositionFront;
            break;
        case AVCaptureDevicePositionFront:
            preferredPosion = AVCaptureDevicePositionBack;
            break;
    }//end switch case
   
//configure new input device
    AVCaptureDevice *captureDevice = [self deviceWithMediaType:AVMediaTypeVideo withPreferredPosition:preferredPosion];
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:nil];
    //update session
    [self.session beginConfiguration];
    // Remove the existing device input first, since using the front and back camera simultaneously is not supported.
    [self.session removeInput:self.captureDeviceInput];
   
    if ( [self.session canAddInput:deviceInput] ) {
       
        [self.session addInput:deviceInput];
        self.captureDeviceInput = deviceInput;
    }
    else {
        [self.session addInput:self.captureDeviceInput];
    }
    [self.session commitConfiguration];
    //enable button
    self.captureButton.enabled = YES;
    self.swapButton.enabled = YES;
}
-(AVCaptureDevice *) deviceWithMediaType:(NSString *)mediaType withPreferredPosition:(AVCaptureDevicePosition) position{
    NSArray *devices = [AVCaptureDevice devicesWithMediaType:mediaType];
    AVCaptureDevice *captureDevice = devices.firstObject;
   
    for ( AVCaptureDevice *device in devices ) {
        if ( device.position == position ) {
            captureDevice = device;
            break;
        }
    }
    return captureDevice;
}


Click here for complete project.

Saturday, 30 July 2016

Drawing on iOS



Drawing with Quartz and UIKit:

Quartz is the native drawing technology in iOS. Core Graphics framework is at the heart of Quartz and is the primary interface use for drawing content. Quartz 2D is a two-dimensional drawing engine which is use of such as path based drawing,  painting with transparency, shading, drawing shadows, transparency layers, color management, anti aliased rendering, PDF documents generation, and PDF metadata access.

Configuring the Graphics Context:
View object create a graphics context and sets it as the current context. This context exists only for the the lifetime of the drawRect: call. For retrieve a pointer to this graphics context we can call UIGraphicsGetCurrentContext function. This function returns a reference to a CGContextRef type, which pass to core graphics function to modify the current graphics state. The graphics context contains a stack for save graphics states. When Quartz creates a graphics context, the stack is empty. Using CGContextSaveState function pushes a copy of the current graphics state onto the stack. Modification make to graphics state affect subsequent drawing operations but do not affect the copy stored on the slack.with done of modification we can return to the previous graphics state by popping the saved state off the top of the stack using the CGContextRestoreGState function. Pushing and popping graphics states in this manner is a fast way to return to a previous state.For Details Click here


Drawing:
//Draw a line
In order to draw graphics on the view it is necessary to subclass to create a subclass of UIView and override the drawRect: method.

Lets subclass a UIView(named LineView)

Now override drawRect: method

- (void)drawRect:(CGRect)rect {
    // Drawing code
    CGContextRef context = UIGraphicsGetCurrentContext(); //Get current graphics context
    CGContextSaveGState(context); //Save current context
    CGContextSetLineWidth(context, lineWidth); // set stroke width of line
    CGContextSetStrokeColorWithColor(context, [[UIColor redColor] CGColor]); //set stroke color
    CGContextMoveToPoint(context, 10,  10); // It is the first point of line
    CGContextAddLineToPoint(context, self.bounds.size.width - 10, 10); // set another point of line
    CGContextStrokePath(context); // stroke line
    CGContextRestoreGState(context);
}
Import newly added subclass to ViewController and add as a subview to the ViewController's view.


//Draw a Rectangle
subclass a UIView(named LineView)
and override drawRect: method

- (void)drawRect:(CGRect)rect {
    // Drawing code
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextSetLineWidth(context, lineWidth);
    CGContextSetStrokeColorWithColor(context, [[UIColor redColor] CGColor]);
    CGContextMoveToPoint(context, 10,  10); // start point
    CGContextAddLineToPoint(context, self.bounds.size.width - 10, 10);
    CGContextAddLineToPoint(context, self.bounds.size.width - 10, self.bounds.size.height - 10);
    CGContextAddLineToPoint(context,  10, self.bounds.size.height - 10);
    CGContextAddLineToPoint(context, 10, 10);
    CGContextStrokePath(context);
   CGContextRestoreGState(context);
}

Saturday, 16 July 2016

Custom Input View For System Keyboard



ios allows apps to display custom input views for the system keyboard. It also enables apps to have an accessory view above the system keyboard or custom input view. Additionally, it enables apps to play key-click sounds when users tap on a controls of an input view or input accessory view.
We can display UIPicker, Color Picker and any other custom view instead of system keyboard. I am going to display a UIPickerView for a keyboard.

Here a sample code for display custom input view for the system keyboard.

First create a sub class of UIView, (named "CustomFontSelectionView").

#import <UIKit/UIKit.h>
@interface CustomFontSelectionView : UIView

#import "CustomFontSelectionView.h"
@implementation CustomFontSelectionView


 Now add a UIPicker of Subview, 
 first declare a instance of UIPicker class in file CustomFontSelectionView.h  file
 and a Array  for containing all objects.

@interface CustomFontSelectionView : UIView<UIPickerViewDelegate, UIPickerViewDataSource>
{
    UIPickerView *pickerView;
    NSArray *fontListArray;
}


add below code in  CustomFontSelectionView.m

-(instancetype) initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        [self initialize];
    }
    return self;
}
-(void) initialize{
    fontListArray = @[[NSNumber numberWithInteger:10],[NSNumber numberWithInteger:11],[NSNumber numberWithInteger:12],[NSNumber numberWithInteger:13],[NSNumber numberWithInteger:14],[NSNumber numberWithInteger:15],[NSNumber numberWithInteger:16],[NSNumber numberWithInteger:17],[NSNumber numberWithInteger:18],[NSNumber numberWithInteger:19],[NSNumber numberWithInteger:20],[NSNumber numberWithInteger:21],[NSNumber numberWithInteger:22],[NSNumber numberWithInteger:23],[NSNumber numberWithInteger:24],[NSNumber numberWithInteger:25]];
    pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    pickerView.delegate = self;
    pickerView.dataSource = self;
    [self addSubview
:pickerView];
}

#pragma mark -
#pragma mark Picker View DataSource
-(NSInteger) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
    return fontListArray.count;
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
    return 1;
}
#pragma mark Picker View Delegate
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
    return [NSString stringWithFormat:@"%@",[fontListArray objectAtIndex:row]];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
    //send delegate to update text with selected font size
    if (self.fontDelegate && [self.fontDelegate respondsToSelector:@selector(didSelectFontSize:)]) {
        [self.fontDelegate didSelectFontSize:[fontListArray objectAtIndex:row]];
    }
} 




Now import Newly created Class to ViewController class
#import "CustomFontSelectionView.h"

and declare a instance variable for Class object
CustomFontSelectionView *customFontSelectionView; (a variable or instance always declare inside Interface Section)

Now go to ViewController and add a UITextField(either by code or by Xib, we can use any way).
and declare a instance of UITextField inside ViewController.h class.
In case of adding a UITextField using Xib connect IBoutlet with declared UITextField.


Add UITextField by code 
Declare a UItextField instance in ".h" file (named textField).
  
@property (nonatomic, strong)  UITextField *textField;

In ViewController.h
 Add following  code to ".m" file
Inside viewDidload method add code for display  Custom view.
self.textField = [[UITextFiled alloc]initWithFrame:CGRectMake(0, 0, self.view.bound.size.frame, 150)];
 [self.view addSubView: self.textField];

Now initialize Custom View

#pragma mark -
-(void) displayFontSelectionView{
    [self.textField resignFirstResponder];
    if (!customFontSelectionView) {
        customFontSelectionView = [[CustomFontSelectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, height)];
    }
    customFontSelectionView.fontDelegate = self;
    self.textField.inputView = customFontSelectionView;
    [self.textField becomeFirstResponder];
}


Add following piece of code just below  " [self.view addSubView: self.textField];"

self.textField.inputView = customColorSelectionView;

We can also add a Input Accessory view with a keyboard(Appear just above keyboard) in the same way
Add a UIToolbar either using Xib or code and add as a input accessory view.

self.textField..inputAccessoryView = self.toolBar; 


Click here for complete project.

Friday, 24 June 2016

UIMenuController

The singleton UIMenuController instance presents the menu interface. This menu is referred to as the editing menu. It is an easy way to add copy/paste menu options with in an app. You can also use it to expose custom features like saving, viewing, or deleting content.

Code for display UIMenuController:

First add a button and on click on that UIMenuController's will appear with menu options.

Here Button Action

#pragma mark -
-(IBAction) buttonAction:(UIButton *)sender{
    [self becomeFirstResponder];
    UIMenuItem *textMenu = [[UIMenuItem alloc] initWithTitle:@"Text" action:@selector(textButtonAction:)];
    UIMenuItem *copyMenu = [[UIMenuItem alloc] initWithTitle:@"Copy" action:@selector(copyButtonAction:)];
    UIMenuItem *editMenu = [[UIMenuItem alloc] initWithTitle:@"Edit" action:@selector(editButtonAction:)];
    UIMenuController *menuController = [UIMenuController sharedMenuController];
    [menuController setTargetRect:CGRectMake(sender.center.x, sender.frame.origin.y, 100, 60) inView:self.view];
    menuController.arrowDirection = UIMenuControllerArrowDown;
    menuController.menuItems = @[textMenu,copyMenu,editMenu];
    [menuController setMenuVisible:YES animated:YES];
}

#pragma mark -
-(void) textButtonAction:(id)sender{
    NSLog(@"Add text action code");
}
-(void) copyButtonAction:(id) sender{
    NSLog(@"Add copy action code");
}
-(void) editButtonAction:(id) sender{
    NSLog(@"Add edit action code");
}

Now we have to do one more thing
Override method canBecomeFirstResponder because default implementation return NO.

- (BOOL)canBecomeFirstResponder { return YES; }

Now we have enough code for display a UIMenuController with all added menu options.

Friday, 6 May 2016

Drawing On CALayer

Layers are often used to provide the backing store for views but can also be used without a view to display content. Layer is a partner of UIVIew. A UIView does not actually draw itself onto the screen; it draws itself into its layer, and it is the layer that is portrayed on the screen.

For drawing on CALayer first call UIGraphicsPushContext(CGContextRef context) inside drawInContext: method, than write drawing code and at the end use UIGraphicsPopContext();

UIGraphicsPushContext(CGContextRef context)  function save the previous graphics state and make the specified context the current context.
UIGraphicsPopContext() function to balance calls to the UIGraphicsPushContext function.  

First Create a subclass of CALayer.
 Add code inside newly created subclass.

-(void) drawInContext:(CGContextRef)ctx{
   
       UIGraphicsPushContext(ctx);
     
     // Drawing code
    UIBezierPath *rectanglePath = [UIBezierPath bezierPath];
    
    //set color for stroke
    [[UIColor blackColor] setStroke];
    
    //Set move point(origin/top left corner)
    [rectanglePath moveToPoint:CGPointMake(0, 0)];
    
    //set top right corner
    [rectanglePath addLineToPoint:CGPointMake(self.frame.size.width, 0)];
    
    //set bottom right corner
    [rectanglePath addLineToPoint:CGPointMake(self.frame.size.width, self.frame.size.height)];
   
    //set bottom left point
    [rectanglePath addLineToPoint:CGPointMake(0,    self.frame.size.height)];
    [rectanglePath closePath];
    rectanglePath.lineWidth = 2;
    [rectanglePath stroke];
    [super drawInContext:ctx];
    UIGraphicsPopContext();
}