Browse Category: iOS

Applying Query in core data

There are few cases when we prefer to use Core data that Sqlite. Core data is faster in fetching records than SQLite. As like sqlite we can fetch data by specifying query in Core data.

Following is the way to set your query for fetch request of core data.

let request = NSFetchRequest()
if #available(iOS 10.0, *)
{
request.entity = EmpData.entity()
}
else
{
request.entity = NSEntityDescription.entity(forEntityName: “EmpData”, in: context)
}

let name = “Ram”

request.predicate = NSPredicate(format: “empName == %@”,empName)

do{
let results = try context.fetch(request)

….
….
….
….

}
catch
{

}

Also Some times we required to fetch only few number of records each time. For example you have large amount of data then we need to fetch data in batches.

Following is the code to do this

request.fetchLimit = 100
request.fetchOffset = recordCount

where fetchLimit is amount of records you want each time to fetch and fetchOffset is from where to start. Here recordCount is the counter to keep track from where to start the fetch for next time.

UserDefaults with NSCoding and Codable to save any kind of Data… Part – 1 ūüėé

¬†UserDefaults¬† is one of the good and handy storage you can use.¬†You can use¬†UserDefaults¬†to store any basic data type for as long as the app is installed. For example, you can use basic types as¬†Bool,¬†Float,¬†Double,¬†Int,¬†String, or¬†URL, but you can also write more complex types such as arrays, dictionaries and¬†Date¬†‚Äď and even¬†Data¬†values.

Advantage: After writing data to UserDefaults, when you run the app the UserDefaults data gets automatically loaded. Its very easy to use it.

Disadvantage:  Its a bad idea to use UserDefaults to save lot of data as it slows down your app loading and increases app load time.

You can use it making an instance of the UserDefaults like below:

let defaults = UserDefaults.standard

Now you can save your data like below:

defaults.set(26, forKey: "Age")

defaults.set(true, forKey: “is_iOS_Best”)

defaults.set(CGFloat.pi, forKey: “Pi”)

defaults.set(Date(), forKey: "CurrentDate")
let myArray = ["iOS", "macOS"]
defaults.set(myArray, forKey: "SavedArray")
let myDict = ["Name": "Sagar", "Hobby": "Coding"]
defaults.set(dict, forKey: "SavedDict")

You can get the stored values/data back using below methods:

  • integer(forKey:)¬†returns an integer if the key existed, or 0 if not.
  • bool(forKey:)¬†returns a boolean if the key existed, or false if not.
  • float(forKey:)¬†returns a float if the key existed, or 0.0 if not.
  • double(forKey:)¬†returns a double if the key existed, or 0.0 if not.
  • object(forKey:)¬†returns¬†Any?¬†so you need to conditionally typecast it to your data type.You can save a complex kind of data too in UserDefaults using NSCoding and Codable protocols.
    NSCoding is available for both Objective-C and Swift developers but Codable is only for Swift developers.We will see the usage of first one : NSCoding


     NSCoding

    Your class must confirm to NSCoding before using it, like you use other protocols : UITableViewDataSource and UITableViewDataDelegate.

    Then you can implement it using below method which changes the object graph to Data, so that it becomes able to save in UserDefaults.

    archivedData(withRootObject:) method of NSKeyedArchiver

    There are many Apple’s own classes that support NSCoding like:¬†UIColor,¬†UIImage,¬†UIView,¬†UILabel,¬†UIImageView,¬†UITableView,¬†SKSpriteNode
    but your custom classes don’t support it by default.

    You can also refer HackingWithSwift blog for free and good coding tutorials.

    Let us have a look at below example for its use.

    For example:

    Consider your custom class is MySelf in which you are using name and image properties.


    import UIKit

    class MySelf: NSObject, NSCoding { //Here NSObject is required to use NSCoding.

         func encode(with aCoder: NSCoder)  {    // this method is required and used to encode data

             aCoder.encode(name, forKey: name)

             aCoder.encode(image, forKey: image)

         }

        required init?(coder aDecoder: NSCoder) {   // this method is required and used to decode data

             name = aDecoder.decodeObject(forKey: name) as! String

            image = aDecoder.decodeObject(forKey: image) as! String

       }


    var
    name: String

       var image: String


    init
    (name: String, image: String) {

             self.name = name

            self.image = image

       }

    }

     


    Now in your ViewController class you can use it like below


     

    import UIKit

    class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UICollectionViewDataSource {

        var people = [MySelf]()          // array of MySelf type data

        @IBOutlet weak var myCollectionView: UICollectionView!

        override func viewDidLoad() {

              super.viewDidLoad()

              let defaults = UserDefaults.standard

              if let savedPeople = defaults.object(forKey: people) as? Data {

                      // Get saved values using below method
    people
    = NSKeyedUnarchiver.unarchiveObject(with: savedPeople) as! [MySelf]
    }

          }

        @IBAction func barButton_addPersonTapped(_ sender: Any) {

               addPerson()    

        }

        func addPerson() {      // Show ImagePickerController

               let imagePicker = UIImagePickerController()

              imagePicker.allowsEditing = true

             imagePicker.delegate = self

             present(imagePicker, animated: true) {

                 //  completion block

              }

          }

        func getDocumentsDirectory() -> URL {   // // Get DocumentsDirectory

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

              let documentsDirectory = paths[0]

              return documentsDirectory

        }

    // UICollectionViewController Delegates


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

         return people.count

    }

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

          let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PersonCollectionViewCell, for: indexPath) as! PersonCollectionViewCell

         let aPerson = people[indexPath.item]

         cell.name.text = aPerson.name

         let path = getDocumentsDirectory().appendingPathComponent(aPerson.image)

         cell.imageView.image = UIImage(contentsOfFile: path.path)

         cell.imageView.layer.cornerRadius = 3

         cell.imageView.layer.borderWidth = 2

         cell.imageView.layer.borderColor = UIColor(displayP3Red: 0, green: 0, blue: 0, alpha: 0.3).cgColor

         cell.layer.cornerRadius = 7

        return cell

     }

    // UIImagePickerController Delegates

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

         guard let image = info[UIImagePickerControllerEditedImage] as? UIImage else { return }

         let imageName = UUID().uuidString

         let imagePath = getDocumentsDirectory().appendingPathComponent(imageName)

         if let jpegData = UIImageJPEGRepresentation(image, 80) {

               try? jpegData.write(to: imagePath)  // Write your image jpeg data to imagePath

         }

         let aPerson = MySelf(name: Img, image: imageName)

         people.append(aPerson)

         myCollectionView.reloadData()

         dismiss(animated: true) {

               //

         }

         self.save()  // Save newly added Image with name.

      }


    func
    save() {  // Save image and name using archivedData method of  NSKeyedArchiver

            let saveData = NSKeyedArchiver.archivedData(withRootObject: people)

            let defaults = UserDefaults.standard

          defaults.set(saveData, forKey: people)

       }

    }


    Your custom collectionViewCell class: PersonCollectionViewCell 


     

    import UIKit

    class PersonCollectionViewCell: UICollectionViewCell {

           @IBOutlet weak var imageView: UIImageView!

           @IBOutlet weak var name: UILabel!

    }


    Have fun… ūüôā

    I will show the usage of Codable in my next post.

    Let me know if you have any queries or problems implementing this feature. Enjoy … ūüôā

Push Notification displayed when application in foreground in iOS 10

Introduction: 

The new framework called ‚ÄúUserNotifications‚ÄĚ is introduced with iOS 10 SDK. The¬†UserNotifications framework¬†(UserNotifications.framework) supports the delivery and handling of local and remote notifications when application is in foreground

Steps for implement code to handle push notifications in iOS 10

Import UserNotifications.framework in your AppDelegate file :                                                                              import UserNotifications  and Also add UNUserNotificationCenterDelegate.

Register for Notification :

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
registerForRemoteNotification()
return true
}
func registerForRemoteNotification() {
if #available(iOS 10.0, *) {
let center  = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
if error == nil{
UIApplication.shared.registerForRemoteNotifications()
}
}
}
else {
UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.sound, .alert, .badge], categories: nil))
UIApplication.shared.registerForRemoteNotifications()

}

}

 Handling delegate methods for UserNotifications :
//MARK: UNUserNotificationCenter Delegate  >= iOS 10
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter willPresent notification: UNNotification, withCompletionHandler   completionHandler: @escaping (_ UNNotificationPresentationOptions) -> Void) {

       //Called when a notification is delivered to a foreground app.

        let userInfo = notification.request.content.userInfo as? NSDictionary

         completionHandler([.alert, .badge, .sound])

¬† ¬† ¬† ¬† print(\(userInfo)”)

       }

  @available(iOS 10.0, *)

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

        // Called to let your app know which action was selected by the user for a given notification.

        let userInfo = response.notification.request.content.userInfo as? NSDictionary
print(“\(userInfo)”)
}

      Add Push Notifications Entitlements :  Go to your project target’s Capabilities tab and add Push Notifications Entitlements. If it’s available in your     certificates then it will enable directly else configure your profile with the certificates and you can enable this capability by that.

For Detail refer the this link :
http://ashishkakkad.com/2016/09/push-notifications-in-ios-10-swift/

Custom Protocol and Delegate

Custom protocols and delegate is the very efficient way to passing values to other controller from one controller. If we required pass the value for only one controller in entire project the we should not go for declaring “Global Variable” to pass the values.



Example:  Display PopOver for option selection on button click event which placed on TableViewCell. On option selection make some changes on TableView.



Let’s assume ViewController of tableview is (VC-1) andViewController of¬† PopOver¬†is (VC-2).

Here the actual process of CODING get started,

create one table view with custom cell on (VC-1) then design for PopOver/ popUp on (VC-2).

Now we have to pass value from  (VC-2) to  (VC-1) so create custom protocol and delegate on  (VC-2) as below

protocol popOverListViewControllerDelegate {

    func getSelectedValueFromPopOverList(str:String)

}

place this above code outside the block of class.

Now declare a variable of delegate inside (VC-2) as below

var delegate : popOverListViewControllerDelegate?

go to option selection event on (VC-2) ie. didSelect method of  popOver table and copy the below code.

this line of code will pass the value to (VC-1)

delegate?.getSelectedValueFromPopOverList(str: arrOptions[indexPath.row])

here is the end of Custom Protocol and Delegate declaration. Let us move to (VC-1) to write the further code.

First of all import the protocol popOverListViewControllerDelegate in (VC-1).

It’s¬† time to set the delegate, to set the delegate create an instance of¬†(VC-2) and set the delegate as below

let popController = UIStoryboard(name: “Main”, bundle: nil).instantiateViewController(withIdentifier: “popListViewController”) as! popListViewController

  popController.delegate = self

Finally we will get the value which was passed by (VC-2) to (VC-1) using below code.

below code is the actual definition of the delegate which we created/declared in  (VC-2)

func getSelectedValueFromPopOverList(str:String)  {

¬† ¬† print(“I got value which is passed from(VC-2) : \(str)”)

}

 

Here is the Demo Project for this tutorial #HaveFun ūüôā

 

 

 

Get CrashLogs with Fabric Crashlytics

Crashlytics provides deep and actionable insights, even the exact line of code your app crashed on. While Crashlytics gives you powerful crash reporting, with one additional click you can enable real-time analytics that help you understand what’s happening in your app.

Installation:

1. Add kit to your Podfile.

use_frameworks!
pod ‘Fabric’
pod ‘Crashlytics’

Then run following command in your terminal

pod install

2. In Project Navigator select your project from targets -> go to Build Phase -> click on plus button and add “New Run Script Phase” and paste following code

“${PODS_ROOT}/Fabric/run” ba500759ec59e71c692c2e3e003edd73e25207c2 13fd4768392c1fb440b9bb7447dab03757c569a498a25c7e667fdbdefd52f57b

3. Add API in Info.plist file

<key>Fabric</key>
<dict>
<key>APIKey</key>
<string>ba500759ec59e71c692c2e3e003edd73e25207c2</string>
<key>Kits</key>
<array>
<dict>
<key>KitInfo</key>
<dict/>
<key>KitName</key>
<string>Crashlytics</string>
</dict>
</array>
</dict>

 

Initialize Your Kit

In AppDelegate. swift file

import Fabric
import Crashlytics

Then in application DidFinishLaunch method

Fabric.with([Crashlytics.self])

 

To get User Information

  • Add following method in your appDelegate file and call this method after¬†¬†Fabric.with([Crashlytics.self]) this
  • line of code.
  • func logUser() {
    // TODO: Use the current user’s information
    // You can call any combination of these three methods
    Crashlytics.sharedInstance().setUserEmail(“user@fabric.io”)
    Crashlytics.sharedInstance().setUserIdentifier(“12345”)
    Crashlytics.sharedInstance().setUserName(“Test User”)
    }

 

 

 

Subclassing in Swift

Subclassing is a very simple and useful concept of inheritance, when we create a subclass of any existing class then that custom class inherits all the methods and properties of existing or predefined class and moreover we can add our own user defined properties and methods to it.

 

Here is the syntax with example for subclassing ,

class myCustomButton : UIButton

{

var section = Int()

}

Problem Statement :-

Consider the example of TableView and it consist Two Section and multiple rows in each section, every table cell has one UIButton and we want to get existing “Row” and “Section” for clicked UIButton.

 

Explanation:-

UIButton has property call “tag” , by setting¬† the “indexPath.row” we can get row¬† indexfor selected button but for getting section for selected button we can use above example of subclass.

Now change cellForRow datasource code as below.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

¬† ¬† ¬† ¬† ¬†let cell = demoTableView.dequeueReusableCell(withIdentifier: “cell”, for: indexPath) as!demoTableView

         cell.btn.tag = indexPath.row

         cell.btn.section = indexPath.section

         return playersCell

    }

 

Finally select button from table view and set “myCustomButton” as superclass to that button.

Scanning QR Code Using AVFoundation Framework

QR (short for Quick Response) code. QR code has gained popularity in consumer space in recent years as a way to encode URL of a landing page or marketing information. Unlike the basic barcode that we’re familiar with QR code contains information in both horizontal and vertical direction. Thus this contributes to its capability of storing larger amount of data in both numeric and letter form.In this tutorial we will build a similar QR code reader app in Swift. After going through the tutorial you will understand how to use the AVFoundation framework to discover and read QR code in real-time. Any barcode scanning in iOS including QR code is totally based on video capturing. That’s why the barcode scanning feature is added in the AVFoundation framework.The app works pretty much like a video capturing app but without recording feature. When the app is launched it takes advantage of the iPhone’s rear camera to spot the QR code and recognises it automatically. 

I have created the user interface of the app in the project template. The label in the UI will be used to display decoded information of QR code and it is associated with the msglbl property of the ViewController class.

As mentioned we rely on the AVFoundation framework to implement the QR code scanning feature.

1) First, open ViewController.swift and import the framework:

     import AVFoundation

2) Later, we’ll need to implement the AVCaptureMetadataOutputObjectsDelegate protocol.

      class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate

3) Instantiate an AVCaptureSession object with the input set to the appropriate AVCaptureDevice for video capturing. Since we are going to capture video data we call the default(for:) method passing it AVMediaTypeVideo to get the video capture device. We instantiate an AVCaptureSession object and add the input of the video capture device. The AVCaptureSession object is used to coordinate the flow of data from the video input device to our output.

The output of the session is set to an AVCaptureMetaDataOutput object. The AVCaptureMetaDataOutput class is the core part of QR code reading.

This class in combination with the AVCaptureMetadataOutputObjectsDelegate protocol is used to intercept any metadata found in the input device (the QR code captured by the device’s camera) and translate it to a human-readable format.

4) The metadataObjectTypes property is also quite important as this is the point where we tell the app what kind of metadata we are interested in. The AVMetadataObjectTypeQRCode clearly indicates our purpose.We have set and configured an AVCaptureMetadataOutput object we need to display the video captured by the device’s camera on screen. This can be done using an AVCaptureVideoPreviewLayer which actually is a CALayer. You use this preview layer in conjunction with an AV capture session to display video. The preview layer is added as a sublayer of the current view. Start the video capture by calling the startRunning method of the capture session.

5)  When the AVCaptureMetadataOutput object recognises a QR code the following delegate method of AVCaptureMetadataOutputObjectsDelegate will be called:

       func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection)

The second parameter (i.e. metadataObjects) of the method is an array object which contains all the metadata objects that have been read.

6) Lastly we decode the QR code into human-readable information.The decoded information can be accessed by using the stringValue property of an AVMetadataMachineReadableCode object.iOS requires app developers to obtain the user’s permission before allowing to access the camera. To do so you have to add a key named NSCameraUsageDescription in the Info.plist file. Open the file and Set the key to Privacy РCamera Usage Description and value to We need to access your camera for scanning QR code.

7) Now you’re ready to go! Hit the Run button to compile and run the app on a real device. Once launched tap the scan button and then point the device to the QR code.The app immediately detects the code and decodes the information.

You can download the completed project here

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.


Need more help?

Hi there, was your problem or query resolved? If not & need more assistance, please do reach out to us at info@nanostuffs.com, we'll be more than delighted to help. Nanostuffs has 7+ years of extensive Salesforce & iOS/Android experience.
Holler Box