The remote end hung up unexpectedly

Sometimes, we faced an annoying problem like this one while trying to clone my BitBucket Repo.

 git clone git@bitbucket.org:veda_the_ram/veda-ios.git
  Cloning into 'veda-ios'...
  remote: Counting objects: 1688, done.
  remote: Compressing objects: 100% (1272/1272), done.
  Connection to bitbucket.org closed by remote host.00 KiB/s
  fatal: The remote end hung up unexpectedly
  fatal: early EOF
  fatal: index-pack failed

Tried increasing the postBuffer size as suggested in different stack overFlow answers. But it did not work out for me. After some research, I found the solution.

  
  git config --global core.compression 9

changing the compression quality  did the trick. Hmm.. ??

Cool Animation In UITableView

Animation in iOS are the heart of the user experience. We can add cool animation with few lines of code. I would like to share a piece of UITableViewAnimation here.

ezgif-com-video-to-gif

After all the cells are displayed normally in table view. Create a simple function called AnimateTableView.

 
func animateTableView() {
        tableview.reloadData()
        let cells = tableview.visibleCells
        let tableHeight = tableview.bounds.size.height
        
        cells.forEach({
            $0.transform = CGAffineTransform(translationX: 0, y: tableHeight)
        })
        
        var delayCounter = 0
        
        cells.forEach { (cell) in
            UIView.animate(withDuration: 1.75, delay: (Double(delayCounter) * 0.05), usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .curveEaseOut, animations: {
                cell.transform = CGAffineTransform.identity
            }, completion: nil)
            delayCounter += 1
        }
    }

Just call that function in viewWillAppear or whereEver you want the show the animation.

cheers 

How to search for Crazy People…

Some times Its so much useful to have a search feature in our apps. It’s so much easy to search the table view in swift.

I have a basic project already setup which  a table view as a list of names.

Screen Shot 2016-12-19 at 8.23.14 PM.png

I have defined two outlets for UITextField and UITableView in my ViewController Class.

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var txtSearch: UITextField!
    @IBOutlet weak var tableView: UITableView!
    
    let names: [String] = [
        "Ccr", "Shishir", "Da ri",
        "Bibek", "Manoj", "Amrit",
        "An Gee", "Dee J", "Ajeet",
        "Ashik", "Be Nod", "Samina",
        "guru", "aarko guru", " aani guru ko dup"
    ]
    var searchText: String = ""
    
    var filterednames: [String]  {
        let searchText = self.searchText.lowercased()
        return names.filter({
            name in
                return searchText.isEmpty || name.lowercased().contains(searchText)
        }).sorted(by: { (name, _) -> Bool in
            return name.hasPrefix(searchText) ?? false
        })
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        txtSearch.addTarget(self,
                            action: #selector(ViewController.filter(sender:)),
                            for: UIControlEvents.editingChanged
        )
    }
    
    func filter(sender: UITextField) {
        searchText = sender.text!
        tableView.reloadData()
    }
}


extension ViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView,
                   numberOfRowsInSection section: Int) -> Int {
        return filterednames.count
    }
    
    func tableView(_ tableView: UITableView,
                   cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        let name = filterednames[indexPath.row]
        cell.set(name: name)  // see extension below.
        return cell
    }
}

extension UITableViewCell {
    func set(name: String) {
        self.textLabel?.text = name
    }
}

So, That’s how we find crazy people.

Choosing you default editor for git in unix system.

I used to love “nano” for a long time. But recently, I gave a try to vi and I am quite happy with it.

We can change our default editor in unix system with simple command.

git config --global core.editor "nano"   --> # if you love nano

git config --global core.editor "vim"   -->  # if you love vim

Presenting TransLucent Modal

POPUp view with a translucent background is simple way to add a cool effect on our app.

My storyBoard settings is show in this figure.

Its a simple view with little bit of opacity. Note that Alpha value is 0.8 and its backgroundColor is Black.

popUp view is simply just an another view.

screen-shot-2016-11-20-at-11-23-51-am

First grab that popUp viewController.

 let popUp = UIStoryboard.storyBoardWith(sbType: .ClubDetail).viewController() as RatingPopUp2

Then set the Modal presentation style. It defines how this modal should be presented.

 popUp.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext

Since I have  all viewControllers setup in a tabBarController, I want to present this view from the rootViewController, So that the tab bar settings remains behind this view.

So, I grab the RootViewcontroller and present this view from it.

 
let rootViewController = UIApplication.sharedApplication().keyWindow?.rootViewController
 rootViewController?.presentViewController(popUp, animated: true, completion: nil)

Result: 

A Sleek effect 🙂

bestresult

 

Find if user is using iPAD or iPhone in swift

Many times we have to know if user is on iPad and iPhone. The most simple example is showing alerts and actionSheet. ActionSheets are cool when you have a bunch of actions. But iPad doesn’t support ActionSheets. In such case we may show alerts in iPad and actionSheet in iPhone.

 

UIAlertControllerStyle determines how the alerts are shown.

var presentationStyle: UIAlertControllerStyle = .ActionSheet
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.Pad) {
            presentationStyle = .Alert
            // Looks like user is using iPad...
        }
        // now show alerts using presentationStyle. and forget what device user is using.

Rounding a double value to x number of decimal places in swift

A little extension I wrote in Swift to round off the numbers to required number of decimal places.

 
extension Double {
    func roundOff(precision: Double) -> Double {
        let multiplier = pow(10.0, precision)
        let y = Double(round(multiplier * self) / multiplier)  // round function takes decimal value and returns double without decimals. round(123.456) --> 123
        return y
        }
}

 

Usage:

 
let x = 123.456

x.roundOff(1)  --> 123.5

x.roundOff(2) --> 123.46

x.roundOff(2) --> 123.456

Add Done Button On UIDatePicker

Default UIDatePicker View has a default Done button when it is displayed. But It does not work by default.

screen-shot-2016-09-28-at-11-30-52-am

If you are using the textField delegate, It is simple. Ios provides us a delegate function that is called when Return key is pressed.

 
func textFieldShouldReturn(textField: UITextField) -> Bool {
    // done button clicked
}

But my requirement don’t allows us to use delegate, so I need another way.

So, we need to add an button. I will be adding button pragmatically but we can also use the storyboard.

I already have textField which shows datePicker when selected.

after setting up the textField and datePicker, a function is called to add the “Done” button.

 
    func setUpDoneButton() {
        let toolBar = UIToolbar()
        toolBar.barStyle = .Default
        toolBar.translucent = true
        
        let space = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: nil, action: nil)
        let doneButton = UIBarButtonItem(title: "Done", 
                                         style: .Done, 
                                         target: self, 
                                         action: #selector(doneDatePickerPressed(_:)))
        doneButton.tintColor = UIColor.blackColor()
        toolBar.setItems([space, doneButton], animated: false)
        toolBar.userInteractionEnabled = true
        toolBar.sizeToFit()
        addDoneButtonToDatePickers(toolBar)
    }

after setting up the button addDoneButtonToDatePickers function is called.

func addDoneButtonToDatePickers(doneButton: UIToolbar) {
        addDoneButtonToDatePickerView(txtStartDate, doneButton: doneButton)
        addDoneButtonToDatePickerView(txtEndDate, doneButton: doneButton)
        
    }
 
func addDoneButtonToDatePickerView(textField: UITextField, doneButton: UIToolbar) {
        textField.inputAccessoryView = doneButton
    }

When Done button is touched, doneDatePickerPressed function is called.

 
    func doneDatePickerPressed(sender: UIBarButtonItem) {
        print("done button clicked.")
        self.view.endEditing(true)
      }

Deleting Cell From UICollectionView

I have displayed images in UICollectionView. I have drag and drop feature added for the cell for this collectionView. Today, I will be adding functionality to delete the cell from the CollectionView when cross button is tapped.

Screen Shot 2016-08-24 at 10.53.25 AM

So, let’s begin.

The cell of collectionView have custom class called EnterCollectionViewCell

I will start by adding a closure variable called action.

 
   var action: (() -> ())?

Add @IBAction for the button in the EnterCollectionView

 
  class EnterCollectionViewCell: UICollectionViewCell {
    var action: (() -> ())?
    @IBOutlet weak var imgView: UIImageView!
    
    @IBAction func btnDeleteEnterImage(sender: UIButton) {
        action?()
    }
}

We will be assigning this closure to action variable in cellForItemAtIndexPath function.

 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = self.enterImageCollectionView.dequeueReusableCellWithReuseIdentifier("EnterCollectionViewCell", forIndexPath: indexPath) as! EnterCollectionViewCell
        cell.imgView.image = enterImages[indexPath.row]
            cell.action = {
                    self.enterImages.removeAtIndex(indexPath.row)
                let indexPath = self.enterImageCollectionView.indexPathForCell(cell)
                self.enterImageCollectionView.deleteItemsAtIndexPaths([indexPath!]) 
            }
            return cell
}

implementing drag and drop in UICollectionView

I have a UICollectionView that displays the images in its cell. I need to allow user to re-order the images.One sleek way to achieve this is using drag and drop.

From Ios 9 and above, Using Drag and Drop feature is rather easy than I thought.

Let’s start:

First add a collectionView in the storyboard. My UICollectionView name is enterImageCollectionView

Add a custom cell for this CollectionView. My custom cell has just an ImageView inside it.

In ViewController, I implemented the protocol UICollectionViewDelegate and  UICollectionViewDataSource.

Screen Shot 2016-08-23 at 4.29.45 PM

 

 

First add a UILongPressGestureRecognizer to the collectionView.

create an  @IBAction for this  UILongPressGestureRecognizer.

@IBAction func longPressedEnterCollectionView(sender: UILongPressGestureRecognizer) {
        switch(sender.state) {
        case UIGestureRecognizerState.Began:
            guard let selectedIndexPath = enterImageCollectionView.indexPathForItemAtPoint(sender.locationInView(self.enterImageCollectionView)) else {
                break
            }
            enterImageCollectionView.beginInteractiveMovementForItemAtIndexPath(selectedIndexPath)
        case UIGestureRecognizerState.Changed:
            enterImageCollectionView.updateInteractiveMovementTargetPosition(sender.locationInView(sender.view!))
        case UIGestureRecognizerState.Ended:
            enterImageCollectionView.endInteractiveMovement()
        default:
            enterImageCollectionView.cancelInteractiveMovement()
        }
    }

When user long press this gesture, the drag and drop feature begins.

When user drags the cell, gesture state is changed. And collectionView track the new position for the cell.

When user drops the cell, gesture state is ended. CollectionView ends the interactions.

We have a delegate function moveItemAtIndexPath for UICollectionView. Here we get the index of the element being removed and index where the removed element is to be placed.

 
extension MessageViewController: UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
        let element = enterImages.removeAtIndex(sourceIndexPath.row)
        enterImages.insert(element, atIndex: destinationIndexPath.row)
      }
    }

Here, enterImages is an array where number of images are saved.

Is that is?

Yes.  🙂