Browse Category: iOS

Animation like floating Buttons.

Hi all, today we will check out simple but cool floating buttons using UIViewAnimations methods. So, in this we are going to show 4 buttons which came out upside from another button. Here we are using constraints of  buttons, button and UIViewAnimations. Let’s start with  adding constraint to each buttons.
1) Setting constraints for buttons:-    

Add constraint such that bottom constraint of 2nd button to 1st bottom similarly do for 3rd to 4th and 4th to 5th button. I am doing this because when i am going to update value for constraint is same and due to that i can manage spacing between them.
I have set my button’s size to 45*45 and other constraints to ZERO. After setting constraint you should see only single button which overlaps other buttons.  And I need IBActions of  all 4 buttons. 

2) Adding Animations to IBAction methods:-    

Add Following line code in your application

if !flag{
  UIView.animate(withDuration: 0.20, animations: {
     self.btn1bottomCons.constant = 55
}, completion: { (isTrue) in
  if isTrue{
     UIView.animate(withDuration: 0.15, animations: {
     self.btn2bottomCons.constant = 55
}, completion: { (isTrue) in
        if isTrue{
UIView.animate(withDuration: 0.10, animations: {
            self.btn3bottomCons.constant = 55
})
}
})
}
})
}else{
UIView.animate(withDuration: 0.5, animations: {
     self.view.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
})
  btn1bottomCons.constant = 0
  btn2bottomCons.constant = 0
  btn3bottomCons.constant = 0
UIView.animate(withDuration: 0.10, animations: {
})
}
flag = !flag

Here flag is Bool value used to toggle the buttons. btn1bottomCons, btn2bottomCons, btn3bottomCons and btn4bottomCons are the constraint which we have created initially. When flag is false set constraint value to 55 otherwise set 0. Please observer that i have set value in the completion block of other button and duration of animation 0.20, 0.15, 0.10. So that at end animation must be fast.
If you like to create your own custom completion handle here is one example given below,….


func yourFunctionName(isFlag:Bool,str:String,isCompleted:(_ success: String)-> Void){
for _ in 01000 {
//make delay
}
var str2 = “Hi “
str2 += “Shashi!, Yours String is—> “
str2 += str
isCompleted(str2)// Pass your result to completion block at the end😎
}

Now call the function as below,

yourFunctionName(isFlag: true, str: “😜“) { (str_temp) in
print(“—-===>***”,str_temp,”***<===—-“)
}

 

3) Run the App:-    

Run the code and click the button and observe there and say “there is no animation happening here😡” .

To solve this issue you need to update layout which is single line of code more powerful because I observer that due to that viewDidload() call again😵 yes.

So you need to add the following line of code

self.view.layoutIfNeeded()

So final code will be,——>        

        if !flag{

            UIView.animate(withDuration: 0.20, animations: {

                self.btn1bottomCons.constant = 55

                self.view.layoutIfNeeded()

            }, completion: { (isTrue) in

                if isTrue{

                    UIView.animate(withDuration: 0.15, animations: {

                        self.btn2bottomCons.constant = 55

                        self.view.layoutIfNeeded()

                    }, completion: { (isTrue) in

                        if isTrue{

                            UIView.animate(withDuration: 0.10, animations: {

                                self.btn3bottomCons.constant = 55

                                self.view.layoutIfNeeded()

                            })

                        }

                    })

                }

            })

        }else{

            UIView.animate(withDuration: 0.5, animations: {

                self.view.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)

            })

            btn1bottomCons.constant = 0

            btn2bottomCons.constant = 0

            btn3bottomCons.constant = 0

            UIView.animate(withDuration: 0.10, animations: {

                self.view.layoutIfNeeded()

            })

        }

        flag = !flag

 

And my original project is on this Link:—–>https://github.com/ShashikantBhadke/ADMobs

Download PDF file using Alamofire in Swift3

Almofire is a very popular library for networking related coding(eg. API call, Downloading Stuffs etc) and totally developed in swift which is replacement of AFNetworking library of ObjectiveC. It has multiple features like Image cacheing, API call integration,File downloading etc. Today we are going to dive into Download PDF file using Alamofire in Swift.

Pods are available for almofire on GitHub for integration of this library into your own project, some steps are explained as follows:- 

  • First create a pod file for implementing the Alamofire and MBProgressHUD

pod ‘Alamofire’ // Download PDF file
pod ‘MBProgressHUD’ //Downloading Progress Bar

  • We have to create Webview Object for open downloaded PDF url.
  • Use following function in view controller and pass the url string to the function.

 

 func downloadPDFFile(urlString:String)

{

    let hud = MBProgressHUD.showAdded(to: self.view, animated: true)

    hud.mode = MBProgressHUDMode.annularDeterminate

    hud.label.text = “Loading…”

    

    let destination: DownloadRequest.DownloadFileDestination = { _, _ in

      let documentsURL:NSURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! as    NSURL

      print(“***documentURL: “,documentsURL)

      let PDF_name : String = “Downloded_PDF_Name”

      let fileURL = documentsURL.appendingPathComponent(PDF_name)

      print(“***fileURL: “,fileURL ?? “”)

       return (fileURL!,[.removePreviousFile, .createIntermediateDirectories])

    }

    Alamofire.download(urlString, to: destination).downloadProgress(closure: { (prog) in

      hud.progress = Float(prog.fractionCompleted)

    }).response { response in

      

      hud.hide(animated: true)

      if response.error == nil, let filePath = response.destinationURL?.path    {

        print(“File Path”,filePath)

      

        //Open this filepath in Webview Object

        

        let fileURL = URL(fileURLWithPath: filePath)

        let request = URLRequest(url: fileURL)

        webView.loadRequest(request)

      }

    }

  }

One fantastic way to Load ‘CollectionView’ inside ‘TableViewCell’ using Two ‘Extensions’ in swift3, iOS

As We know we, Often, we assign a collection view’s data source to its view controller. But here the problem is that we have only one view controller and many collection views.

As I have taken number of ‘Sections’ inside table view. so following is the Solution to distinguish between a collection view on the first section , and one on the second , third and fourth…

So here is a way to store which table view cell a collection view is in.

 

  • TableView : I have taken multiple sections And Only One Row.
  • Collection View : I have Only one Section And Multiple Items.

 

In ViewController.swift Use Following –

  • Extension :

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {

     func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int   {

          return 3

     }

     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell   {

          let cell = collectionView.dequeueReusableCell(withReuseIdentifier: “UploadCell”, for: indexPath) as!                 UploadCollectionViewCell

          //Code

    return cell

     }

     func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath  {       

          print(“Collection view at row \(collectionView.tag) selected index path \(indexPath)”)

     }

}

 

 

In TableViewCell.swift Use Following –

  • Extension :

  extension TableViewCell  {

          func setCollectionViewDataSourceDelegate<D: UICollectionViewDataSource & UICollectionViewDelegate>(_ dataSourceDelegate: D, forRow row: Int) {

               collectionView.delegate = dataSourceDelegate

               collectionView.dataSource = dataSourceDelegate

               collectionView.tag = row

               collectionView.setContentOffset(collectionView.contentOffset, animated:false) // Stops collection view if it was scrolling.

               collectionView.reloadData()

          }

          var collectionViewOffset: CGFloat {

               set { collectionView.contentOffset.x = newValue }

               get { return collectionView.contentOffset.x }

          }

     }

 

*******  One IMP addition in ‘willDisplay’ method of tableView in ViewController.swift  *******

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

          guard let tableViewCell = cell  else { return }

          tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.section)

     }

 

 

Thanks.

iOS – Tap to zoom and share image using Apple’s QuickLook framework

QuickLook framework is one of the best framework by Apple. It can be used to preview files such as iWork, MS Office, RTF, CSV documents, pdf, text files, Images.

You can use this framework to implement image zooming and sharing feature. We don’t need to write this zooming and sharing code ourself. QuickLook framework provides this all awesome functionality.

Let’s start implementing this powerful and easy framework.
(I have used Swift 3 and XCode 8.3.2)

*  Use Single View application template and give a name to your project(App). Select Swift language.

* On Storyboard make your view controller UI like this :  Check this image.
Take 2 UIImageViews  and take 1 UIButton on each UIImageView. Create necessary IBOutlets and IBActions.

* Your final ViewController Code should look like below.


import UIKit
import QuickLook   // Import QuickLook to use it’s functionalities.

let imageURLs =  [“https://static2.hdwallpapers.net/wallpapers/2015/03/24/574/thumb_steve-jobs-typographic-portrait.jpg”, “http://www.planetware.com/photos-large/F/france-paris-eiffel-tower.jpg”]

class Downloader  {    // This is Image Downloader helper class
        class func downloadImageWithURL(_ url:String) -> UIImage? {
               let data = try? Data(contentsOf: URL(string: url)!)

if
let imgData = data {
                   return UIImage(data: imgData)
               }

              else {
                  print(“\n\nThis image url may be wrong : \n \(url)”)
                  return nil
               }

    }

}


class iOSConcurrencyViewController: UIViewController, QLPreviewControllerDataSource

    // Connect this 2 imageView outlets with your imageViews.
    @IBOutlet weak var imageView1: UIImageView!  
    @IBOutlet weak var imageView2: UIImageView!

   // Connect this outlet with Bar button named – Start
    @IBOutlet
weak var barButton_Start: UIBarButtonItem!

   let quickLookController = QLPreviewController()
   var myQLimageURL: URL?

    override func viewDidLoad() {

        super.viewDidLoad()

       // Add QuickLook dataSource to  self
       quickLookController.dataSource =
self

    }

@IBAction func didClickOnStart(_ sender: AnyObject) {  // Connect this IBAction with Bar button item – Start

        // Here we will start downloading images and then disable the start button.
        barButton_Start.isEnabled = false

        //   ##################  Dispatch Queues ##################

         // Default(System provided) global Dispatch queue

        // It can download any image in any order at any time once started.

        let imgDownloader_DefaultConcurrentQueue = DispatchQueue.global(qos: .default)

        //img1

        downloadUsingGCD_AndShowImage(in: imageView1, index: 0, with: imgDownloader_DefaultConcurrentQueue)

        //img2

        downloadUsingGCD_AndShowImage(in: imageView2, index: 1, with: imgDownloader_DefaultConcurrentQueue)

}

 

// For GCD – Dispatch Queues

    func downloadUsingGCD_AndShowImage(in imageView: UIImageView, index imageIndex: Int, with Queue: DispatchQueue) {

            Queue.async {  // To avoid blocking UI, download images in background.

            let img = Downloader.downloadImageWithURL(imageURLs[imageIndex])

            let fileParts = imageURLs[imageIndex].components(separatedBy: “/”)

            DispatchQueue.main.async { // UI update code should be on main thread.

                imageView.image = img

                self.saveImageToDirectory(imageName: fileParts.last!, img: img!)

            }

        }

    }


// You have used a button on each imageView. Give 0 tag for button1 and 1 for button2. Then connect both buttons IBAction to this.
@IBAction func button_ZoomImage_Tapped(_ sender: UIButton) {

        var index = Int()

        switch sender.tag {

        case 0:

            index = 0

        case 1:

            index = 1

        default:

            break

        }

        // Get image name with extension from image url
        let fileParts = imageURLs[index].components(separatedBy: “/”)

        myQLimageURL = getImageFromDirectory(imageName: fileParts.last!) 

        if let QLImgURL = myQLimageURL {

            if QLPreviewController.canPreview(QLImgURL as QLPreviewItem) { 

                // This line refreshes current preview otherwise you will see only 1 image for both image views.
                quickLookController.refreshCurrentPreviewItem() 

                //navigationController?.pushViewController(quickLookController, animated: true)

                            present(quickLookController, animated: true, completion: {

                                print(“completion block”)

                            })

            }

        }

    }

 

    // Get Documents Directory helper function

    func getDocumentsDirectory() -> URL {

        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)

        let documentsDirectory = paths[0]

        return documentsDirectory

    }

    

    // Save Image to Directory

    func saveImageToDirectory(imageName: String, img: UIImage) {

        //if let image = UIImage(named: imageName) {

            if let data = UIImageJPEGRepresentation(img, 0.8) {

                let filename = getDocumentsDirectory().appendingPathComponent(imageName)

                try? data.write(to: filename)

            }

        //}

    }

    

    // Get Image from Directory

    func getImageFromDirectory(imageName: String) -> URL? {

        let imageURL = getDocumentsDirectory().appendingPathComponent(imageName)

        let imagePath = (getDocumentsDirectory().appendingPathComponent(imageName)).path

        if FileManager.default.fileExists(atPath: imagePath) {

            return imageURL

        }

        else {

            return nil

        }

    }

    

    // QuickLook Datasource
    func numberOfPreviewItems(in controller: QLPreviewController) -> Int {

        return 1    // This will return only 1 image at a time

    }

    func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {

        return myQLimageURL! as QLPreviewItem

    }

 

Have fun… 🙂

Let me know if you have any queries or problems implementing this feature. Enjoy … 🙂

 

Animated Launch Screen

Basically when we want to set an image for LaunchScreen then we use LaunchScreen.storyboard for setting an image, but as this file does not have any class file (eg .swift or .h & .m) so we can not write code for animating that image at runtime. To achieve this we need to use main.storyboard

Steps to implement animated Launch Screen : –

1) Click on project name on ProjectNavigatorPanel -> go to Target.

2) Scroll down  to “Main Interface” -> click down arrow -> change  LaunchScreen.storyboard to Main.

3) Go to Main.storyboard -> Select your view controller for which you want to set animated Launch Screen.

4) Select your view controller -> click on Editor on top menu bar -> Embed In -> select Navigation Controller

5) Set Navigation Controller as Initial ViewController of your project.

Now create a class for writing code of animation and connect it to view controller on Main.storyboard , Once the animation is done you can push a view controller to next view controller programmatically.

 

NOTE : You can write any type of animation code in that class file (eg .swift) as per your requirements. I have used .gif image for LaunchScreen using code from “Swift+Gif.swift” file.Have a fun with animation Code Here

NSSortDescriptor in swift 3

To sort an json array using NSSortDescriptor in swift3

 

NSSortDescriptor :

A sort descriptor describes a comparison used to sort a collection of objects. You create an instance of NSSortDescriptor that specifies the property key to be sorted, and whether the comparison should be in ascending, or descending order. A sort descriptor can also specify a method to use when comparing the property key values, rather than the default of compare:.

It is important to remember that NSSortDescriptor does not sort objects. It provides the description of how to sort objects. The actual sorting is done by other classes, often NSArray or NSMutableArray.

NSSortDescriptor objects are constructed with the following parameters:

  • key: for a given collection, the key for the corresponding value to be sorted on for each object in the collection.
  • ascending: a boolean specifying whether the collection should be sorted in ascending (YES) or descending (NO) order.

 

// replace the urlname

let task = URLSession.shared.dataTask(with: NSURL(string: “urlname”)! as URL, completionHandler: { (data, response, error) -> Void in

       if (data != nil || error == nil)

                {

                let dict: AnyObject? = try! JSONSerialization.jsonObject(with: data!, options: []) as AnyObject?

                 if (dict is NSArray)

                {

                    let dictArray : NSArray = dict as! NSArray

                    let aArray : NSMutableArray = NSMutableArray(array: dictArray)

                     //replace keyname whatever you want an array should be sort ,for example , json array contain “id” key 

                     //you want array should be sort using that “id” , keyname should be “id”

                   // if you want array ascending then set value  “true” for key ascending, otherwise set to “false”

                    let descriptor: NSSortDescriptor = NSSortDescriptor(key: “keyname”, ascending: true)

                    // sortedResult is an result array which is sorted using key defined in NSSortDescriptor

                     sortedResults = aArray.sortedArray(using: [descriptor]) as NSArray

                   print(sortedResults)

                    }

                   }

        })

        task.resume()

iOS – Image Downloader helper class (Swift 3)

Image Downloader Class written in Swift 3 to download images.

class Downloader {

        class func downloadImageWithURL(_ url:String) -> UIImage? {

           let data = try? Data(contentsOf: URL(string: url)!)

         if let imgData = data {

            return UIImage(data: imgData)

        }

        else {

            print(“\n\nThis image url may be wrong : \n \(url)”)

            return nil

        }

    }

} // class end

You can then use this class to download and show image in your UIImage  as below:

        let image  =  Downloader.downloadImageWithURL(“http://images.freeimages.com/images/premium/small-comps/3352/33528960-palouse-waterfall-washington.jpg”)

yourImageView.image = image

Then you are done. Enjoy… 🙂

 

Make future payment using Braintree payment gateway

This tutorial is for those who are developing a mobile application and they want to charge a customer(one or more time) in future. In this tutorial I am going to explain backend functionality in details.

Most of the time we need charge to  customer  in future. Some developers may store details in the database but this is not the best way when it comes to security. Fortunately this feature is provided by braintree and stripe payment gateways. Following tutorial will explain you how we can use braintree API.

Before we start a tutorial make sure that you have a braintree(Sandbox/Production) account, if you don’t have an account  you can open your braintree sandbox account from here Sandbox Account. Mobile developers need to install braintree provided sdk from here Mobile SDK
Braintree payment screen

Once you installed SDK successfully you can see the above screen and fields like card Number, Expiration Date and CVV Number which is provided by braintree you don’t need to do any code for that.

If you using sandbox account enter following Card details for testing purpose.

Sandbox Card Number: 4242 4242 4242 4242

Card Exp: Any future expiry month/Year

CVV: 123

When user click “Buy Now” button braintree SDK returns you paymentMethodNonce .  What you’ll do next step. Simply you’ll send paymentMethodNonce to your server through webservice.

Now the actual backend functionality start here.

Suppose you are sending the parameter paymentMethodNonce to the API YourServer.com/add_card_token.php

In add_card_token.php i will use the method provided by braintree (make sure you have downloaded PHP braintree library if not then click here)

<?php

require_once ‘lib/Braintree.php’; //installed braintree php library and include over here

Braintree_Configuration::environment(‘sandbox’);

Braintree_Configuration::merchantId(‘your_account_merchant_id’);

Braintree_Configuration::publicKey(‘public_key’);

Braintree_Configuration::privateKey(‘private_key’);

$paymentMethodNonce = $_POST[‘paymentMethodNonce ‘];//Getting parameters from mobile dev

$result = Braintree_Customer::create( array( ‘firstName’ => ‘abc’, ‘lastName’ => ‘efg’, ‘company’ => ‘Nanostuffs’, ‘paymentMethodNonce’ => $paymentMethodNonce ));

$customerid = $result->customer->id; //Store this info into the database

$card_token = $result->customer->paymentMethods[0]->token;//Store this info into the database

?>

The method (Braintree_Customer::create) will returns you all the basic information about the card like expiry, last four…

You will get customer id $result->customer->id and card_token in response $result->customer->paymentMethods[0]->token

You will store this information into the database for that particular customer.

Great, now you are ready to charge a customer in future anytime. Suppose i want to charge that customer now i will use the following method.

<?php

require_once ‘lib/Braintree.php’; //installed braintree php library and include over here

Braintree_Configuration::environment(‘sandbox’);

Braintree_Configuration::merchantId(‘your_account_merchant_id’);

Braintree_Configuration::publicKey(‘public_key’);

Braintree_Configuration::privateKey(‘private_key’);

try{

$result = Braintree_Transaction::sale(array(  ‘amount’ => ‘100’,

‘paymentMethodToken’ => $customer_id,

‘options’ => [ ‘submitForSettlement’ => True  ] )

);

if($result->success) {

$transactionId = $result->transaction->id;

}else{

$err = ”;

foreach($result->errors->deepAll() AS $error) { $err.= $error->message.” “; }

echo $err;

}

}catch(Exception $e)

{}

?>

Check and parse proper response returned by braintree. You have charged to the customer successfully. If you run the same method again you can see the charge successfully. Without entering user card details again.

You can achieve this using any sever side langauge. I am familiar with PHP only.

Let us know if this tutorial really help you 🙂

UIAlertView Deprecated in Xcode6.0

Hi All,

Everybody is curious about changes made by Apple in Xcode 6 and newly added functionalities, here is the one noticeable change which is nothing but UIAlertView and UIActionsheet is deprecated.
Now Apple has introduced a new class for replacement of those – UIAlertController. Let see how it can be used for displaying alertview :

UIAlertController *alertController = [UIAlertController
                              alertControllerWithTitle:@"Title"
                              message:@"Message"
                              preferredStyle:UIAlertControllerStyleAlert];

Buttons can be added by creating instance of the UIAlertAction 


UIAlertAction *cancelAction = [UIAlertAction 
            actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel method")
                      style:UIAlertActionStyleCancel
                    handler:^(UIAlertAction *action)
                    {
                      NSLog(@"Cancel button called");
                    }];

UIAlertAction *okAction = [UIAlertAction 
            actionWithTitle:NSLocalizedString(@"OK", @"OK method")
                      style:UIAlertActionStyleDefault
                    handler:^(UIAlertAction *action)
                    {
                      NSLog(@"OK button called");
                    }];

[alertController addAction:cancelAction];
[alertController addAction:okAction];