Monday, 10 November 2014

Swift + NSDate ot String and Vice Versa



//--- Convert NSDate to Date String ---//

func dateformatterDate(date: NSDate) -> NSString
{
        var dateFormatter: NSDateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "MM-dd-yyyy"
        dateFormatter.timeZone = NSTimeZone(abbreviation: "UTC")
        
        return dateFormatter.stringFromDate(date)
        

}





//--- Convert Date String to NSDate ---//

func dateformatterDateString(dateString: NSString) -> NSDate?
{
        var dateFormatter: NSDateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "MM-dd-yyyy"
        dateFormatter.timeZone = NSTimeZone(abbreviation: "UTC")
        
        
        return dateFormatter.dateFromString(dateString)
 }

Swift + Convert Hex Color Code to UIColor By Using Extension

In viewDidLoad


self.view.backgroundColor = UIColor(hexColorCode: "#CC1800") // Solid color

self.view.backgroundColor = UIColor(hexColorCode: "#CC1800dd") // Color with alpha





//--- Add Extension on UIColor ---//

extension UIColor
{

    convenience init(hexColorCode: String)
    {
        var red:   CGFloat = 0.0
        var green: CGFloat = 0.0
        var blue:  CGFloat = 0.0
        var alpha: CGFloat = 1.0
        
        if hexColorCode.hasPrefix("#")
        {
            let index   = advance(hexColorCode.startIndex, 1)
            let hex     = hexColorCode.substringFromIndex(index)
            let scanner = NSScanner(string: hex)
            var hexValue: CUnsignedLongLong = 0
            
            if scanner.scanHexLongLong(&hexValue)
            {
                if countElements(hex) == 6
                {
                    red   = CGFloat((hexValue & 0xFF0000) >> 16) / 255.0
                    green = CGFloat((hexValue & 0x00FF00) >> 8)  / 255.0
                    blue  = CGFloat(hexValue & 0x0000FF) / 255.0
                }
                else if countElements(hex) == 8
                {
                    red   = CGFloat((hexValue & 0xFF000000) >> 24) / 255.0
                    green = CGFloat((hexValue & 0x00FF0000) >> 16) / 255.0
                    blue  = CGFloat((hexValue & 0x0000FF00) >> 8)  / 255.0
                    alpha = CGFloat(hexValue & 0x000000FF)         / 255.0
                }
                else
                {
                    print("invalid hex code string, length should be 7 or 9")
                }
            }
            else
            {
                println("scan hex error")
            }
        }
        else
        {
            print("invalid hex code string, missing '#' as prefix")
        }
        
        self.init(red:red, green:green, blue:blue, alpha:alpha)
    }

}




// Other Methods

extension UIColor

{
    /**
    Create non-autoreleased color with in the given hex string and alpha
    
    :param:   hexString
    :param:   alpha
    :returns: color with the given hex string and alpha
    
    
    Example:
    
    // With hash
    let color: UIColor = UIColor(hexString: "#ff8942")
    
    // Without hash, with alpha
    let secondColor: UIColor = UIColor(hexString: "ff8942", alpha: 0.5)
    
    // Short handling
    let shortColorWithHex: UIColor = UIColor(hexString: "fff")
    
    
    */
    convenience init(hexString: String, alpha: Float)
    {
        var hex = hexString
        
        // Check for hash and remove the hash
        if hex.hasPrefix("#")
        {
            hex = hex.substringFromIndex(advance(hex.startIndex, 1))
        }
        
        // Check for string length
        assert(countElements(hex) == 6 || countElements(hex) == 3)
        
        // Deal with 3 character Hex strings
        if countElements(hex) == 3
        {
            var redHex   = hex.substringToIndex(advance(hex.startIndex, 1))
            var greenHex = hex.substringWithRange(Range<String.Index>(start: advance(hex.startIndex, 1), end: advance(hex.startIndex, 2)))
            var blueHex  = hex.substringFromIndex(advance(hex.startIndex, 2))
            
            hex = redHex + redHex + greenHex + greenHex + blueHex + blueHex
        }
        
        let redHex = hex.substringToIndex(advance(hex.startIndex, 2))
        let greenHex = hex.substringWithRange(Range<String.Index>(start: advance(hex.startIndex, 2), end: advance(hex.startIndex, 4)))
        let blueHex = hex.substringWithRange(Range<String.Index>(start: advance(hex.startIndex, 4), end: advance(hex.startIndex, 6)))
        
        var redInt:   CUnsignedInt = 0
        var greenInt: CUnsignedInt = 0
        var blueInt:  CUnsignedInt = 0
        
        NSScanner(string: redHex).scanHexInt(&redInt)
        NSScanner(string: greenHex).scanHexInt(&greenInt)
        NSScanner(string: blueHex).scanHexInt(&blueInt)
        
        self.init(red: CGFloat(redInt) / 255.0, green: CGFloat(greenInt) / 255.0, blue: CGFloat(blueInt) / 255.0, alpha: CGFloat(alpha))
    }

    
    
    /**
    Create non-autoreleased color with in the given hex value and alpha
    
    :param:   hex
    :param:   alpha
    :returns: color with the given hex value and alpha
    
    Example:
    let secondColor: UIColor = UIColor(hex: 0xff8942, alpha: 0.5)
    
    */

    convenience init(hex: Int, alpha: Float)
    {
        var hexString = NSString(format: "%2X", hex)
        self.init(hexString: hexString, alpha: alpha)
    }

}

Swift + Add Pull to Refresh on Table View


var refreshControl:UIRefreshControl!      // An optional variable




func viewDidLoad()
{
        super.viewDidLoad()

        self.refreshControl = UIRefreshControl()
        self.refreshControl.attributedTitle = NSAttributedString(string: "Pull to refersh")
        self.refreshControl.addTarget(self, action: "refresh:", forControlEvents:                 
        UIControlEvents.ValueChanged)
        self.tableView.addSubview(refreshControl)
 }

   func refresh(sender:AnyObject)
  {
     // Code to refresh table view  
  }




At some point you could end refreshing.
self.refreshControl.endRefreshing()

Sunday, 9 November 2014

Swift + Add Custom Right Bar Button Item on Navigation Bar or Add Multiple bar button on Navigation Bar in Swift

In viewDidLoad

//---   Add Custom Right Bar Button Item   ---//

            self.addRightNavItemOnView()




    func addRightNavItemOnView()
    {
        
        let buttonEdit: UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
        buttonEdit.frame = CGRectMake(0, 0, 40, 40)
        buttonEdit.setImage(UIImage(named:"edit.png"), forState: UIControlState.Normal)
        buttonEdit.addTarget(self, action: "rightNavItemEditClick:", forControlEvents: UIControlEvents.TouchUpInside)
        var rightBarButtonItemEdit: UIBarButtonItem = UIBarButtonItem(customView: buttonEdit)
        
        
        
        let buttonDelete: UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
        buttonDelete.frame = CGRectMake(0, 0, 40, 40)
        buttonDelete.setImage(UIImage(named:"delete.png"), forState: UIControlState.Normal)
        buttonDelete.addTarget(self, action: "rightNavItemDeleteClick:", forControlEvents: UIControlEvents.TouchUpInside)
        
        
        var rightBarButtonItemDelete: UIBarButtonItem = UIBarButtonItem(customView: buttonDelete)
        
        
        
// add multiple right bar button items       self.navigationItem.setRightBarButtonItems([rightBarButtonItemDelete, rightBarButtonItemEdit], animated: true)
        
    // uncomment to add single right bar button item
   // self.navigationItem.setRightBarButtonItem(rightBarButtonItem, animated: false)
        
    }
    
    
    func rightNavItemEditClick(sender:UIButton!)
    {
        println("rightNavItemEditClick")
    }
    
    func rightNavItemDeleteClick(sender:UIButton!)
    {
        println("rightNavItemDeleteClick")
    }


Swift + Add Custom Left Bar Button Item on Navigation Bar

 In View Did Load

//---   Add Custom Left Bar Button Item   ---//

        self.addLeftNavItemOnView()



    func addLeftNavItemOnView ()
    {

       // hide default navigation bar button item
        self.navigationItem.leftBarButtonItem = nil;
        self.navigationItem.hidesBackButton = true;
        
        
        let buttonBack: UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
        buttonBack.frame = CGRectMake(0, 0, 40, 40)
        buttonBack.setImage(UIImage(named:"ImageName.png"), forState: UIControlState.Normal)
        buttonBack.addTarget(self, action: "leftNavButtonClick:", forControlEvents: UIControlEvents.TouchUpInside)
        
        var leftBarButtonItem: UIBarButtonItem = UIBarButtonItem(customView: buttonBack)
        
        self.navigationItem.setLeftBarButtonItem(leftBarButtonItem, animated: false)
        
        
    }
    
    func leftNavButtonClick(sender:UIButton!)
    {
        self.navigationController?.popViewControllerAnimated(true)
    }

Tuesday, 14 October 2014

Keep iOS 6 UITableView Group styles in iOS 7 Apps

There are lots of changes in UITableView in iOS 7. Earlier we have used group table view to have a rounded corner and other nice looking tables in iOS 6.
I was trying to keep my iOS 6 tables intact in my iOS 7 apps.



- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
   
    // This will remove extra separators from tableview
    self.tableViewSettings.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];

    [self.tableViewSettings setSeparatorInset:UIEdgeInsetsZero];
   

}



// Now See UITableView Delegate Methods ::


#pragma mark- UITableDataSource Delegate ::

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 5;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"CellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    
    if(cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault  reuseIdentifier:cellIdentifier];
        
        [cell setBackgroundColor:[UIColor clearColor]];
        
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }
    
    [cell.textLabel setFont:[UIFont boldSystemFontOfSize:20.0f]];
    
  
    
    [cell.textLabel setText:@"test"];
    
    
    return cell;
    
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    
}



- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 60;
    
}





- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    // This will create a "invisible" footer
    return 0.01f;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
    return [UIView new];
    
}


- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell respondsToSelector:@selector(tintColor)])
    {
        cell.backgroundColor = UIColor.clearColor;
        
        CAShapeLayer *layer = [self tableView:tableView layerForCell:cell forRowAtIndexPath:indexPath withColor:[UIColor whiteColor]];
        
        CGRect bounds = CGRectInset(cell.bounds, 5, 0);
        UIView *testView = [[UIView alloc] initWithFrame:bounds];
        [testView.layer insertSublayer:layer atIndex:0];
        testView.backgroundColor = UIColor.clearColor;
        cell.backgroundView = testView;
        cell.selectedBackgroundView = [self backgroundCellView:cell indexPath:indexPath tableView:tableView];
    }
}





- (UIView *)backgroundCellView:(UITableViewCell *)cell indexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableView
{
    CAShapeLayer *layer = [self tableView:tableView layerForCell:cell forRowAtIndexPath:indexPath withColor:[UIColor whiteColor]];
    CGRect bounds = CGRectInset(cell.bounds, 5, 0);
    UIView *testView = [[UIView alloc] initWithFrame:bounds];
    [testView.layer insertSublayer:layer atIndex:0];
    return testView;
}





- (CAShapeLayer *)tableView:(UITableView *)tableView layerForCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath withColor:(UIColor *)color
{
    CGFloat cornerRadius = 5.f;
    CAShapeLayer *layer = [[CAShapeLayer alloc] init];
    CGMutablePathRef pathRef = CGPathCreateMutable();
    CGRect bounds = CGRectInset(cell.bounds, 5, 0);
    BOOL addLine = NO;
    
    if (indexPath.row == 0 && indexPath.row == [tableView numberOfRowsInSection:indexPath.section]-1)
    {
        CGPathAddRoundedRect(pathRef, nil, bounds, cornerRadius, cornerRadius);
    }
    else if (indexPath.row == 0)
    {
        CGPathMoveToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds));
        CGPathAddArcToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds), CGRectGetMidX(bounds), CGRectGetMinY(bounds), cornerRadius);
        CGPathAddArcToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMinY(bounds), CGRectGetMaxX(bounds), CGRectGetMidY(bounds), cornerRadius);
        CGPathAddLineToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds));
        addLine = YES;
    }
    else if (indexPath.row == [tableView numberOfRowsInSection:indexPath.section]-1)
    {
        CGPathMoveToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds));
        CGPathAddArcToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds), CGRectGetMidX(bounds), CGRectGetMaxY(bounds), cornerRadius);
        CGPathAddArcToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds), CGRectGetMaxX(bounds), CGRectGetMidY(bounds), cornerRadius);
        CGPathAddLineToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMinY(bounds));
    }
    else
    {
        CGPathAddRect(pathRef, nil, bounds);
        addLine = YES;
    }
    
    
    
    layer.path = pathRef;
    
    CFRelease(pathRef);
    
    layer.fillColor = color.CGColor;
    
    if (addLine == YES)
    {
        CALayer *lineLayer = [[CALayer alloc] init];
        CGFloat lineHeight = (1.f / [UIScreen mainScreen].scale);
        lineLayer.frame = CGRectMake(CGRectGetMinX(bounds), bounds.size.height-lineHeight, bounds.size.width, lineHeight);

        lineLayer.backgroundColor = tableView.separatorColor.CGColor;

        [layer addSublayer:lineLayer];
    }
    
    
    return layer;

}






Thursday, 25 September 2014

Call two or more async services using Dispatch Group

// https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

// for details see chapter of Apple's iOS Developer Library's Concurrency Programming Guide


//create dispatch group
dispatch_group_t  group = dispatch_group_create();

dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
    // block1
    NSLog(@"Block1");
    [NSThread sleepForTimeInterval:5.0];
    NSLog(@"Block1 End");
});


dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
    // block2
    NSLog(@"Block2");
    [NSThread sleepForTimeInterval:8.0];
    NSLog(@"Block2 End");
});

dispatch_group_notify(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
    // block3
    NSLog(@"Block3");
});


dispatch_release(group);

and could produce output like this:
2012-08-11 16:10:18.049 Dispatch[11858:1e03] Block1
2012-08-11 16:10:18.052 Dispatch[11858:1d03] Block2
2012-08-11 16:10:23.051 Dispatch[11858:1e03] Block1 End
2012-08-11 16:10:26.053 Dispatch[11858:1d03] Block2 End
2012-08-11 16:10:26.054 Dispatch[11858:1d03] Block3









If you do not have control over the dispatch_async calls for your blocks, as might be the case for async completion blocks, you can use the GCD groups using dispatch_group_enter and dispatch_group_leave directly.


// create a group
dispatch_group_t group = dispatch_group_create();

// pair a dispatch_group_enter for each dispatch_group_leave
dispatch_group_enter(group);       // pair 1 enter
[self computeInBackground:1 completion:^{
    NSLog(@"1 done");
    dispatch_group_leave(group);      // pair 1 leave
}];

// again... (and again...)
dispatch_group_enter(group);          // pair 2 enter
[self computeInBackground:2 completion:^{
    NSLog(@"2 done");
    dispatch_group_leave(group);         // pair 2 leave
}];

// dispatch your final block after all the dispatch_group_enters
dispatch_async(dispatch_get_main_queue(), ^{
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    NSLog(@"finally!");
});



In this example, computeInBackground:completion: is implemented as:
- (void)computeInBackground:(int)no completion:(void (^)(void))block {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSLog(@"%d starting", no);
        sleep(no*2);
        block();
    });
}



Output (with timestamps from a run):
12:57:02.574  2 running
12:57:02.574  1 running
12:57:04.590  1 done
12:57:06.590  2 done
12:57:06.591  finally!