简体   繁体   中英

UITextField inside XIB / NIB does not show Copy, Paste, etc. context menu

I want to use UITextFields inside of a UICollectionView and i have the problem that the textfields do not show a context menu. Normally outside of the collection view the textfields show a context menu when the user clicks / touches long inside of the textfield. Inside of the collection view the behaviour gets lost.

Here is my code in an simple example. ViewController.swift :

import UIKit

class ViewController: UIViewController {

    @IBOutlet var cv: UICollectionView!

    let string_array : [String] = [
        "test",
        "test2",
        "test3"
    ]

    var sizingTextFieldCell : TextFieldCell?
    var textfieldCellNib : UINib = UINib(nibName: "TextFieldCell", bundle: nil)

    override func viewDidLoad() {
        super.viewDidLoad()

        self.sizingTextFieldCell = (textfieldCellNib.instantiate(withOwner: nil, options: nil) as NSArray).firstObject as! TextFieldCell?

        self.cv.register(self.textfieldCellNib, forCellWithReuseIdentifier: "TextFieldCell")

        self.cv.delegate = self
        self.cv.dataSource = self
    }
}

// UICollectionView DataSource
extension ViewController : UICollectionViewDataSource
{
    // count of columns
    func numberOfSections(in collectionView: UICollectionView) -> Int
    {
        return 1
    }

    // count of cell items
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
        return string_array.count
    }

    // content of the cell items
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
        let form_element_index = indexPath.row    // index of the collectionView cell

        let cell : TextFieldCell = collectionView.dequeueReusableCell(withReuseIdentifier: "TextFieldCell", for: indexPath) as! TextFieldCell

        cell.textfield.text = string_array[form_element_index]

        return cell
    }
}

// UICollectionView DelegateFlowLayout
extension ViewController : UICollectionViewDelegateFlowLayout
{
    // wenn ich die funktion entferne haben alle elemente nur noch die minimalgröße
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let form_element_index = indexPath.row    // index of the collectionView cell

        self.sizingTextFieldCell!.textfield.text = string_array[form_element_index]

        return self.sizingTextFieldCell!.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
    }
}

TextFieldCell.swift :

import UIKit

class TextFieldCell: UICollectionViewCell, UITextFieldDelegate {

    @IBOutlet var textfield: UITextField!

    override func awakeFromNib()
    {
        self.textfield.textColor = UIColor(red: 0.1, green: 0.1, blue: 0.1, alpha: 1)           // black text color
        self.layer.cornerRadius = 5                                                                 // radius 4

        textfield.delegate = self as! UITextFieldDelegate
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        //super.touchesBegan(touches, with: event)
        self.textfield.becomeFirstResponder()
        //self.next?.touchesBegan(touches, with: event)
    }

    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool
    {
        return true
    }
}

Has anyone an idea what can be done to solve this problem? Thanks in advance!

UPDATE:

I downloaded the project provided by @cylov:

https://drive.google.com/file/d/0B1w1Ti0xMEZXaFo4RGJHUDAtTFU/view

I realised that the root view in the TextField.xib file provided by him is a UIView whereas it is supposed to be UICollectionView. This must have happened because of adding the xib file separately after adding TexField.xib. Making UIView behave as a UICollectionViewCell perhaps created an unexpected behaviour.

1st approach

When you add a new file (subclassing UICollectionViewCell), mark the checkbox saying: Also create xib

2nd approach

Another approach to the solution would have been to delete the root view present in xib file and drag drop a brand new UICollectionViewCell and start afresh. This definitely fixes the issue.

ANSWER THAT DID NOT WORK

  1. I tried following your code and figured out that the following dataSource method of UICollectionView was not getting called:

     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

Fixed this by replacing

return self.sizingTextFieldCell!.systemLayoutSizeFitting(UILayoutFittingCompressedSize)

with

return CGSize(width: 251.0, height: 50.0)
  1. Now later on I tried long tapping a text field on the collection view, I was able to get the context menu.

I am attaching screenshots related to the same. 在此输入图像描述

在此输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM