 	/**
 	Select a cell whose index is given one and move to it.
 
-	:param: item     An integer value which indicates the index of cell.
-	:param: animated True if the scrolling should be animated, false if it should be immediate.
+	:param: item              An integer value which indicates the index of cell.
+	:param: animated          True if the scrolling should be animated, false if it should be immediate.
 	*/
 	public func selectItem(_ item: Int, animated: Bool = false) {
-		self.selectItem(item, animated: animated, notifySelection: true)
+		self.selectItem(item, animated: animated, notifySelection: true, simulateSelection: false)
 	}
 
 	/**
 	Private. Select a cell whose index is given one and move to it, with specifying whether it calls delegate method.
 
-	:param: item            An integer value which indicates the index of cell.
-	:param: animated        True if the scrolling should be animated, false if it should be immediate.
-	:param: notifySelection True if the delegate method should be called, false if not.
-	*/
-	fileprivate func selectItem(_ item: Int, animated: Bool, notifySelection: Bool) {
-		self.collectionView.selectItem(
-			at: IndexPath(item: item, section: 0),
-			animated: animated,
-			scrollPosition: UICollectionViewScrollPosition())
-		self.scrollToItem(item, animated: animated)
-		self.selectedItem = item
-		if notifySelection {
-			self.delegate?.pickerView?(self, didSelectItem: item)
+	:param: item              An integer value which indicates the index of cell.
+	:param: animated          True if the scrolling should be animated, false if it should be immediate.
+	:param: notifySelection   True if the delegate method should be called, false if not.
+	:param: simulateSelection True if selection animation should be simulated (Selects the item but bounces back to previous one if item can't be selected)
+	*/
+	fileprivate func selectItem(_ item: Int, animated: Bool, notifySelection: Bool, simulateSelection: Bool) {
+		let selectedItem = self.delegate?.pickerView?(self, willSelectItem: item) ?? self.selectedItem
+		let previousSelectedItem = self.selectedItem
+		self.selectedItem = selectedItem
+
+		if self.simulateAnimation && simulateSelection && selectedItem != item {
+			self.simulatingScrollItem = item
+			self.collectionView.selectItem(
+				at: IndexPath(item: item, section: 0),
+				animated: animated,
+				scrollPosition: UICollectionViewScrollPosition())
+			self.scrollToItem(item, animated: animated)
+		} else {
+			self.simulatingScrollItem = nil
+			self.collectionView.selectItem(
+				at: IndexPath(item: selectedItem, section: 0),
+				animated: animated,
+				scrollPosition: UICollectionViewScrollPosition())
+			self.scrollToItem(selectedItem, animated: animated)
+			if notifySelection && (alwaysNotify || selectedItem != previousSelectedItem) {
+				self.delegate?.pickerView?(self, didSelectItem: selectedItem)
+			}
 		}
 	}
 


	// MARK: UICollectionViewDelegate
	public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
		self.selectItem(indexPath.item, animated: true)
	}

	// MARK: UIScrollViewDelegate

		self.collectionView.collectionViewLayout.invalidateLayout()
		self.collectionView.reloadData()
		if self.dataSource != nil && self.dataSource!.numberOfItemsInPickerView(self) > 0 {
			self.selectItem(0, animated: false, notifySelection: false, simulateSelection: true)
		}
	}

