Friday, 24 June 2016

Dynamic row height of UITableViewCell

There may be situation where we want a UITableViewCell to be of dynamic height .

For example: We have a custom UITableViewCell in which we have a title UILabel and detail UILabel . We want detail UILabel  to be of dynamic height .

So first of all create a custom UITableViewCell class. And two UILabel named title and detail .

1) Set the top, leading and trailing constraint for title label to content view of cell .

2) Now set bottom , leading and trailing constraint for  detail label to content view of cell .

3) Set the vertical spacing  between title label and detail UILabel .

4) Now to prioritize  the title 's constraint over detail label 's constraint  set the content hugging and content compression priority .

  On title label set the content hugging and content compression priority to 751.

Again on detail label set the content hugging and content compression priority to 750 .


It is not yet done. Here we created a basic cell with two UILabel . To make it work in your view controller  set the estimated height for row at indexpath and height for row at indexpath  . UITableview provide methods for both purpose . You can return estimatedRowHeight as per your requirement. It is just an arbitrary value . Return the UITableViewAutomaticDimension for height for row at index path .

That's it .

Friday, 17 June 2016

Add gradient layer to UIView

There may be a situation  when we want to add gradient  to UIView. As we know every UIView is backed by  a layer.  We can also add or insert as many layers to UIView with different functionality. As we can add gradient color to UIView, add animation layer and many more .

It is very easy to add a layer to UIView as: 

 let topgradientLayer = CAGradientLayer()
  topGredientLayer.frame = yourFrame.bounds

  topGredientLayer.startPoint = CGPointMake(0.5, 1.0)
  topGredientLayer.endPoint = CGPointMake(0.5, 0.0)

  topGredientLayer.colors = [UIColor(colorLiteralRed: 1.0,      green: 1.0, blue: 1.0, alpha: 0.0).CGColor,   UIColor(colorLiteralRed: 1.0, green: 1.0, blue: 1.0, alpha: 1.0).CGColor]

yourFrame.layer.insertSublayer(topGredientLayer, atIndex: 0)

This way we can add a layer to UIVIew.The default layer of UIView resize with  its view  but  sublayer does not resize with its view .

To make this work  we create a subclass of UIView and write above code in awakeFromNib() method . And also override layoutSublayersOfLayer(). 

For example:

override func awakeFromNib() {
  //add your layer here
}

override func layoutSublayersOfLayer(layer: CALayer) {
  yourSubLayer.frame  = self.bounds
}



Friday, 10 June 2016

Add a overlay layer on UIView

 Sometime we want to add an overlay layer on the  UIView. We can add an overlay shaded layer using CALayer. As we know each UIView is backed by  a layer. We can add many different layer  as sublayer to UIView. By using CALayer  we add as many effects to UIView as we want . 

For example , to add a sublayer to the part of the UIView, we can write a method for it .   

-(void)addLayerOnView:(UIView *)view withPercentage:(CGFloat)percentage{
    
    CALayer * subLayer  = [[CAShapeLayer alloc]init];
    
    CGFloat requiredW = (percentage/100) * view.frame.size.width ;
    
    CGRect tmpFrame =  view.frame;
    tmpFrame.size.width = requiredW;
    subLayer.frame = tmpFrame;
    subLayer.position  = CGPointMake(subLayer.frame.size.width/2, subLayer.frame.size.height/2);
    subLayer.opacity = 0.5f;
    
    subLayer.backgroundColor =  [UIColor grayColor].CGColor;
    
    [view.layer addSublayer:subLayer];
}

The above defined method take a UIView and percentage  as arguments . UIView is an object on which we want to add a sublayer and percentage tell us to the area of UIView on which we want to add a transparent layer .

In method , We create an instance of CAShapeLayer . Then we get the required width of the layer. We want the width of the layer should be percentage of the total width of the UIView . So we get the Width using formula:

    CGFloat requiredW = (percentage/100) * view.frame.size.width ;

Then set the frame, position and background color of the layer.

subLayer.frame = tmpFrame;
    subLayer.position  = CGPointMake(subLayer.frame.size.width/2, subLayer.frame.size.height/2);

We want to layer should be little transparent , so we also set the opacity of the layer :

    subLayer.opacity = 0.5f;

Finally we set the layer as sublayer of the UIView .

    [view.layer addSublayer:subLayer];






Friday, 3 June 2016

Add dashed border around a UIView

Hello.., some time we have some specific need in our . We may want a UIView to have a dashed border . We can add a border to UIView  , but that will be solid . To add a simple border, we do this:

  view.layer.borderWidth = 1
 view.layer.borderColor  = UIColor.lightGrayColor().CGColor


But what if we want to add dashed border like this:

   

To add dashed border like this , we can create a new layer and that layer as sublayer of the required view.



func dashedBorderLayerWithColor(color:CGColorRef) -> CAShapeLayer {
        
       let  borderLayer = CAShapeLayer()
        borderLayer.name  = "borderLayer"
         let frameSize = selectedViewForImage.frame.size
        let shapeRect = CGRectMake(0, 0, frameSize.width, frameSize.height)
        
        borderLayer.bounds=shapeRect
        borderLayer.position = CGPointMake( frameSize.width/2,frameSize.height/2)
        borderLayer.fillColor = UIColor.clearColor().CGColor
        borderLayer.strokeColor = color
        borderLayer.lineWidth=1
        borderLayer.lineJoin=kCALineJoinRound
        borderLayer.lineDashPattern = NSArray(array: [NSNumber(integer: 8),NSNumber(integer:4)]) as? [NSNumber]
        
        let path = UIBezierPath.init(roundedRect: shapeRect, cornerRadius: 0)
        
        borderLayer.path = path.CGPath
        
        return borderLayer

    }

Here we create an instance of CAShapeLayer. Then set its frame. After that we have set the different properties on instance of CALayer like fill color and stroke color and line width. Since we add a dashed line so we set lineJoin property to KCALineJoinRound. 
Then define the lineDashPattern which takes an array of numbers.
Then finally create a Bezierpath and set that path to the layer. and then return the layer.

Now to add dashed layer we can call above defined function to get the dashed layer like this

let borderLayer  = dashedBorderLayerWithColor(UIColor.blackColor().CGColor)
        
view.layer.addSublayer(borderLayer)
        

Friday, 27 May 2016

Delegate in swift

When working with swift, it's common case where we encounter in a situation where we want an object to perform the task on behalf of another object. The rescue to this is delegate. It is very same process of working of delegate like in objective c. But creating a custom delegate is little different then objective c in swift .

Lets look in example, here we are creating a custom delegate :


protocol userDelegate:class{

  //list of methods

func userDidLogIn()
func userDidLogOut()

}

Class User: NSObject{

//make a singleton of the User class
static let sharedUser =  User()

//define a property of the delegate
weak var delegate:userDelegate?

func logInUser(){
   //here we can store the state of the user and perform some other task
     
//call delegate method
delegate?.userDidLogIn() 
 
}

func  logoutUser(){
  //delete user detail from app
 
//call delegate method
 delegate?.userDidLogOut()
}
}


Now to use this delegate, we can create a login view controller, where user will login , on successful login , we make a singleton User() object and call its method logInUser . In logIn view controller will  conform to the userDelegate .

import UIKit

class LogInVc: UIViewController, userDelegate{

@IBAction func btnActn_userLogIn(sender:AnyObject){
      
       //create user
      let user  = User.sharedUser

    user. logInUser()

}

@IBAction func btnActn_logOut(sender:AnyObject){
   let user  = User.sharedUser

    user. logoutUser()
}

Now it's time to implement delegate methods, here we can perform the post log in task.
func userDidLogIn(){
 //perform post log in task here
}

func userDidLogOut{
//perform log out task here
}

}

Friday, 6 May 2016

Change UITabBar item's image color and title text color

Some time there is a need to add tab bar in our app. Apple provide UITabBarController to add a tab bar . 
Here is an example to add tab bar in our app
To add  a tab bar  in our app, we create  a UITabBarController instance.

let tabVC  =  UITabBarController()

Then create  the view controller instances we want to add  in tab bar . For example , we create two UIViewController instance here. You can  create the subclasses of UIViewController as per your requirements.

let vc1 =  MyViewController1()
let vc2 = MyViewController2()


Then add  both view controller to tabVC 's viewControllers property as:

tabVC.viewControllers = [vc1, vc2]

Then set the index of the view controller we want to see selected by default as:

tabVC.selectedIndex = 1

Now we have set up tab bar controller and add two view controllers to it . Now we add the  tabBarItem property of both view controllers  like as:

vc1.tabBarItem   = UITabBarItem(title:"Profile", image:nil, tag:1)
 or 
vc1.tabBarItem  =  UITabBarItem(title:String, image:UIImage?, unSelectedImage:UIImage?)
 
Here title and image color are of system color that is light gray . We can change the image color for both selected and unselected state of UITabBar items as

vc1.tabBarItem  = UITabBarItem(title:"Profile", image:UIImage(named:"profile.png")?.imageWithRenderingMode(.AlwaysOriginal), tag: 1)

Then above code assign a title Profile for the vc1 tab and set a image to the tab. The title will appear at the bottom of the  tab image. The  tab image color will be now of the same color as profile.png(red, white whatever.)

But the title color is same as before. So to change the color of title also , add this line:

UITabBatItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.whiteColor()], forState: .Normal) 

This will change the color  of the title of the tab bar item  in tab bar to white for normal state. You can  change the title color for selected state also in same way , just change the state in above statement .

         

Friday, 1 April 2016

Function in Swift

Functions are a self contained block of code that perform a specific task. Every function has a type in swift(parameter type and return type). Swift functions are more flexible  and allow us to do more things with it. As with swift function we can return multiple values as tuple, can pass variable number of arguments to it. It also allows the nesting of the function .
All of these we will look in  below described example:


func doSum(numbers:[Int])-> Int{

var sum =0
for num in numbers {
sum =  sum+ num
}

return sum
}


This function named doSum takes an integer array and do the sum of the numbers and in last return the sum.

To return multiple values from function use:

func doMath(numbers:[Int])-> (sum:Int, min:Int, max:Int){

var sum =0
var max = numbers[0]
var min = numbers[0]
for num in numbers {
         sum =  sum+ num
       
         if num >max{
              max  = num
        } else if num< min{
             min = num
       }
}

return (sum,min,max)
}

To call this function

let result =  doMath([23,34,56,56,67])

print(result.max)
print(result.min)
print(result.sum)

Functions can take variable number of argument , collecting them in array :

func doAvg(numbers:Int...)-> Int {

var sum =0
for num in numbers {
 sum = sum+ num
}
return sum/ numbers.count
}

To call this function
 let average = doAvg(23, 34, 5,55)


Function can also  be nested. In this case the inner function  will have access to the variable and things of the outer function .


Reference: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/GuidedTour.html