Wednesday, 17 August 2016

Custom Map Annotation Pin in Swift

Custom Map Annotation Pin in Swift



1) Set Your Storyboard Like This :




2) Write This Code in ViewController :


import UIKit

import MapKit

private let reuseIdentifier = "CustomPin"

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var mapView: MKMapView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
       
        let annotation = MKPointAnnotation()
        annotation.title = "My Home"
        annotation.coordinate = CLLocationCoordinate2D(latitude: 23.0300, longitude: 72.5800)

        self.mapView.addAnnotation(annotation)
        
        self.mapView.showAnnotations([annotation], animated: true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView! {
        
        let pin = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseIdentifier) ?? CustomPin(annotation: annotation, reuseIdentifier:reuseIdentifier)
        
        pin.canShowCallout = false
        
        return pin
    }

    
    func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
        if let mapPin = view as? CustomPin {
            updatePinPosition(mapPin)
        }
    }
    
    func mapView(mapView: MKMapView, didDeselectAnnotationView view: MKAnnotationView) {
        
        if let mapPin = view as? CustomPin {
            if mapPin.preventDeselection {
                mapView.selectAnnotation(view.annotation!, animated: false)
                
                let alert = UIAlertController(title: "Alert", message: "View Clicked Here", preferredStyle: UIAlertControllerStyle.Alert)
                alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
                self.presentViewController(alert, animated: true, completion: nil)
                
            }
        }
    }
    
    func updatePinPosition(pin:CustomPin) {
        let defaultShift:CGFloat = 50
        let pinPosition = CGPointMake(pin.frame.midX, pin.frame.maxY)
        
        let y = pinPosition.y - defaultShift
        
        let controlPoint = CGPointMake(pinPosition.x, y)
        let controlPointCoordinate = mapView.convertPoint(controlPoint, toCoordinateFromView: mapView)
        
        mapView.setCenterCoordinate(controlPointCoordinate, animated: true)
    }
    

}


3) Create UIView XIB & Write This Code in UIVIEW Class :




CustomCallout.swift :

import Foundation

import MapKit

class CustomCallout: UIView {
    
    
    @IBOutlet weak var titleLabel: UILabel!
    
    override func hitTest(var point: CGPoint, withEvent event: UIEvent?) -> UIView? {
        let viewPoint = superview?.convertPoint(point, toView: self) ?? point
        
        let isInsideView = pointInside(viewPoint, withEvent: event)
        
        let view = super.hitTest(viewPoint, withEvent: event)
        
        return view
    }
    
    override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
        return CGRectContainsPoint(bounds, point)
    }
}


4) Create MKPinAnnotationView & Write This Code in MKPinAnnotationView Class :


import Foundation

import MapKit

class CustomPin: MKPinAnnotationView {
    
    private var calloutView:CustomCallout?
    private var hitOutside:Bool = true
    
    var preventDeselection:Bool {
        return !hitOutside
    }
    
    override func setSelected(selected: Bool, animated: Bool) {
        let calloutViewAdded = calloutView?.superview != nil
        
        
        if (selected || !selected && hitOutside) {
            super.setSelected(selected, animated: animated)
        }
        
        self.superview?.bringSubviewToFront(self)
        
        if (calloutView == nil) {
            calloutView = NSBundle.mainBundle().loadNibNamed("Callout", owner: nil, options: nil)[0] as? CustomCallout
            
            calloutView?.titleLabel.text = (self.annotation?.title)!
        }
        
        if (self.selected && !calloutViewAdded) {
            addSubview(calloutView!)
            calloutView!.center = CGPointMake(10, -calloutView!.frame.size.height / 2.0)
        }
        
        if (!self.selected) {
            calloutView?.removeFromSuperview()
        }
    }
    
    override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
        var hitView = super.hitTest(point, withEvent: event)
        
        if let callout = calloutView {
            if (hitView == nil && self.selected) {
                hitView = callout.hitTest(point, withEvent: event)
            }
        }
        
        hitOutside = hitView == nil
        
        return hitView;
    }
}



******* Finally OUTPUT : -









Tableview with Sections

Tableview with Section ( Data Divided in Sections )



1) Set Your Storyboard Like This :





2) Write This Code in ViewController :

ViewController.h :

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property(strong,nonatomic)IBOutlet UITableView *tblBudget;

@property (strong,nonatomic) NSMutableArray *arrItem;

@end


ViewController.m :


#import "ViewController.h"

#import "TableViewCell.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize arrItem,tblBudget ;

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.arrItem = [[NSMutableArray alloc]initWithCapacity:0];
    
    [self fetchListOfBudget];
    
}


# pragma mark - Fetch Data from API -

-(void)fetchListOfBudget
{
    
    NSMutableData *postData = [[NSMutableData alloc] initWithData:[[NSString stringWithFormat:@"tag=%@",@"list_budget"] dataUsingEncoding:NSUTF8StringEncoding]];
    
    
    [postData appendData:[[NSString stringWithFormat:@"&event_id=100"] dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://.....Your_URL"]
                                                           cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                       timeoutInterval:10.0];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:postData];
    
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                                completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
                                      {
                                          dispatch_async(dispatch_get_main_queue(), ^{
                                              
                                             
                                          });
                                          if (error) {
                                              NSLog(@"%@", error);
                                          }
                                          else
                                          {
                                              NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                              NSLog(@"%@", httpResponse);
                                              
                                              NSError* error;
                                              NSDictionary* responseDict = [NSJSONSerialization JSONObjectWithData:data
                                                                                                           options:kNilOptions
                                                                                                             error:&error];
                                              NSLog(@"responseDict: %@", responseDict);
                                              
                                              if(!error)
                                              {
                                                  if([responseDict[@"error"] intValue] == 0)
                                                  {
                                                      
                                                      dispatch_async(dispatch_get_main_queue(), ^{
                                                          
                                                          id object = responseDict[@"data"];
                                                          if (![object isKindOfClass:[NSMutableArray class]]) {
                                                            
                                                              [tblBudget reloadData];
                                                              
                                                              return;
                                                          }
                                                          
                                                          NSMutableArray *arrAllItem = [[NSMutableArray alloc]initWithArray:responseDict[@"data"]];
                                                         
                                                          if (arrAllItem.count>0)
                                                          {
                                                              NSMutableArray *arrCategory = [arrAllItem valueForKeyPath:@"category_id"];
                                                              
                                                              NSMutableArray *unique = [NSMutableArray array];
                                                              
                                                              for (id obj in arrCategory) {
                                                                  if (![unique containsObject:obj]) {
                                                                      [unique addObject:obj];
                                                                  }
                                                              }
                                                              
                                                              arrCategory = [[NSMutableArray alloc] initWithArray:unique];
                                                              
                                                              
                                                              for (int i = 0 ; i< arrCategory.count; i++)
                                                              {

                                                                  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(category_id ==  %@)",arrCategory[i]];
                                                                  
                                                                  NSArray *filteredArray = [arrAllItem filteredArrayUsingPredicate:predicate];
                                                                  
                                                                  if (filteredArray.count > 0)
                                                                  {
                                                                      NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:0];
                                                                      
                                                                      [dict setObject:arrCategory[i] forKey:@"category_id"];
                                                                      [dict setObject:filteredArray[0][@"category"] forKey:@"category_name"];
                                                                      [dict setObject:filteredArray forKey:@"item_list"];
                                                                      
                                                                      [self.arrItem addObject:dict];
                                                                      
                                                                      NSLog(@"%@",dict);
                                                                  }
                                                              }
                                                              
                                                              [tblBudget reloadData];
                                                          }
                                                          
                                                      });
                                                  }
                                                  else
                                                  {
                                                      dispatch_async(dispatch_get_main_queue(), ^{
                                                          
                                                         // [CommonFunctions showAlertMessage:[responseDict valueForKey:@"error_msg"]];
                                                          
                                                      });
                                                  }
                                              }
                                              else
                                              {
                                                  dispatch_async(dispatch_get_main_queue(), ^{
                                                      
                                                      
                                                      NSLog(@"Error in pass json");
                                                  });
                                              }
                                              
                                          }
                                          
                                      }];
    [dataTask resume];
}


#pragma mark - Table view methods -
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return self.arrItem.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:self.arrItem[section][@"item_list"]];
    
    return arr.count;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return self.arrItem[section][@"category_name"];
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    return 40;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"Cell";
    
    TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
    
    if (cell == nil)
    {
        cell = (TableViewCell *)[[[NSBundle mainBundle] loadNibNamed:@"TableViewCell" owner:self options:nil] objectAtIndex:0];
    }
    
    NSMutableDictionary *dic = [[NSMutableDictionary alloc]initWithDictionary:self.arrItem[indexPath.section][@"item_list"][indexPath.row]];
    
    cell.selectionStyle=UITableViewCellSelectionStyleNone;
    cell.backgroundColor=[UIColor clearColor];
    
    cell.lblItemName.text = [NSString stringWithFormat:@"%@",dic[@"item"]];
    
    if ([dic[@"actual_amount"] floatValue] > 0)
    {
        cell.lblCost.text = [NSString stringWithFormat:@"Cost: $%@ (Actual)",dic[@"actual_amount"]];
    }
    else
    {
        cell.lblCost.text = [NSString stringWithFormat:@"Cost: $%@ (Estimated)",dic[@"estimated_amount"]];
    }
    
   
    cell.lblPaid.text = [NSString stringWithFormat:@"Paid: $%@",dic[@"paid"]];
  
    return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSMutableDictionary *dic = [[NSMutableDictionary alloc]initWithDictionary:self.arrItem[indexPath.section][@"item_list"][indexPath.row]];
    
    NSLog(@"%@",dic) ;
    
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 73;
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end



3) Write This Code in UITableViewCell :

UITableViewCell.h :



#import <UIKit/UIKit.h>

@interface TableViewCell : UITableViewCell

@property IBOutlet UILabel *lblItemName;
@property IBOutlet UILabel *lblCost;
@property IBOutlet UILabel *lblPaid;

@end






**** Your API return this type of Data , Here Example is given below



 data =     (
                {
            "actual_amount" = 90;
            category = Band;
            "category_id" = 1;
            "created_by" = 3;
            "created_date" = "2016-08-11 02:22:28";
            "del_flag" = 0;
            due = 40;
            "estimated_amount" = 190;
            "event_id" = 100;
            id = 552;
            item = Catering;
            notes = "Enter Notes";
            paid = 50;
            prc = 90;
            status = 1;
            "updated_by" = 3;
            "updated_date" = "2016-08-12 06:52:41";
        },
                {
            "actual_amount" = 0;
            category = "Event Venue";
            "category_id" = 5;
            "created_by" = 3;
            "created_date" = "2016-08-11 02:22:28";
            "del_flag" = 0;
            due = 0;
            "estimated_amount" = 60;
            "event_id" = 100;
            id = 556;
            item = Venue;
            notes = "";
            paid = 0;
            prc = 60;
            status = 1;
            "updated_by" = 0;
            "updated_date" = "0000-00-00 00:00:00";
        },







**** OUTPUT