Sunday, 2 July 2017

Create PCH file in Xcode 6


In the C and C++ programming languages, a header file is a file whose text may be automatically included in another source file by the C preprocessor, usually specified by the use of compiler directives in the source file.

Prefix.pch is a precompiled header file. Precompiled headers were invented to make compiling faster. Rather than parsing the same header files over and over, these files get parsed once, ahead of time.
Xcode 5 and older version of Xcode by default add PCH file with project, but Xcode 6 doesn't include PCH file automatocally.
We can add PCH file in Project.
Here steps to add PCH file in Project:

1) Create new file by selecting File > New File > iOS > Other > PCH File > Next.
2) Give name to newly created file.(Ex- PrefixHeader)
3) Select Project > Targets > Build Setting.
4) Search for 'Prefix header'.
5) Under "Apple LLVM 7.0" you will get the Prefix Header Key.

 6) Type file directory. (Ex- ProjectFolder/ProjeectName-Prefix.pch).
7) Clean project.
8) Build project.

Monday, 26 June 2017

Circular Progress Bar Indicator

iOS don't provide pre-build 'Circular Progress View/Bar' like UIProgressBar.
Implementing a 'Circular Progress View' is simple in iOS. Here piece of code for implement 'Circular Progress View'.

1) Create a Sub-Class of UIView Class

@interface CircularProgressView : UIView
{
    CGFloat startAngle;
    CGFloat endAngle;
}
@property (nonatomic, assign) CGFloat percentage;
-(id) initWithFrame:(CGRect)frame;
@end

#import "CircularProgressView.h"

@implementation CircularProgressView

-(id) initWithFrame:(CGRect)frame{

  self = [super initWithFrame:frame];
    if (self) {
       
        startAngle = M_PI * 1.5;
        endAngle = startAngle + (M_PI*2);
    }
    return self;
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    [[UIColor colorWithRed:(CGFloat)235/255 green:(CGFloat)237/255 blue:(CGFloat)236/255 alpha:1] setStroke];
    UIBezierPath *benzierPathBack = [UIBezierPath bezierPath];
    [benzierPathBack addArcWithCenter:CGPointMake(rect.size.width / 2, rect.size.height / 2) radius:(rect.size.width / 2 - 5) startAngle:startAngle endAngle:(endAngle - startAngle) * (100 / 100.0) + startAngle clockwise:YES];
   
    benzierPathBack.lineWidth = 10;
    [benzierPathBack stroke];
   
    CGContextSaveGState(context);
   
    UIBezierPath* bezierPath = [UIBezierPath bezierPath];
   
    // Create our arc, with the correct angles
    [bezierPath addArcWithCenter:CGPointMake(rect.size.width / 2, rect.size.height / 2) radius:(rect.size.width / 2-5) startAngle:startAngle endAngle:(endAngle - startAngle) * (_percentage / 100.0) + startAngle clockwise:YES];
   
    // Set the display for the path, and stroke it
    bezierPath.lineWidth = 10;
    [[UIColor colorWithRed:(CGFloat)1/255 green:(CGFloat)111/255 blue:(CGFloat)37/255 alpha:1] setStroke];
    [bezierPath stroke];  
}


Import CircularProgressView Class, create an object and change percentage value, you can see a 'Circular Progress View'.

Sunday, 18 June 2017

Drawing on View

A UIBezierPath object combines the geometry of a path with attributes that describe the path during rendering. We can set the geometry and attributes separately and can change them independent of one another. Once we have the object configured the way you want it, you can tell it to draw itself in the current context. Because the creation, configuration, and rendering process are all distinct steps, Bezier path objects can be reused easily in  code. We can even use the same object to render the same shape multiple times, perhaps changing the rendering options between successive drawing calls. 
For more details about UIBezierPath Click Here.

Now, we are going to create a simple drawing app using UIBezierpath.

First, create a  subclass of UIView Class.
Suppose name is SketchView
 Inside SketchView.h
@interface SketchView : UIView
{
    UIBezierPath *scriblePath;
}


Add following code in SketchView.m

@implementation SketchView

-(instancetype) initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if(self){
        scriblePath = [[UIBezierPath alloc] init];
        scriblePath.lineCapStyle=kCGLineCapRound;
        scriblePath.miterLimit=0;
        scriblePath.lineWidth = 2; //Set Stroke with
    }
    return self;
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
    [[UIColor blackColor] setStroke];
    [scriblePath strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
}

#pragma mark -
-(void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
     CGPoint touchPoint = [[touches anyObject] locationInView:self.superview];
    [scriblePath moveToPoint:touchPoint];
}
-(void) touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
     CGPoint touchPoint = [[touches anyObject] locationInView:self.superview];
    [scriblePath addLineToPoint:touchPoint];
    [self setNeedsDisplay];
}

@end

Sunday, 11 June 2017

Custom View With Transparent Oval.

UIBezierPath define a path consisting of straight and curved line segment and render the path in custom views. We can use this for specify the geometry of path, path can define simple shapes such as rectangle, oval, arc or can define complex polygons.For more details about UIBezierPath Click Here.

I am going to draw a custom view with transparent oval.I will use UIBenzierPath  fro achieving result.

First create a SubClass of UIView.
Ex. named sub class to CustomView
Inside drawRect: method of CustomView.m

- (void)drawRect:(CGRect)rect {
    // Drawing code

//First Create path for Oval
    UIBezierPath *apath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(5, 5,  self.frame.size.width-10, self.frame.size.height-10)];
    //Create another path
    UIBezierPath *clipPath = [ UIBezierPath bezierPathWithRect:CGRectInfinite];

//Append both path
    [clipPath appendPath:apath];
    clipPath.usesEvenOddFillRule = YES; //

usesEvenOddFillRule property is used to determine whether the even-odd or non-zero rule is used to determine the area enclosed by the path.   

  CGContextSaveGState(UIGraphicsGetCurrentContext());
    [clipPath addClip];
    CGContextSaveGState(UIGraphicsGetCurrentContext());
    [[UIColor orangeColor] setFill];
    [[UIColor blackColor] setStroke];
    clipPath.lineWidth = 2;
    [clipPath stroke];
    [clipPath fill];
}


Sunday, 4 June 2017

Core Animation

Core Animation is a graphics rendering and animation infrastructure use to animate the views and other visual elements. Core Animation is not a replacement for app’s views. Instead, it is a technology that integrates with views to provide better performance and support for animating their content. All you have to do is configure a few animation parameters (such as the start and end points) and tell Core Animation to start. Core Animation does the rest, handing most of the actual drawing work off to the onboard graphics hardware to accelerate the rendering. This automatic graphics acceleration results in high frame rates and smooth animations without burdening the CPU and slowing down your app.

Below code add "Pulse Effect" animation.

//Create a CALayer
CALayer *animatelayer = [CALayer layer];
//Setting Frame for CALayer
animatelayer.frame = CGRectMake(0,0, 160, 160);
//Setting Color for CALayer
animatelayer.backgroundColor = [UIColor redColor].CGColor;
//Setting Position for CALayer
animatelayer.position = (CGPoint){CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds)};
//Setting Corner radius for CALayer to look like a Circle
animatelayer.cornerRadius = 80;

//Create a Basic Animation
CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
theAnimation.duration=2.0;
theAnimation.repeatCount=HUGE_VALF;
theAnimation.autoreverses=YES;theAnimation.fromValue=[NSNumber numberWithFloat:0.7];
theAnimation.toValue=[NSNumber numberWithFloat:0.0];

//Add animation to CALayer
[animatelayer addAnimation:theAnimation forKey:@"animateOpacity"];

//Add CALayer to View
[self.view.layer insertSublayer:animatelayer atIndex:0];

For details Click here

Sunday, 28 May 2017

Frame Animation with CGAffineTransform

One of the most powerful and useful property of UIView is transform, which takes a CGAffineTransform. This is a matrix that express how each pixel of UIView should be modified, applying some mathematical formulas.

CGAffineTransformScale: CGAffineTransformScale use for scale a view up and down. A transform value of 5.0 means make the view 5 times bigger than actual frame.

CGAffineTransformRotate: Use for rotate a view by given angle. It uses radian.


Here a piece of code for render a view  with animation from center.

UIImageView *aniView;

//method for display subview.
-(void) displaySubView{
    //Create object for sub view
    if (!aniView) {
        aniView = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.center.x, self.view.center.y, 0, 0)];
        aniView.backgroundColor = [UIColor clearColor];
        aniView.image = [UIImage imageNamed:@"imagename.png"];
        aniView.clipsToBounds = YES;
        aniView.center = self.view.center;

      // Reduce view to 1/10th of its original frame
        aniView.transform = CGAffineTransformScale(aniView.transform, .01, .01);
        [self.view addSubview:aniView];
    }
    [UIView animateWithDuration:1 animations:^{

        // return the view to original frame
        aniView.transform = CGAffineTransformScale(aniView.transform, 100, 100);
      
    }];
}

//Method for hide subview
-(void) hideSubView{
    [UIView animateWithDuration:1 animations:^{
        aniView.transform = CGAffineTransformScale(aniView.transform, .01, .01);
    }];
}

Sunday, 7 May 2017

UITableView in Swift

Adding a Table View in swift is same as Objective-C.
Create a new Single View Application and give any name you want,  make sure you select 'Swift' language.


 Go to  storyboard and add UITableView, make a IBOutlet for Table view
Now, switch to ViewController .swift class and add UITableViewDelegate and UITableDataSource

Class RolePopOverViewController: UIViewController, UITableViewDelegate,UITableViewDataSource{
  
// IBOutel for UITableView
     @IBOutlet weak var roleTableView: UITableView!  

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
  

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}


Note: You can see a error "Type ViewController does not conform to Protocol  ''UITableViewDataSource' ". Its just because we didn't add two required Table View Data Source Method yet.

create a NSArray instance  globally
var allRoleDataArray : NSArray!

Now register UITableViewCell class
roleTableView .registerClass(UITableViewCell.self, forCellReuseIdentifier: "CellIdentifier")
//initialize globally declare array
 allRoleDataArray = ["One","Two","Three","Four","Five"]

Add above lines in viewDidLoad()

Now time to add UITableView Data Source method

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return allRoleDataArray.cout  
 }


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
       
        let cell = tableView.dequeueReusableCellWithIdentifier("CellIdentifier", forIndexPath: indexPath) as UITableViewCell
        var value : NSString = allRoleDataArray[indexPath.row] as NSString
        cell.textLabel?.text = value
        return cell;
    }


you can't see error any more.
Build and run the app.
Now  open ViewController.swift and add ''didSelectRow'' method

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        var value : NSString = allRoleDataArray[indexPath.row] as NSString
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
        NSLog("Selected Row = %@", value)
    }


Again run the App and select any row you can see some message on console.
Ex: if you select second row you can see "Selected Row = Two"

Sunday, 30 April 2017

Display Scrollable Image

In some cases image is bigger than screen size.
For display full image within the screen need to bind that image within the UIScrollView.
Process of binding a image with UIScrollview is easy and can achieve in 5 steps.

Here the step by step process to bind a image with UIScrollView.
1)  Create an instant of UIScrollView.
2)  Get image instant to display
3)  Retrieve width and height of image.
4)  Add UIImageView above to UIScrollView.
5)  Set UIScrollview content size equals to image size.

//Add a UIScrollView
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
scrollView.backgroundColor = [UIColor whiteColor];
[self.view addSubView:scrollView];

//Get Image
UIImage *displayImage = [UIImage imageNamed:@""];

//Get Image Size
CGSize imageSize = displayImage.size;

//Add Image View
UIImageView *displayImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, imageSize.width, imageSize.height)];
displayImageView.backgroundColor = [UIColor clearColor];
displayImageView.image = displayImage;
[scrollView addSubView: displayImageView];
[scrollView setContentSize: imageSize];

Sunday, 9 April 2017

Draw a Dashed Pattern Stroke

A small small changes left better impact on UI. In this post we will work on to enhance UI implementation with dashed pattern border on UIView.

Draw dashed pattern border on UIView is very simple and we can use UIBezierPath for draw dashed pattern border.
Lets start, first create subclass of UIView(named DashedBorderView).

#import <UIKit/UIKit.h>

@interface DashedPatternView : UIView

@end


#import "DashedPatternView.h"

@implementation DashedPatternView


/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/


@end

Go to DashedPatternView.m and uncomment drawRect: method
Now add following code for draw  a rectangle

- (void)drawRect:(CGRect)rect {
    // Drawing code
    [[UIColor blackColor] setStroke];
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(10, 10)];
    [path addLineToPoint:CGPointMake(rect.size.width, 10)];
    [path addLineToPoint:CGPointMake(rect.size.width, rect.size.height - 10)];
    [path addLineToPoint:CGPointMake(10, rect.size.height - 10)];
    [path closePath];
    path.lineWidth = 2.0;
    [path stroke];
}

 
Go to your controller class and add DashedPatternView as a subview on main view.
Here code

-(void) addBorderView{
DashedPatternView *dashedView = [[DashedPatternView alloc] init];
    dashedView.frame = CGRectMake(100, 300, self.view.frame.size.width-200, 60);
    dashedView.backgroundColor = [UIColor clearColor];
[self.view addSubview:dashedView];

}

Call addBorderView() method from viewDidLoad() method.
Run the app and you can see a rectangle with solid black border
Now we are going to add dashed pattern border instead of solid border
Add following code just before to call stroke method

CGFloat dashes[] = { 6,6,6};
    [path setLineDash:dashes count:3 phase:0];


above two lines of code enough for draw dashed pattern border.
first we have initialize an array for the dashed border style pattern(you can change the pattern and can see result)
second line of code  set pattern for draw with 3 count(Count of pattern array).

Now run the app and you can see a rectangle with dashed pattern border.


Thursday, 30 March 2017

Get User Current Location

Location service improve the app by enhancing user experience. Lots of application's features base on location service like finding near places, restaurant and whatever user want to search. Uber, Ola, Nearby and tons of applications are based on location service and display required content on the basis of that. Suppose we are stand on a place and want to search restaurant near current location, in this case we must know user current location and than can display result according to user search.
Now question is how can we get user current location? It is not a difficult task, every language provide in build framework and library for perform this task.
 Apple provide Core Location Framework for obtaining all necessary information regarding user's current location. Core Location Framework provide geographic location of device. Click here to know about Geographic coordinate system.

Lets start the coding stuff to fetch current location of a user.
Add Core Location Framework in the build phase of target under"Link Binary with Library"  section, switch to controller class and import location framework and implement <CLLocationManagerDelegate> and declare an instance of CLLocationManager.

#import <CoreLocation/CoreLocation.h>
@interface HomeMapViewController : UIViewController<CLLocationManagerDelegate>{
            CLLocationManager *locationManager;
}
@end

Now switch to .m class and add method for fetch current location

@implementation HomeMapViewController
      - (void)viewDidLoad {
              [super viewDidLoad];
              // Do any additional setup after loading the view from its nib.
               [self  getCurrentLocation];
       }
     -(void) getCurrentLocation{
         locationManager = [[CLLocationManager alloc] init];
         locationManager.delegate = self;
         locationManager.desiredAccuracy = kCLLocationAccuracyBest;
         if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
             [locationManager requestWhenInUseAuthorization];
         }
         [locationManager startUpdatingLocation];
     }
// define delegate methods of <CLLocationManagerDelegate>
      - (void)locationManager:(CLLocationManager *)manager
         didFailWithError:(NSError *)error{
          NSLog(@"Error to fetch location = %@", error);
     }
     -(void) locationManager:(CLLocationManager *)manager didUpdateLocations:               (NSArray<CLLocation *> *)locations{
         CLLocation *location = [locations lastObject];
         CLLocationCoordinate2D cord = location.coordinate;
         NSLog(@"Current Location\n Latitude - %f \n Longitude - %f", cord.latitude, cord.longitude);
     }@end

Now run the app and allow the application to fetch your current location.
You can see latitude and longitude value of location on  console area. We are successfully getting  current location of device/user.
We can stop location update service any time by using 'stopUpdatingLocation' method. It will be better to stop location service after getting current location. add following  line of code inside of 'didUpdateLocations' method

[locationManager stopUpdatingLocation];

But the problem is, value of location in form of latitude and longitude and it is not in human readable address. Lets convert the coordinate value in human readable address.

CLGeocoder class provide service for convert coordinate to human readable address. By specify the latitude and longitude of a given location, you can use CLGeocoder to find a user-readable address.

Lets create a new method for getting human readable address of coordinate.

-(void) getReadableAddressFrom:(CLLocation *)location{
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
        NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
        if (error == nil && [placemarks count] > 0) {
            CLPlacemark *placemark = [placemarks lastObject];
            NSString *address = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@",placemark.subThoroughfare, placemark.thoroughfare,placemark.postalCode, placemark.locality,placemark.administrativeArea,placemark.country];
            NSLog(@"Address = %@", address);
        } else {
            NSLog(@"%@", error.debugDescription);
        }
    } ];
}


Inside 'didUpdateLocations' method add line of code to call above method.
[self getReadableAddressFrom:location];

Run the code and check the console, you can see address details.

Note :   For running the application on simulator set the default address of simulator.
In the menu bar, select “Debug” -> “Location” for setting the simulator location.


Sunday, 5 March 2017

Display a controller on the top of all controller

We have in-build methods to present and navigate a new controller from currently visible controller.
We can use "presentViewController: animated: completion:" method to present a new controller and "pushViewController: animated:" method to push a new controller in navigation controller stack.
But for presenting and navigating a new controller  we must know current visible controller, our presenting and navigation code must be inside the current visible controller file. Suppose our project require to display a controller on notification call, when user receive a notification a controller will present. In this scenario we don't know when the app will receive notification, and at the time of receiving  notification, which controller is on top. So what is the best solution of this problem? first option is write  code inside all classes and call this method on the basis of local notification, when a controller appear its add a observer for present a controller and when its disappear remove that observer. But, is this good option/solution? No, its not a solution of problem. If we accept this approach, than we need to add extra work to controller local notification for present and push controller.  Instead of accepting first approach we will find the current visible controller and present new controller from any where of the application and no need to write same code again and again in side all classes.

In this blog post i am going to find current visible controller and present a new controller.
Lets start,

Go to your project and add new category for UIWindow.
Inside .h file add following methods

- (UIViewController *)visibleViewController;
+ (UIViewController *) getVisibleViewControllerFrom:(UIViewController *) vc;


Now switch to .m file and define methods

- (UIViewController *)visibleViewController {
    UIViewController *rootViewController = self.rootViewController;
    return [UIWindow getVisibleViewControllerFrom:rootViewController];
}

+ (UIViewController *) getVisibleViewControllerFrom:(UIViewController *) vc {
    if ([vc isKindOfClass:[UINavigationController class]]) {
        return [UIWindow getVisibleViewControllerFrom:[((UINavigationController *) vc) visibleViewController]];
    } else if ([vc isKindOfClass:[UITabBarController class]]) {
        return [UIWindow getVisibleViewControllerFrom:[((UITabBarController *) vc) selectedViewController]];
    } else {
        if (vc.presentedViewController) {
            return [UIWindow getVisibleViewControllerFrom:vc.presentedViewController];
        } else {
            return vc;
        }
    }

}
 //--------
In the first method, we are not doing any thing, just we are calling the second method with root controller of window.
In the second method,    we are checking the kind of controller(is a kind of UINavigationController, UITabBarController, presentedViewContrller) and returning top of the controller.

Go to ViewController.m file and import UIWindow category class
 and add below method

-(void) displayFullScreenMessage{
//create a instance of controller
    MessageViewController *controller = [[MessageViewController alloc] initWithNibName:@"MessageViewController" bundle:nil];
    //get main window
    UIWindow *mainWindow =  [[UIApplication sharedApplication] keyWindow];

//get current visible controller
    UIViewController *visiblecontroller = [mainWindow visibleViewController];

//present a controller
    [visiblecontroller presentViewController:controller animated:YES completion:nil];
}


Now we have enough code for display a controller on the top of the controller.
Call the above method and display controller.

Friday, 3 February 2017

Draw a curve on UIView

As we all know, User interface is a key part for all application. User interface of an application is only way to interact with end user. A better user interface provide better experiences to end user.
In this block, we are going to create a curve at the upper part of a view.
Resultant screen will be look line below image


                                                                 


For drawing a curve on the upper part of a view, we need to do some math works for setting the radius and center on view. 
We need 3 things for drawing a curve:
1. Center.
2. Radius
3. Start angle.
4. End angle.
At the initial point we are not having any point and angle.
Suppose, we want to draw a curve on the upper part of view with area w * 100, w is the width of view.
now we have 3 points on the curve
1. view x origin and 100.
2. view center and 0.
3. view width and 100.
so all points are:
initial point - (0, 100)
mid point - (w/2, 0)
end point -  (w, 100).

Now we are having three points, so we can draw a triangle using these points
Lets say our triangle is ∆ABC and ø be the angle opposite to side A.
We can calculate distance between all points of triangle AB, BC and CA

Suppose A is the distance between A and B(AB), similarly B is the distance between BC and C is the distance between CA. 
suppose r be the radius of circle/arc.
then A/sinø = 2r,
This isn't hard (just drop a perpendicular from O to A, and use the definition of sin on the similar triangles).

Area of triangle  ∆ABC
K = (BCsinø)/2
sinø = 2K/BC

Now
2r = A/(2K/BC)
r = ABC/4K

Draw a perpendicular for A to BC, we will get height of triangle which is 100(curve draw area as we defined initially)
so K = (base * height) / 2;
K = B * h / 2;

so radius  r = AC / 2h.
we have calculated radius. lets calculate center
x point of center will be in the mid of the curve area and y point will be radius.
so center c = (w/2, r)

now we are ready for draw a curve on the upper part of a view.

Sub-classing of view is the best option for customization and redrawing.
Create a new class(subclass of UIView) namely CurveView(you can choose any name for a class)

in a CurveView.h file declare the following methods and variables
//----variables
    CGFloat radius;
    CGPoint centerPoint;
    CGFloat curveTopMargin;

//----methods
-(instancetype) initWithFrame:(CGRect)frame withUpperCurveMargin:(CGFloat)topMargin;

also declare a macro for convert angle from degree to radians
#define   DEGREES_TO_RADIANS(degrees)  ((M_PI * degrees)/ 180)

Switch to CurveView.m file and following code
//method for initialize an instance of CurveView
-(instancetype) initWithFrame:(CGRect)frame withUpperCurveMargin:(CGFloat)topMargin{
    self = [super initWithFrame: frame];
    if(self){
        curveTopMargin = topMargin;
        [self calculateRadius];
    }
    return self;
}

Now add code for calculate center point and radius
#pragma mark - Calculate radius and center
-(void) calculateRadius{
    CGFloat a = [self calculateDistance:CGPointMake(0, curveTopMargin) andPoint:CGPointMake(self.frame.size.width/2, 0)];
    CGFloat c = [self calculateDistance:CGPointMake(self.frame.size.width, curveTopMargin) andPoint:CGPointMake(self.frame.size.width/2, 0)];
    radius = (a * c)/(2*curveTopMargin);
    centerPoint = CGPointMake(self.frame.size.width/2, radius);
}
-(CGFloat) calculateDistance:(CGPoint)p1 andPoint:(CGPoint)p2{
    CGFloat x =sqrt((pow((p2.x - p1.x), 2)+(pow(p2.y - p1.y, 2))));
    return x;
}


And now add drawRect() method for drawing a view with curve
- (void)drawRect:(CGRect)rect {
    // Drawing code
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    //-------draw
    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
    CGContextSetFillColorWithColor(context, [UIColor cyanColor].CGColor);
    UIBezierPath *curvePath = [UIBezierPath bezierPath];
    [curvePath addArcWithCenter:centerPoint radius:radius-1  startAngle:DEGREES_TO_RADIANS(0) endAngle:DEGREES_TO_RADIANS(360) clockwise:YES];
    CGPathRef cgPath = CGPathCreateCopy(curvePath.CGPath);
    CGContextAddPath(context, cgPath);
    CGContextSetLineWidth(context, 1);
    CGContextSetShadowWithColor(context, CGSizeMake(0, -1.0), 0.3, [UIColor lightGrayColor].CGColor);
    CGContextDrawPath(context, kCGPathEOFillStroke);
    CGPathRelease(cgPath);
    CGContextRestoreGState(context);
}


Go to controller class and add curve view as a subview
-(void) addCurveView{
    CGSize screenSize = [UIScreen mainScreen].bounds.size;
    CurveView *topCurveView = [[CurveView alloc] initWithFrame:CGRectMake(0, screenSize.height, screenSize.width, 250) withUpperCurveMargin:60];
    topCurveView.backgroundColor = [UIColor clearColor];
    [self.view addSubview:topCurveView];
    CGRect f = topCurveView.frame;
    f.origin.y = screenSize.height - f.size.height;
    [UIView animateWithDuration:0.3 animations:^{
        topCurveView.frame = f;
    }];
}


Run the app, w can see a curve at the upper part.

Click here for Complete project.

Thursday, 19 January 2017

Getting Current Location

The Core Location Framework provide the Objective-C interface for obtaining information about current location and heading(direction in which device is pointing) of user. By using this framework we can configure and schedule delivery of location and heading event and can define geographic regions.

Get current location:
CLLocationManager class have ability to deliver current location and heading event. We can use this class for start and stop delivery of  location and heading event. Its provide all event information through delegates methods(CLLocationManagerDelegate).

Here code snippet for getting current location

-(void) getCurrentLocation{
    //Create an instance of CLLocationManager
    CLLocationManager * locationManager = [[CLLocationManager alloc] init];

    // Set delegate
    locationManager.delegate = self;

   // set accuracy
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;

    //request for authorization
    if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
        [locationManager requestWhenInUseAuthorization];
    }

    //start updating locations
    [locationManager startUpdatingLocation];
}


Now define the delegate method for getting location inforamation

-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    CLLocation *currentLocation = [locations lastObject];
    NSLog(@"Location latitude - %f",currentLocation.coordinate.latitude);
    NSLog(@"Location longitude - %f", currentLocation.coordinate.latitude);
}

// get error message to fetch location
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"didFailWithError: %@", error);
}

Its enough for getting current location of user.
Run the app.
First its prompt a message for getting accessibility to use current location(This message will appear  first time only). Click on allow button and  we can see location info in console area.

Note: For running the application on simulator, we need to do some extra setting, because by default simulator location is set to 'None' and this is the reason we are getting error message instead of current location information.
Now select 'Location' under Debug menu option of simulator, and choose 'custom location'. We can see some value for latitude and longitude, it is the position of Apple or Apple store,  we can change latitude and longitude value. Now click on 'Ok' and run the app again.
we can see  latitude and longitude value on console area.

Now we are getting current location of user in the form of latitude and longitude, but is it enough to find address/location by a user?  If i provide my latitude and longitude details to some one , is it possible to find my location for that?
We are getting current location information but its not understand for user. So we are going to convert location info in human readable format.

No need to worry about conversion because Core Location framework has ability to perform this task by CLGeocoder.
CLGeocoder:
The CLGeocoder class provides services for converting coordinate(latitude and longitude) to the user-friendly representation. A user-friendly representation of the coordinate typically consists of the street, city, state, and country information corresponding to the given location, but it may also contain a relevant point of interest, landmarks, or other identifying information. 

 Now back to code and update locationManager: didUpdateLocations: method with below code

 -(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    //stop updating locations
    [manager stopUpdatingLocation];
    //get current location
    CLLocation *currentLocation = [locations lastObject];
    NSLog(@"Location latitude - %f",currentLocation.coordinate.latitude);
    NSLog(@"Location longitude - %f", currentLocation.coordinate.latitude);
 
    //convert coodinate to user-friendly representation
    CLGeocoder *geoCoder = [[CLGeocoder alloc] init];
    [geoCoder reverseGeocodeLocation:locations.lastObject completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        CLPlacemark *placeMark = [placemarks lastObject];
        NSLog(@"name = %@", placeMark.name);
        NSLog(@"address dict = %@",placeMark.addressDictionary);
    }];
}


Run the application again.
Now we can see address details in console area.



Sunday, 15 January 2017

Contact Picker Controller

One of the useful framework provided by Apple is "ContactsUI Framework". ContactUI Framework display user's contact list in a graphical interface.  The ContactUI Framework is useful for display, edit, select and create contact within the app. Before enter in code lets discuss about some important classes of this framework.

CNContactPickerViewController:
CNContactPickerViewController present the entire list of contact to user. This class allows to user to select one or multiple contacts. Its supports both single selection and multi-selection. The app does not need access to the user’s contacts and the user will not be prompted for access. It will only have access to the final selection of the user.

CNContactViewController:
The CNContactViewController is used to display a contact. It can display a new contact, unknown contact, or existing contact.

Now we are ready for display entire list of contacts  within the application.

Here code snippet for  display CNContactPickerViewController
//Create an instance of  CNContactPickerViewController
CNContactPickerViewController *contactController = [[CNContactPickerViewController alloc] init];
//Set the CNContactPickerDelegate
    contactController.delegate = self;
//Present picker controller
    [self presentViewController:contactController animated:YES completion:nil];

Implement the delegate method  for getting details of selected contant.
(In this example we are going to handle onle single selection of contact)

 - (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact{
            NSLog(@"Given Name = %@",contact.givenName);
           //Get numbers
           NSArray *phoneNumbers= contact.phoneNumbers;
    for(CNLabeledValue *phoneNumber in phoneNumbers){
        if ([phoneNumber isKindOfClass:[CNLabeledValue class]]) {
            NSLog(@"CNLabeledValue - %@", ((CNLabeledValue *)phoneNumber).value);
            id valueType = ((CNLabeledValue *)phoneNumber).value;
            if ([valueType isKindOfClass:[CNPhoneNumber class]]) {
                    NSLog(@"phone number - %@",[valueType valueForKey:@"digits"]);
                    NSLog(@"Country -> %@", [valueType valueForKey:@"countryCode"]);
            }
         }
    }
    [picker dismissViewControllerAnimated:YES completion:nil];
}


// contactPickerDidCancel invoked, when user cancel picker selection
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker{
    [picker dismissViewControllerAnimated:YES completion:nil];
}


For more detail Click here

Thursday, 5 January 2017

Basic Operators in Swift



Basic Operators

 An operator is a special symbol or phrase that use to check, change, or combine values. For example, the addition operator (+) adds two number. 
let a = 2 + 3
Swift supports most standard C operators and improves several capabilities to eliminate common coding errors.

Unlike C, Swift lets you perform remainder (%) calculations on floating-point numbers. Swift also provides two range operators (a..<b and a...b) not found in C, as a shortcut for expressing a range of values. 


Terminology


Operators are unary, binary, or ternary:
  • Unary operators operate on a single target (such as -a, ++i, --i).
  • Binary operators operate on two targets (such as 2 + 3) and are infix because they appear in between their two targets.
  • Ternary operators operate on three targets. Like C, Swift has only one ternary operator, the ternary conditional operator (a ? b : c).
The values that operators affect are operands. In the expression 1 + 2, the + symbol is a binary operator and its two operands are the values 1 and 2. 

Assignment Operator(=)

Assignment operator initializes or updates the value.
let x = 100   // Declare a  constant variable x with value 100.
var y = 5   //// Declare a  variable y with initial value 5.
y = x        // y is equal to x(100)

Arithmetic Operators

Swift supports the four standard arithmetic operators for all number types:

1. Addition (+)   
   1 + 5   //equals 6
2. Subtraction (-) 
   14 - 4   //equals 10
3. Multiplication (*) 
   4*7    //equals 28 
4. Division (/) 
   30/5    //equals 6
Unlike the arithmetic operators in C and Objective-C, the Swift arithmetic operators do not allow values to overflow by default.


Remainder Operator


The remainder operator (a % b) works out how many multiples of b will fit inside a and returns the value that is left over (known as the remainder).
  9 % 4 // equals 1 
To determine the answer for a % b, the % operator calculates the following equation and returns remainder as its output:
a = (b x some multiplier) + remainder
where some multiplier is the largest number of multiples of b that will fit inside a.


Increment and Decrement Operators

Like C, Swift provides an increment operator (++) and a decrement operator (--) as a shortcut to increase or decrease the value of a numeric variable by 1.

var x = 0;
++x      //Now x equal to 1.
 
Each time you call ++i, the value of i is increased by 1. Essentially, ++i is shorthand for saying i = i + 1. Likewise, --i can be used as shorthand for i = i - 1.
The ++ and -- symbols can be used as prefix operators or as postfix operators. ++i and i++ are both valid ways to increase the value of i by 1. Similarly, --i and i-- are both valid ways to decrease the value of i by 1. 

1. If the operator is written before the variable, it increments the variable before returning its value.  
2. If the operator is written after the variable, it increments the variable after returning its value.

Unary Minus Operator

The sign of a numeric value can be toggled using a prefixed -, known as the unary minus operator: 
let a =10
let minus_a = -a   //minus_a equal to -10
let plus_a = -minus_a  //plus_a equal to 10
The unary minus operator (-) is prepended directly before the value it operates on, without any white space.

Unary Plus Operator

The unary plus operator (+) simply returns the value it operates on, without any change:

 let minus_value = -10
 let sec_value = +minus_value    //sec_value is equal to -10

Compound Assignment Operators

Like C, Swift provides compound assignment operators that combine assignment (=) with another operation. One example is the addition assignment operator (+=): 

Ex : let a = 5;
       a +=4     //now  a equal to 9

The expression a += 2 is shorthand for a = a + 2. Effectively, the addition and the assignment are combined into one operator that performs both tasks at the same time. 
NOTE: The compound assignment operators do not return a value. You cannot write let b = a += 2.

Comparison Operators

Swift supports all standard C comparison operators: 
  1. Equal to (==) 
   2.  Not equal to (!=)
   3. Greater than  (>)
   4. Less than (<)
   5.Greater than or equal to(>=)
   6.Less than or equal to(<=)

NOTE: Swift also provides two identity operators (=== and !==), which you use to test whether two object references both refer to the same object instance.

Ternary Conditional Operator

The ternary conditional operator is a special operator with three parts, which takes the form question ? answer1 : answer2. It is a shortcut for evaluating one of two expressions based on whether question is true or false. If question is true, it evaluates answer1 and returns its value; otherwise, it evaluates answer2 and returns its value.

a==5?b:c
if a equal to 5 than its return b otherwise c. 


Nil Coalescing Operator

The nil coalescing operator (x ?? y) unwraps an optional x if it contains a value, or return a default value y if x is nil. The expression x is always an optional type. The expression y must match the type that is stored inside x.

NOTE: If the value of a is non-nil, the value of b is not evaluated. This is known as short-circuit evaluation. 
EX: let firstColor = "Black"
      let defaultColor = "White"
      let backgroundColor = firstColor ?? defaultColor
     //In this example value of background color is Black


      let firstColor : String?

      let defaultColor = "White"
      let backgroundColor = firstColor ?? defaultColor
     //In this example value of background color is White because firstColor is nil

Range Operators

Swift includes two range operators, which are shortcuts for expressing a range of values.

Closed Range Operator

The closed range operator (a...b) defines a range that runs from a to b, and includes the values a and b. The value of a must not be greater than b.
The closed range operator is useful when iterating over a range in which you want all of the values to be used, such as with a for-in loop:
 for index in 1...5{
          println ("\(index) times 5 is \(index * 5)")
}
OutPut:
// 1 times 5 is 5 
// 2 times 5 is 10 
// 3 times 5 is 15  
// 4 times 5 is 20
// 5 times 5 is 25   





Half-Open Range Operator

The half-open range operator (a..<b) defines a range that runs from a to b, but does not include b. It is said to be half-open because it contains its first value, but not its final value. As with the closed range operator, the value of a must not be greater than b. If the value of a is equal to b, then the resulting range will be empty.
Half-open ranges are particularly useful when you work with zero-based lists such as arrays, where it is useful to count up to (but not including) the length of the list: 

for index in 1..<5{
          println ("\(index) times 5 is \(index * 5)")
}
OutPut:
// 1 times 5 is 5 
// 2 times 5 is 10 
// 3 times 5 is 15  
// 4 times 5 is 20 

Logical Operators

Logical operators modify or combine the Boolean logic values true and false. Swift supports the three standard logical operators found in C-based languages:
 1. Logical Not Operator(!)
      Logical not invert boolean value so that true become false and false become true.

2.Logical And Operator (&&)
     The logical AND operator (a && b) creates logical expressions where both values must be true for the overall expression to also be true.
If either value is false, the overall expression will also be false. In fact, if the first value is false, the second value won’t even be evaluated, because it can’t possibly make the overall expression equate to true. This is known as short-circuit evaluation. 

3. Logical OR Operator (||)

The logical OR operator (a || b) is an infix operator made from two adjacent pipe characters. You use it to create logical expressions in which only one of the two values has to be true for the overall expression to be true.
Like the Logical AND operator above, the Logical OR operator uses short-circuit evaluation to consider its expressions. If the left side of a Logical OR expression is true, the right side is not evaluated, because it cannot change the outcome of the overall expression.