HomeiOS Developmentios - How do I becomeFirstResponder in a UIContextMenuContentPreviewProvider

ios – How do I becomeFirstResponder in a UIContextMenuContentPreviewProvider


When making a UIContextMenuConfiguration for my assortment view, I set the preview supplier to be a customized UIViewController that accommodates a textField which turns into first responder on viewDidAppear.

Anticipated habits:
The keyboard exhibits up when the textfield is energetic

Precise habits:
The cursor blinks within the textfield however the keyboard by no means1 exhibits up.

  1. I’m able to get the keyboard to look whereas the context menu is energetic if I cycle foreground inactivate to foreground energetic (i.e. go Residence by swiping up after which come again into the app) https://i.imgur.com/FYKtyFD.mp4.

I attempted listening to UIResponder’s keyboard(Will|Did)(Present|Conceal)Notifications and setting a breakpoint inside them throughout foreground activation however it did not actually assist.

Here is the code I used to arrange the demo within the video (https://i.imgur.com/FYKtyFD.mp4).

import UIKit

class WordCell: UICollectionViewCell {
  static let textAttributes: [NSAttributedString.Key: Any] = [.font: UIFont.systemFont(ofSize: 24)]
  let label = UILabel(body: .zero)

  override init(body: CGRect) {
    tremendous.init(body: body)
    backgroundColor = .clear
    addSubview(label)
  }

  override func layoutSubviews() {
    tremendous.layoutSubviews()
    label.body = bounds
  }

  required init?(coder _: NSCoder) {
    fatalError("init(coder:) has not been carried out")
  }

  func setup(with phrase: String) {
    label.attributedText = NSMutableAttributedString(string: phrase, attributes: Self.textAttributes)
  }
}

class PreviewViewController: UIViewController {
  let textField = UITextField(body: .zero)
  let textual content: String

  init(_ textual content: String) {
    self.textual content = textual content
    tremendous.init(nibName: nil, bundle: nil)
  }

  required init?(coder _: NSCoder) {
    fatalError("init(coder:) has not been carried out")
  }

  override func viewDidLoad() {
    tremendous.viewDidLoad()
    let measurement = NSAttributedString(string: textual content).measurement()
    preferredContentSize = measurement.making use of(CGAffineTransform(scaleX: 2, y: 2))
    textField.textual content = textual content
    textField.textAlignment = .middle
    view.addSubview(textField)
  }

  override func viewDidLayoutSubviews() {
    tremendous.viewDidLayoutSubviews()
    textField.body = view.bounds
  }

  override func viewDidAppear(_ animated: Bool) {
    tremendous.viewDidAppear(animated)
    textField.becomeFirstResponder()
  }
}

class ViewController: UIViewController {
  let dataSource = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.".elements(separatedBy: .whitespaces)
  var collectionView: UICollectionView!

  override func viewDidLoad() {
    tremendous.viewDidLoad()
    collectionView = UICollectionView(body: .zero, collectionViewLayout: UICollectionViewFlowLayout())
    collectionView.dataSource = self
    collectionView.delegate = self
    collectionView.register(WordCell.self, forCellWithReuseIdentifier: "cell")
    view.addSubview(collectionView)
  }

  override func viewDidLayoutSubviews() {
    tremendous.viewDidLayoutSubviews()
    collectionView.body = view.bounds
  }
}

extension ViewController: UICollectionViewDelegate {
  func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemsAt indexPaths: [IndexPath], level: CGPoint) -> UIContextMenuConfiguration? {
    guard let offset = indexPaths.first?.merchandise else { return nil }

    let phrase = dataSource[offset]
    let configuration = UIContextMenuConfiguration(identifier: nil) {
      return PreviewViewController(phrase)
    } actionProvider: { _ in
      return UIMenu(kids: [
        UIAction(title: "No op") { _ in
          print(#function)
        }
      ])
    }

    return configuration
  }
}

extension ViewController: UICollectionViewDataSource {
  func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection part: Int) -> Int {
    dataSource.rely
  }

  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! WordCell
    cell.setup(with: dataSource[indexPath.item])
    return cell
  }
}

extension ViewController: UICollectionViewDelegateFlowLayout {
  func collectionView(_ collectionView: UICollectionView, structure collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let phrase = dataSource[indexPath.item]
    let attributedText = NSAttributedString(string: phrase, attributes: WordCell.textAttributes)
    let textSize = attributedText.measurement()
    let width = textSize.width + 2
    return CGSize(width: width, peak: 44)
  }
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments