Post

Replies

Boosts

Views

Activity

Reply to Intermittent crash when presenting SwiftUI sheet with UIPagingViewController
Code continued... Focusable Text Field /**   Supports first responder and pageable state, so the keyboard only   shows after the page view has fully transitioned.  */ struct FocusablePageableTextField: UIViewRepresentable {   @Binding var text: String   var isFirstResponder: Bool = false   var placeholder: String = ""   var textAlignment: NSTextAlignment = .left   var autocapitalizationType: UITextAutocapitalizationType = .sentences   var keybaordType: UIKeyboardType = .default   var textContentType: UITextContentType? = nil   var autocorrectionType: UITextAutocorrectionType = .yes   var activePage: Int   @Binding var isPageChanging: Bool   @Binding var currPage: Int   @Binding var showSpinner: Bool   var onReturnCallback: () -> Void   var onButtonPressCallback: () -> Void       // Optional callback for when text field is updated   var onUpdateCallback: (() -> Void)? = nil       func makeUIView(context: UIViewRepresentableContext<FocusablePageableTextField>) -> UITextField {     let textField = UITextField(frame: .zero)     textField.placeholder = placeholder     textField.textAlignment = textAlignment     textField.autocapitalizationType = autocapitalizationType     textField.keyboardType = keybaordType     textField.textContentType = textContentType == nil ? .none : textContentType!     textField.autocorrectionType = autocorrectionType           // Prevents the textfield from growing when text exceeds its bounds     textField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)           // Style     textField.layer.cornerRadius = 20     textField.layer.borderWidth = 2     textField.layer.borderColor = ColorPalette.primaryTint.cgColor           textField.font = UIFont(name: Fonts.brandBold.uiktFont, size: UIScreen.main.bounds.height > 812 ? 18 : 14)     textField.textColor = ColorPalette.secondaryTint           textField.rightView = UIView()     textField.rightViewMode = .always     textField.rightView?.translatesAutoresizingMaskIntoConstraints = false     textField.rightView?.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.height > 568 ? 35 : 30).isActive = true     textField.addPadding(.left(UIScreen.main.bounds.height > 568 ? 35 : 30))           textField.rightView?.addSubview(context.coordinator.continueButton)     textField.rightView?.addConstraintsWithFormat(format: "H:|[v0]|", views: context.coordinator.continueButton)     textField.rightView?.addConstraintsWithFormat(format: "V:|[v0]|", views: context.coordinator.continueButton)           textField.delegate = context.coordinator     context.coordinator.continueButton.addTarget(context.coordinator, action: #selector(context.coordinator.buttonCallback), for: .touchUpInside)     return textField   }   func makeCoordinator() -> FocusablePageableTextField.Coordinator {     return Coordinator(self)   }   func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<FocusablePageableTextField>) {     uiView.text = text     DispatchQueue.main.async { self.onUpdateCallback?() }     if !isPageChanging && currPage == activePage && isFirstResponder && !context.coordinator.didBecomeFirstResponder {       DispatchQueue.main.async {         uiView.becomeFirstResponder()       }       context.coordinator.didBecomeFirstResponder = true     }     if isPageChanging {       uiView.endEditing(true)       context.coordinator.didBecomeFirstResponder = false     }   }       class Coordinator: NSObject, UITextFieldDelegate {     private let parent: FocusablePageableTextField     var didBecomeFirstResponder = false     init(_ parent: FocusablePageableTextField) {       self.parent = parent     }     func textFieldDidChangeSelection(_ textField: UITextField) {       DispatchQueue.main.async { [weak self] in         guard let self = self else { return }                   self.parent.text = textField.text ?? ""                 }     }           func textFieldShouldReturn(_ textField: UITextField) -> Bool {       parent.onReturnCallback()       return true     }           @objc func buttonCallback(sender: UIButton) {       parent.onButtonPressCallback()     }           // View components     let continueButton: UIButton = {       let button = UIButton(type: .custom)       button.setImage(UIImage(named: "Icon-Chevron-Blue"), for: .normal)       button.imageView?.contentMode = .scaleAspectFill       button.translatesAutoresizingMaskIntoConstraints = false               return button     }()   } } View containing Paging View (Presented by the Sheet) struct PagesView: View {        @State private var currPage = 0   @State private var pageDirection: UIPageViewController.NavigationDirection = .forward   @State private var isPageChanging = false         var body: some View {     VStack {       PageControlView(numberOfPages: 3, currentPage: $currPage) // UIPageControl       PageViewController(controllers: [         AnyView(SamplePageInputView(isPageChanging: $isPageChanging,                        currPage: $currPage,                        submitCallback: nextPage)),                   AnyView(SamplePageInputView(isPageChanging: $isPageChanging,                       currPage: $currPage,                       submitCallback: nextPage)),                   AnyView(SamplePageInputView(isPageChanging: $isPageChanging,                       currPage: $currPage,                       submitCallback: nextPage))]                   .map { UIHostingController(rootView: $0)},                 currPage: $currPage, pageDirection: $pageDirection, isPageChanging: $isPageChanging)     }   }       private func nextPage() {     if (!isPageChanging) {       pageDirection = .forward       currPage += 1       isPageChanging = true     }   }       private func previousPage() {     if (!isPageChanging) {       pageDirection = .reverse       currPage -= 1       isPageChanging = true     }   } }
Topic: UI Frameworks SubTopic: UIKit Tags:
Jun ’21