From 177d812795c441979f35a46a2a17ede9770cc3fc Mon Sep 17 00:00:00 2001 From: RyosukeCla Date: Fri, 22 Dec 2023 14:24:10 +0900 Subject: [PATCH] fix select input ui --- ios/Nativebrik/Nativebrik/forms.swift | 141 ++++++++------------------ ios/Nativebrik/Nativebrik/utils.swift | 13 +++ 2 files changed, 54 insertions(+), 100 deletions(-) diff --git a/ios/Nativebrik/Nativebrik/forms.swift b/ios/Nativebrik/Nativebrik/forms.swift index c3ccfff..d216dd7 100644 --- a/ios/Nativebrik/Nativebrik/forms.swift +++ b/ios/Nativebrik/Nativebrik/forms.swift @@ -10,68 +10,6 @@ import UIKit import YogaKit import TipKit -class SelectPickerViewController: UIViewController, UIPopoverPresentationControllerDelegate, UIPickerViewDelegate, UIPickerViewDataSource { - var options: [UISelectInputOption] = [] - var onSelected: (_ option: UISelectInputOption) -> Void = { _ in } - required init?(coder: NSCoder) { - super.init(coder: coder) - } - - init(options: [UISelectInputOption]?, onSelected: @escaping (_ option: UISelectInputOption) -> Void, source: UIView) { - super.init(nibName: nil, bundle: nil) - self.options = options ?? [] - self.onSelected = onSelected - self.preferredContentSize = CGSize(width: 200, height: 130) - self.modalPresentationStyle = .popover - self.popoverPresentationController?.sourceView = source - self.popoverPresentationController?.delegate = self - self.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection([.up, .down]) - } - - override func viewDidLoad() { - super.viewDidLoad() - self.view.backgroundColor = .systemBackground - let picker = UIPickerView(frame: CGRect(x: 0, y: 0, width: 200, height: 130)) - picker.delegate = self - picker.dataSource = self - - self.view.addSubview(picker) - } - - // UIPopoverPresentationControllerDelegate - func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle { - return .none - } - - // UIPickerViewDelegate - func numberOfComponents(in pickerView: UIPickerView) -> Int { - return 1 - } - - func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { - return options.count - } - - // UIPickerViewDataSource - func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { - if options.count < row { - return "None" - } - let option = options[row] - return option.label ?? option.value - } - // when a option is selected - func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { - if options.count < row { - let option = UISelectInputOption(value: "None", label: nil) - self.onSelected(option) - return - } - let option = options[row] - self.onSelected(option) - } -} - class TooltipViewController: UIViewController, UIPopoverPresentationControllerDelegate { var message: String? = "" init(message: String, source: UIView) { @@ -283,7 +221,7 @@ class TextInputView: UIView, UITextFieldDelegate { } } -class SelectInputView: UIControl, UIPickerViewDataSource { +class SelectInputView: UIControl { required init?(coder: NSCoder) { super.init(coder: coder) } @@ -296,62 +234,65 @@ class SelectInputView: UIControl, UIPickerViewDataSource { layout.isEnabled = true layout.width = YGValueUndefined layout.width = .init(value: 100.0, unit: .percent) - configurePadding(layout: layout, frame: block.data?.frame) layout.flexShrink = 1 } configureBorder(view: self, frame: block.data?.frame) - // input layout - let picker = UIPickerView(frame: .zero) - picker.configureLayout { layout in - layout.isEnabled = true - layout.width = .init(value: 100.0, unit: .percent) - configurePadding(layout: layout, frame: block.data?.frame) - } - picker.dataSource = self - - // text input layout - let label = UILabel(frame: .zero) - label.text = block.data?.value ?? "None" - label.configureLayout { layout in + let button = UIButton(frame: .zero) + button.setTitle(block.data?.value ?? "None", for: .application) + button.configureLayout { layout in layout.isEnabled = true } if let color = block.data?.color { - label.textColor = parseColor(color) + button.setTitleColor(parseColor(color), for: .normal) } else { - label.textColor = .label + button.setTitleColor(.label, for: .normal) + } + button.contentHorizontalAlignment = parseTextAlignToHorizontalAlignment(block.data?.textAlign) + + if #available(iOS 15.0, *) { + var config = UIButton.Configuration.plain() + let frame = block.data?.frame + config.contentInsets = .init( + top: CGFloat(frame?.paddingTop ?? 0), + leading: CGFloat(frame?.paddingLeft ?? 0), + bottom: CGFloat(frame?.paddingBottom ?? 0), + trailing: CGFloat(frame?.paddingRight ?? 0) + ) + var foregroundColor: UIColor = .label + if let color = block.data?.color { + foregroundColor = parseColor(color) + } + config.titleTextAttributesTransformer = .init({ _ in + return .init([ + .font: parseTextBlockDataToUIFont(block.data?.size, block.data?.weight, block.data?.design), + .foregroundColor: foregroundColor + ]) + }) + button.configuration = config } - label.font = parseTextBlockDataToUIFont(block.data?.size, block.data?.weight, block.data?.design) - label.numberOfLines = 0 if #available(iOS 14.0, *) { - self.addAction(.init { _ in - let picker = SelectPickerViewController(options: block.data?.options, onSelected: { option in - label.text = option.label ?? option.value - }, source: self) - self.window?.rootViewController?.present(picker, animated: true) - }, for: .touchDown) + let handleSelect = { (action: UIAction) in + // TODO: do something + } + let actions: [UIAction] = block.data?.options?.map({ option in + return UIAction(title: option.label ?? option.value ?? "None", state: .on, handler: handleSelect) + }) ?? [] + button.menu = UIMenu(children: actions) + button.showsMenuAsPrimaryAction = true + if #available(iOS 15.0, *) { + button.changesSelectionAsPrimaryAction = true + } } - self.addSubview(label) + self.addSubview(button) } deinit { - if self.window?.rootViewController?.presentedViewController is SelectPickerViewController { - self.window?.rootViewController?.dismiss(animated: true) - } } override func layoutSubviews() { super.layoutSubviews() } - - // UIPickerViewDataSource - func numberOfComponents(in pickerView: UIPickerView) -> Int { - return 1 - } - - func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { - return component - } } diff --git a/ios/Nativebrik/Nativebrik/utils.swift b/ios/Nativebrik/Nativebrik/utils.swift index e748b01..7f1bc53 100644 --- a/ios/Nativebrik/Nativebrik/utils.swift +++ b/ios/Nativebrik/Nativebrik/utils.swift @@ -189,6 +189,19 @@ func parseTextAlign(_ data: TextAlign?) -> NSTextAlignment { } } +func parseTextAlignToHorizontalAlignment(_ data: TextAlign?) -> UIControl.ContentHorizontalAlignment { + switch data { + case .LEFT: + return .left + case .CENTER: + return .center + case .RIGHT: + return .right + default: + return .left + } +} + func parserKeyboardType(_ data: UITextInputKeyboardType?) -> UIKeyboardType { switch data { case .ALPHABET: