@@ -14,7 +14,8 @@ import UIKit
1414#endif
1515
1616
17- public class TextField : SkyflowElement , Element , BaseElement , UITableViewDelegate , UITableViewDataSource {
17+
18+ public class TextField : SkyflowElement , Element , BaseElement {
1819 var onBeginEditing : ( ( ) -> Void ) ?
1920 var onEndEditing : ( ( ) -> Void ) ?
2021 var onFocusIsTrue : ( ( ) -> Void ) ?
@@ -39,14 +40,11 @@ public class TextField: SkyflowElement, Element, BaseElement, UITableViewDelegat
3940 internal var isErrorMessageShowing : Bool {
4041 return self . errorMessage. alpha == 1.0
4142 }
42- internal let tableViewContainer = UIView ( )
4343
44- internal let tableView = UITableView ( )
4544 internal var listCardTypes : [ CardType ] ?
46- internal var dropdownIcon = UIImageView ( )
47-
45+ internal var dropdownButton = UIButton ( )
4846 internal var selectedCardBrand : CardType ? = nil
49-
47+
5048 internal var uuid : String = " "
5149
5250 internal var textFieldCornerRadius : CGFloat {
@@ -252,7 +250,6 @@ public class TextField: SkyflowElement, Element, BaseElement, UITableViewDelegat
252250
253251 setupField ( )
254252 }
255- // new code
256253 public func update( updateOptions: CollectElementOptions ) {
257254 if ( updateOptions. cardMetaData != nil && self . fieldType == . CARD_NUMBER) {
258255 self . options. cardMetaData = updateOptions. cardMetaData
@@ -265,6 +262,9 @@ public class TextField: SkyflowElement, Element, BaseElement, UITableViewDelegat
265262 } else {
266263 for _ in schemes {
267264 listCardTypes = schemes
265+ if let cardTypes = listCardTypes, cardTypes. count >= 2 {
266+ getDropDownIcon ( )
267+ }
268268 }
269269 }
270270 let t = self . textField. secureText!. replacingOccurrences ( of: " - " , with: " " ) . replacingOccurrences ( of: " " , with: " " )
@@ -277,39 +277,6 @@ public class TextField: SkyflowElement, Element, BaseElement, UITableViewDelegat
277277 }
278278
279279 }
280- // MARK: - UITableViewDelegate and UITableViewDataSource
281- public func tableView( _ tableView: UITableView , numberOfRowsInSection section: Int ) -> Int {
282- return listCardTypes!. count
283- }
284-
285- public func tableView( _ tableView: UITableView , cellForRowAt indexPath: IndexPath ) -> UITableViewCell {
286- guard let cell = tableView. dequeueReusableCell ( withIdentifier: " CustomCell " , for: indexPath) as? CustomTableViewCell else {
287- return UITableViewCell ( )
288- }
289- let isSelected = listCardTypes ? [ indexPath. row] . instance. defaultName == selectedCardBrand? . instance. defaultName
290- cell. configure ( with: listCardTypes ? [ indexPath. row] . instance. defaultName ?? " not found " , isSelected: isSelected)
291- return cell
292- }
293-
294- public func tableView( _ tableView: UITableView , didSelectRowAt indexPath: IndexPath ) {
295- selectedCardBrand = listCardTypes ? [ indexPath. row]
296- let t = self . textField. secureText!. replacingOccurrences ( of: " - " , with: " " ) . replacingOccurrences ( of: " " , with: " " )
297- let card = CardType . forCardNumber ( cardNumber: t) . instance
298- updateImage ( name: selectedCardBrand? . instance. imageName ?? card. imageName, cardNumber: t)
299- onChangeHandler ? ( ( self . state as! StateforText ) . getStateForListener ( ) )
300- tableView. reloadData ( )
301- hideDropdown ( )
302- }
303- internal func getTopmostWindow( ) -> UIWindow ? {
304- if #available( iOS 13 . 0 , * ) {
305- return UIApplication . shared. connectedScenes
306- . compactMap { ( $0 as? UIWindowScene ) ? . windows. first ( where: { $0. isKeyWindow } ) }
307- . first
308- } else {
309- return UIApplication . shared. keyWindow
310- }
311- }
312- // new code till here
313280
314281 func updateStyle( _ source: Style ? , _ destination: inout Style ? ) {
315282 guard let newStyle = source else { return }
@@ -583,31 +550,32 @@ public class TextField: SkyflowElement, Element, BaseElement, UITableViewDelegat
583550 imageView. layer. borderWidth = self . collectInput!. iconStyles. base? . borderWidth ?? 0
584551 imageView. layer. cornerRadius = self . collectInput!. iconStyles. base? . cornerRadius ?? 0
585552
586- dropdownIcon. frame = CGRect ( x: imageView. frame. width + 7 , y: containerView. frame. height / 3 , width: 12 , height: 15 )
553+ // dropdownIcon.frame = CGRect(x: imageView.frame.width + 7, y: containerView.frame.height / 3, width: 12, height: 15)
587554
588555 if ( listCardTypes? . count == 0 || listCardTypes == nil ) {
589556 selectedCardBrand = nil
590- dropdownIcon . isHidden = true
591- dropdownIcon . removeFromSuperview ( )
557+ dropdownButton . isHidden = true
558+ dropdownButton . removeFromSuperview ( )
592559 imageView. center = containerView. center
593560 } else if ( listCardTypes != nil ) {
594561 if ( listCardTypes!. count >= 2 ) {
595- dropdownIcon. isHidden = false
596- getDropDownIcon ( )
597562 imageView. frame = CGRect ( x: 0 , y: 0 , width: 40 , height: 24 )
598- dropdownIcon. frame = CGRect ( x: 0 , y: 0 , width: 12 , height: 15 )
599- imageView. center = CGPoint ( x: containerView. frame. width / 2 - dropdownIcon. frame. width / 2 ,
600- y: containerView. frame. height / 2 )
601- dropdownIcon. center = CGPoint ( x: imageView. frame. maxX + dropdownIcon. frame. width / 2 + 7 ,
602- y: containerView. frame. height / 2 )
603- containerView. frame = CGRect ( x: 0 , y: 0 , width: max ( imageView. frame. maxX, dropdownIcon. frame. maxX) , height: 40 )
604- if ( cardIconAlignment == . left) {
605- textField. padding. left = 70
563+
564+ // uimenu code
565+ if #available( iOS 14 . 0 , * ) {
566+ if ( cardIconAlignment == . left) {
567+ textField. padding. left = 70
568+ }
569+ dropdownButton. frame = CGRect ( x: imageView. frame. maxX + 10 , y: ( containerView. frame. height / 2 ) - 5 , width: 12 , height: 15 )
570+ imageView. center = CGPoint ( x: containerView. frame. width / 2 - dropdownButton. frame. width / 2 ,
571+ y: containerView. frame. height / 2 )
572+ containerView. frame = CGRect ( x: 0 , y: 0 , width: max ( imageView. frame. maxX, dropdownButton. frame. maxX) , height: 40 )
573+ containerView. addSubview ( dropdownButton)
606574 }
607- containerView. addSubview ( dropdownIcon)
608575 } else {
609- dropdownIcon. isHidden = true
610- dropdownIcon. removeFromSuperview ( )
576+ if #available( iOS 14 . 0 , * ) {
577+ dropdownButton. isHidden = true
578+ }
611579 if ( cardIconAlignment == . left) {
612580 textField. padding. left = 60
613581 }
@@ -633,10 +601,10 @@ public class TextField: SkyflowElement, Element, BaseElement, UITableViewDelegat
633601 textField. leftViewMode = . always
634602 textField. leftView = cardIconContainerView
635603 } else {
636- if ( dropdownIcon . isHidden) {
604+ if ( dropdownButton . isHidden) {
637605 cardIconContainerView. frame = CGRect ( x: 0 , y: 0 , width: containerView. frame. width + 5 , height: 40 )
638606 } else {
639- cardIconContainerView. frame = CGRect ( x: 0 , y: 0 , width: containerView. frame. width + dropdownIcon . frame. width + 5 , height: 40 )
607+ cardIconContainerView. frame = CGRect ( x: 0 , y: 0 , width: containerView. frame. width + dropdownButton . frame. width + 5 , height: 40 )
640608 }
641609 textField. rightView = cardIconContainerView
642610 textField. rightViewMode = . always
@@ -646,80 +614,79 @@ public class TextField: SkyflowElement, Element, BaseElement, UITableViewDelegat
646614 }
647615
648616 private func getDropDownIcon( ) {
649- dropdownIcon. tintColor = . black
650- #if SWIFT_PACKAGE
651- dropdownIcon. image = UIImage ( named: " dropdown " , in: Bundle . module, compatibleWith: nil )
652- #else
653- let frameworkBundle = Bundle ( for: TextField . self)
654- var bundleURL = frameworkBundle. resourceURL
655- bundleURL!. appendPathComponent ( " Skyflow.bundle " )
656- let resourceBundle = Bundle ( url: bundleURL!)
657- dropdownIcon. image = UIImage ( named: " dropdown " , in: resourceBundle, compatibleWith: nil )
658- #endif
659- // dropdownIcon.image = UIImage(named: "Success-Icon")
660- dropdownIcon. layer. borderColor = UIColor . black. cgColor
661- dropdownIcon. isHidden = false
662- dropdownIcon. tintColor = . gray
663- let tapGesture = UITapGestureRecognizer ( target: self , action: #selector( dropdownButtonTapped) )
664- dropdownIcon. isUserInteractionEnabled = true
665- dropdownIcon. addGestureRecognizer ( tapGesture)
666- setupTableView ( )
617+ if #available( iOS 14 . 0 , * ) {
618+ setUpMenuView ( )
619+ dropdownButton. frame = CGRect ( x: 0 , y: 0 , width: 12 , height: 15 )
620+ #if SWIFT_PACKAGE
621+ dropdownButton. setImage ( UIImage ( named: " dropdown " , in: Bundle . module, compatibleWith: nil ) , for: . normal)
622+ #else
623+ let frameworkBundle = Bundle ( for: TextField . self)
624+ var bundleURL = frameworkBundle. resourceURL
625+ bundleURL!. appendPathComponent ( " Skyflow.bundle " )
626+ let resourceBundle = Bundle ( url: bundleURL!)
627+ dropdownButton. setImage ( UIImage ( named: " dropdown " , in: resourceBundle, compatibleWith: nil ) , for: . normal)
628+ #endif
629+ dropdownButton. isHidden = false
630+ dropdownButton. tintColor = . gray
631+ }
667632 }
668- internal func setupTableView( ) {
669- tableView. delegate = self
670- tableView. dataSource = self
671- tableView. register ( CustomTableViewCell . self, forCellReuseIdentifier: " CustomCell " )
672- tableView. isHidden = true
673- tableViewContainer. isHidden = true
674- tableView. layer. cornerRadius = 12
633+ @available ( iOS 14 . 0 , * )
634+ internal func setUpMenuView( ) {
635+ let actionClosure : ( UIAction ) -> Void = { [ weak self] action in
636+ guard let self = self else { return }
637+
638+ if let matchingCardType = CardType . allCases. first ( where: { $0. instance. defaultName == action. title } ) {
639+ self . selectedCardBrand = matchingCardType
640+ }
641+ if self . fieldType == . CARD_NUMBER {
642+ let t = self . textField. secureText!. replacingOccurrences ( of: " - " , with: " " ) . replacingOccurrences ( of: " " , with: " " )
643+ let card = CardType . forCardNumber ( cardNumber: t) . instance
644+ self . updateImage ( name: self . selectedCardBrand? . instance. imageName ?? card. imageName, cardNumber: t)
645+ self . onChangeHandler ? ( ( self . state as! StateforText ) . getStateForListener ( ) )
646+ }
647+
648+ self . updateMenuView ( )
649+ }
675650
676- tableViewContainer. frame = CGRect ( x: textField. frame. origin. x + 30 , y: textField. frame. maxY, width: 250 , height: 0 )
677- tableViewContainer. layer. cornerRadius = 12
678- tableViewContainer. layer. shadowColor = UIColor . black. cgColor
679- tableViewContainer. layer. shadowOffset = CGSize ( width: 0 , height: 4 )
680- tableViewContainer. layer. shadowOpacity = 0.5
681- tableViewContainer. layer. shadowRadius = 10
682- tableViewContainer. layer. masksToBounds = false
651+ var menuChildren : [ UIMenuElement ] = [ ]
683652
684- tableView. frame = CGRect ( x: 0 , y: 0 , width: 250 , height: 0 )
685- tableViewContainer. addSubview ( tableView)
686- }
687- @objc internal func dropdownButtonTapped( ) {
688- if tableViewContainer. isHidden {
689- showDropdown ( )
690- } else {
691- hideDropdown ( )
692- }
693- }
694- internal func hideDropdown( ) {
695- UIView . animate ( withDuration: 0.3 , animations: {
696- // self.tableView.frame.size.height = 0
697- self . tableViewContainer. frame. size. height = 0
698- } ) { _ in
699- self . tableView. isHidden = true
700- self . tableViewContainer. isHidden = true
653+ if let cardTypes = listCardTypes {
654+ for cardType in cardTypes {
655+ let state : UIMenuElement . State = ( cardType. instance. defaultName == selectedCardBrand? . instance. defaultName) ? . on : . off
656+ let action = UIAction ( title: cardType. instance. defaultName, state: state, handler: actionClosure)
657+ menuChildren. append ( action)
658+ }
701659 }
660+ let menu = UIMenu ( options: . displayInline, children: menuChildren)
661+ dropdownButton. menu = menu
662+ dropdownButton. showsMenuAsPrimaryAction = true
702663 }
703- internal func showDropdown( ) {
704- tableView. isHidden = false
705- tableViewContainer. isHidden = false
706-
707- guard let topWindow = getTopmostWindow ( ) else {
708- return
709- }
710-
711- if tableViewContainer. superview == nil {
712- topWindow. addSubview ( tableViewContainer)
713- }
714-
715- topWindow. bringSubviewToFront ( tableViewContainer)
716-
717- // Configure tableView frame and appearance
718- UIView . animate ( withDuration: 0.3 ) {
719- self . tableView. frame. size. height = CGFloat ( self . listCardTypes!. count * 51 )
720- self . tableViewContainer. frame. size. height = CGFloat ( self . listCardTypes!. count * 51 )
721- self . tableView. backgroundColor = . white
664+
665+ @available ( iOS 14 . 0 , * )
666+ internal func updateMenuView( ) {
667+ var updatedMenuChildren : [ UIMenuElement ] = [ ]
668+
669+ if let cardTypes = listCardTypes {
670+ for cardType in cardTypes {
671+ let state : UIMenuElement . State = ( cardType. instance. defaultName == selectedCardBrand? . instance. defaultName) ? . on : . off
672+ let action = UIAction ( title: cardType. instance. defaultName, state: state, handler: { [ weak self] action in
673+ guard let self = self else { return }
674+ if let matchingCardType = CardType . allCases. first ( where: { $0. instance. defaultName == action. title } ) {
675+ self . selectedCardBrand = matchingCardType
676+ }
677+ if self . fieldType == . CARD_NUMBER {
678+ let t = self . textField. secureText!. replacingOccurrences ( of: " - " , with: " " ) . replacingOccurrences ( of: " " , with: " " )
679+ let card = CardType . forCardNumber ( cardNumber: t) . instance
680+ self . updateImage ( name: self . selectedCardBrand? . instance. imageName ?? card. imageName, cardNumber: t)
681+ self . onChangeHandler ? ( ( self . state as! StateforText ) . getStateForListener ( ) )
682+ }
683+ self . updateMenuView ( )
684+ } )
685+ updatedMenuChildren. append ( action)
686+ }
722687 }
688+
689+ dropdownButton. menu = UIMenu ( options: . displayInline, children: updatedMenuChildren)
723690 }
724691
725692 override func validate( ) -> SkyflowValidationError {
@@ -824,6 +791,11 @@ extension TextField {
824791 var p = style? . padding ?? fallbackStyle? . padding ?? UIEdgeInsets ( top: 0 , left: 0 , bottom: 0 , right: 0 )
825792 if self . fieldType == . CARD_NUMBER, self . options. enableCardIcon, cardIconAlignment == . left {
826793 p. left = 60
794+ if ( listCardTypes != nil ) {
795+ if ( listCardTypes!. count >= 2 ) {
796+ p. left = 70
797+ }
798+ }
827799 }
828800
829801 if style? . width != nil {
0 commit comments