Browse Tag: Swift

Move View/ScrollView to keep TextField visible when keyboard appears!

There is a very common but tricky part comes while handling textfields position when keyboard appears. Its sometimes become headache for developers to handle such small but tricky issue. When keyboard appears then some textfields get covered and user can’t see while editing it.

There are some solutions to handle this but many of them works only for the first time. And then doesn’t work.
I have found one best solution and it works great always and I have modified this code to work on Swift 4. I have used XCode 9.1 for this tutorial code.

Lets do it.

You will have to create new project to try this. Design your storyboard like the image from below link.

And set delegate of all textFields to ViewController.

Now in your ViewController class you can use it like below


import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

     @IBOutlet weak var myScrollView: UIScrollView!

     @IBOutlet weak var constraintContentHeight: NSLayoutConstraint!

     override func viewDidLoad() {



override func viewWillAppear(_ animated:Bool) {


//1  Add this observers to observe keyboard shown and hidden events
      NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(aNotification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

     NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(aNotification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)


override func viewWillDisappear(_ animated: Bool) {


//2  Remove the observers added for keyboard from your ViewController

     NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)

     NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)


var activeField: UITextField?

// MARK: – UITextField Delegates

//3  ViewController activeField is an object of UITextField which will be used to manage and resign current active textField 

func textFieldShouldReturn(_ textField: UITextField) -> Bool {


     return true


func textFieldDidBeginEditing(_ textField: UITextField) {

     activeField = textField


func textFieldDidEndEditing(_ textField: UITextField) {

     activeField = nil


// Called when the UIKeyboardWillHide is sent

//4  This method is called from selector. So it requires @objc keyword and this method will adjust your scrollView (here myScrollView  ?)  and textFields to show as original.

@objc func keyboardWillBeHidden(aNotification: NSNotification) {

     let contentInsets: UIEdgeInsets = .zero

     self.myScrollView.contentInset = contentInsets

     self.myScrollView.scrollIndicatorInsets = contentInsets


// Called when the UIKeyboardWillShow is sent

This method will adjust your scrollView
and will show textFields above the keyboard.
keyboardWillShow(aNotification: NSNotification) {

     var info = aNotification.userInfo!

     let kbSize: CGSize = ((info[“UIKeyboardFrameEndUserInfoKey”] as? CGRect)?.size)!

     print(“kbSize = \(kbSize)”)

     let contentInsets: UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0)

     myScrollView.contentInset = contentInsets

     myScrollView.scrollIndicatorInsets = contentInsets

     var aRect: CGRect = self.view.frame

     aRect.size.height -= kbSize.height

     if !aRect.contains(activeField!.frame.origin) {

          self.myScrollView.scrollRectToVisible(activeField!.frame, animated: true)



} // Class End

Alternative for xib in swift3 iOS

Hi all,

Lets see the simplest and best way to replace or avoid use of xib by using UIView on storyboard.


  1.  Go on storyboard ,select Viewcontroller Drag UIView and drop it between FirstResponder and exit button on that.
  2.  Add IBOutlet of that UIView on ViewController.swift file.
  3.  set the center, width, height for that UIView
  4.  Refer Following code :


——– IBOutlet ——–

@IBOutlet var View_alternativeForXib: UIView!

var view_BGDimmer = UIView()


——– Set the center , width, height for that UIView as well as add transperent Background view ———

 = (UIApplication.shared.keyWindow?.center)!

          view_BGDimmer.frame = (UIApplication.shared.keyWindow?.frame)!

         View_alternativeForXib.frame.size.width = (UIApplication.shared.keyWindow?.frame.width)! – 40

         View_alternativeForXib.frame.origin.x = (UIApplication.shared.keyWindow?.frame.origin.x)! + 20

          view_BGDimmer.backgroundColor =  colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)

          view_BGDimmer.alpha = 0.3


          UIApplication.shared.keyWindow?.insertSubview(self.View_alternativeForXib, aboveSubview: self.view_BGDimmer)

          UIView.animate(withDuration: 0.1, animations: {

          }) { (completed) in



——-  To dismiss view ——

   func dimissPopUp() {

        UIView.animate(withDuration: 0.2, animations: {

            self.view_BGDimmer.alpha = 0.0



        }) { (completed) in









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 BoolFloatDoubleIntString, 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


    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: UIColorUIImageUIViewUILabelUIImageViewUITableViewSKSpriteNode
    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


    name: String

       var image: String

    (name: String, image: String) {

    = 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() {


              let defaults = UserDefaults.standard

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

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


        @IBAction func barButton_addPersonTapped(_ sender: Any) {



        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

    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]

         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)



         dismiss(animated: true) {


  // Save newly added Image with name.


    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 … 🙂

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(“”)

yourImageView.image = image

Then you are done. Enjoy… 🙂


Need more help?

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