       return
     }
     
-    if !scrollView.bounds.contains(v.frame) {
-      let contentOffsetX = (v.frame.origin.x < scrollView.bounds.minX) ? v.frame.origin.x : v.frame.maxX - scrollView.bounds.width
-      let normalizedOffsetX = min(max(contentOffsetX, 0), scrollView.contentSize.width - scrollView.bounds.width)
+    let contentOffsetX: CGFloat? = {
+      let shouldScroll = !scrollView.bounds.contains(v.frame)
+      
+      switch tabBarCenteringStyle {
+      case .whenNeeded:
+        guard shouldScroll else {
+          return nil
+        }
+        fallthrough
+      case .always:
+        return v.center.x - bounds.width / 2
+      case .never:
+        guard shouldScroll else {
+          return nil
+        }
+        return v.frame.origin.x < scrollView.bounds.minX ? v.frame.origin.x : v.frame.maxX - scrollView.bounds.width
+      }
+    }()
+    
+    if let x = contentOffsetX {
+      let normalizedOffsetX = min(max(x, 0), scrollView.contentSize.width - scrollView.bounds.width)
       scrollView.setContentOffset(CGPoint(x: normalizedOffsetX, y: 0), animated: true)
     }
   }

  case scrollable
}

open class TabBar: Bar {
  /// A dictionary of TabItemLineStates to UIColors for the line.
  fileprivate var lineColorForState = [TabItemLineState: UIColor]()

  
  /// An enum that determines the tab bar style.
  open var tabBarStyle = TabBarStyle.auto {
    didSet {
      layoutSubviews()
    }
  }

  /// An enum that determines the tab bar centering style.
  open var tabBarCenteringStyle = TabBarCenteringStyle.never {
    didSet {
      layoutSubviews()
    }
