@@ -27,6 +27,8 @@ public class ModernSearchBar: UISearchBar, UISearchBarDelegate, UITableViewDataS
2727
2828 private var choice : Choice = . normal
2929
30+ private var keyboardHeight : CGFloat = 0
31+
3032 //MARKS: VIEWS
3133 private var suggestionsView : UITableView !
3234 private var suggestionsShadow : UIView !
@@ -43,17 +45,19 @@ public class ModernSearchBar: UISearchBar, UISearchBarDelegate, UITableViewDataS
4345 public var searchLabel_textColor : UIColor ?
4446 public var searchLabel_backgroundColor : UIColor ?
4547
46- public var suggestionsView_maxHeight : CGFloat = UIScreen . main . bounds . height . divided ( by : 2.5 )
48+ public var suggestionsView_maxHeight : CGFloat !
4749 public var suggestionsView_backgroundColor : UIColor ?
4850 public var suggestionsView_contentViewColor : UIColor ?
4951 public var suggestionsView_separatorStyle : UITableViewCellSeparatorStyle = . none
5052 public var suggestionsView_selectionStyle : UITableViewCellSelectionStyle = UITableViewCellSelectionStyle . none
51- public var suggestionsView_verticalSpaceWithSearchBar : CGFloat = 4
53+ public var suggestionsView_verticalSpaceWithSearchBar : CGFloat = 3
5254
5355 public var suggestionsView_searchIcon_height : CGFloat = 17
5456 public var suggestionsView_searchIcon_width : CGFloat = 17
5557 public var suggestionsView_searchIcon_isRound = true
5658
59+ public var suggestionsView_spaceWithKeyboard : CGFloat = 3
60+
5761
5862 //MARK: INITIALISERS
5963 required public init ( coder aDecoder: NSCoder ) {
@@ -76,6 +80,7 @@ public class ModernSearchBar: UISearchBar, UISearchBarDelegate, UITableViewDataS
7680 self . delegate = self
7781 self . isSuggestionsViewOpened = false
7882 self . interceptOrientationChange ( )
83+ self . interceptKeyboardChange ( )
7984 }
8085
8186 private func configureViews( ) {
@@ -153,6 +158,22 @@ public class ModernSearchBar: UISearchBar, UISearchBarDelegate, UITableViewDataS
153158 self . endEditing ( true )
154159 }
155160
161+ public func searchBarShouldEndEditing( _ searchBar: UISearchBar ) -> Bool {
162+ if let shouldEndEditing = self . delegateModernSearchBar? . searchBarShouldEndEditing ? ( searchBar) {
163+ return shouldEndEditing
164+ } else {
165+ return true
166+ }
167+ }
168+
169+ public func searchBarShouldBeginEditing( _ searchBar: UISearchBar ) -> Bool {
170+ if let shouldBeginEditing = self . delegateModernSearchBar? . searchBarShouldBeginEditing ? ( searchBar) {
171+ return shouldBeginEditing
172+ } else {
173+ return true
174+ }
175+ }
176+
156177
157178 // --------------------------------
158179 // ACTIONS
@@ -315,7 +336,7 @@ public class ModernSearchBar: UISearchBar, UISearchBarDelegate, UITableViewDataS
315336 }
316337
317338 private func closeSuggestionsView( ) {
318- if ( self . isSuggestionsViewOpened) {
339+ if ( self . isSuggestionsViewOpened == true ) {
319340 self . animationClosing ( )
320341 self . isSuggestionsViewOpened = false
321342 }
@@ -373,22 +394,37 @@ public class ModernSearchBar: UISearchBar, UISearchBarDelegate, UITableViewDataS
373394
374395 private func updateSizeSuggestionsView( ) {
375396 var frame : CGRect = self . suggestionsView. frame
376- frame. size. height = self . getMaxHeightSuggestionsView ( newHeight: self . suggestionsView. contentSize. height)
377- self . suggestionsView. frame = frame
378- UIView . animate ( withDuration: 0.0 ) {
397+ frame. size. height = self . getExactMaxHeightSuggestionsView ( newHeight: self . suggestionsView. contentSize. height)
398+
399+ UIView . animate ( withDuration: 0.3 ) {
400+ self . suggestionsView. frame = frame
379401 self . suggestionsView. layoutIfNeeded ( )
380402 self . suggestionsView. sizeToFit ( )
381403 }
382404 }
383405
384- private func getMaxHeightSuggestionsView( newHeight: CGFloat ) -> CGFloat {
385- if ( newHeight > self . suggestionsView_maxHeight) {
386- return self . suggestionsView_maxHeight
406+ private func getExactMaxHeightSuggestionsView( newHeight: CGFloat ) -> CGFloat {
407+ var estimatedMaxView : CGFloat !
408+ if self . suggestionsView_maxHeight != nil {
409+ estimatedMaxView = self . suggestionsView_maxHeight
410+ } else {
411+ estimatedMaxView = self . getEstimateHeightSuggestionsView ( )
412+ }
413+
414+ if ( newHeight > estimatedMaxView) {
415+ return estimatedMaxView
387416 } else {
388417 return newHeight
389418 }
390419 }
391420
421+ private func getEstimateHeightSuggestionsView( ) -> CGFloat {
422+ return self . getViewTopController ( ) . frame. height
423+ . subtracting ( self . getShadowY ( ) )
424+ . subtracting ( self . keyboardHeight)
425+ . subtracting ( self . suggestionsView_spaceWithKeyboard)
426+ }
427+
392428 // --------------------------------
393429 // UTILS
394430 // --------------------------------
@@ -400,6 +436,10 @@ public class ModernSearchBar: UISearchBar, UISearchBarDelegate, UITableViewDataS
400436 }
401437 }
402438
439+ private func getViewTopController( ) -> UIView {
440+ return self . getTopViewController ( ) !. view
441+ }
442+
403443 private func getTopViewController( ) -> UIViewController ? {
404444 var topController : UIViewController ? = UIApplication . shared. keyWindow? . rootViewController
405445 while topController? . presentedViewController != nil {
@@ -424,6 +464,10 @@ public class ModernSearchBar: UISearchBar, UISearchBarDelegate, UITableViewDataS
424464 return self . getEditText ( ) . superview!. convert ( self . getEditText ( ) . frame. origin, to: nil )
425465 }
426466
467+ // --------------------------------
468+ // OBSERVERS CHANGES
469+ // --------------------------------
470+
427471 private func interceptOrientationChange( ) {
428472 self . getEditText ( ) . addObserver ( self , forKeyPath: " frame " , options: NSKeyValueObservingOptions ( rawValue: 0 ) , context: nil )
429473 }
@@ -435,11 +479,31 @@ public class ModernSearchBar: UISearchBar, UISearchBarDelegate, UITableViewDataS
435479 }
436480 }
437481
482+ private func interceptKeyboardChange( ) {
483+ NotificationCenter . default. addObserver ( self , selector: #selector( keyboardWillShow ( notification: ) ) , name: NSNotification . Name. UIKeyboardWillShow, object: nil )
484+ NotificationCenter . default. addObserver ( self , selector: #selector( keyboardWillHide ( notification: ) ) , name: NSNotification . Name. UIKeyboardWillHide, object: nil )
485+ }
486+
487+ @objc private func keyboardWillShow( notification: NSNotification ) {
488+ let userInfo = notification. userInfo as! [ String : NSObject ] as NSDictionary
489+ let keyboardFrame = userInfo. value ( forKey: UIKeyboardFrameEndUserInfoKey) as! CGRect
490+ let keyboardHeight = keyboardFrame. height
491+
492+ self . keyboardHeight = keyboardHeight
493+ self . updateSizeSuggestionsView ( )
494+ }
495+
496+ @objc private func keyboardWillHide( notification: NSNotification ) {
497+ self . keyboardHeight = 0
498+ self . updateSizeSuggestionsView ( )
499+ }
500+
438501 // --------------------------------
439502 // PUBLIC ACCESS
440503 // --------------------------------
441504
442505 public func getSuggestionsView( ) -> UITableView {
443506 return self . suggestionsView
444507 }
508+
445509}
0 commit comments