8

I have a search form that uses a tableview. After updating Xcode 12 today the UISwitch, UITextField, UISlider no longer work when nested inside a UITableViewCell. Is there a property that has changed that I need to set to make this work again?

To be sure it wasn't just my project, I created a new project and nestled a UITextField inside of it and it doesn't work either.

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = UITableViewCell()
    
    let textField = UITextField(frame: CGRect(x: 5, y: 5, width: 400.0, height: 25.0))
    textField.delegate = self
    textField.backgroundColor = .blue
    cell.addSubview(textField)

    return cell
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print("this will get called even when selecting the UITextField")
}

func textFieldDidBeginEditing(_ textField: UITextField) {
    print("this is never called")
}
Jason F
  • 309
  • 4
  • 11
  • 3
    As @matt correctly answered, you are mistakenly adding a custom view as a direct subview of the cell itself, instead of as a subview inside the cell's `contentView`. The reason that this causes an issue with Xcode 12 and iOS 14 is because the default cell `contentView` is now created lazily when the `contentView` property is first accessed, instead of being created in init, which means it can end up being added to the cell on top of your custom views (which shouldn't be subviews of the cell in the first place). You just need to update your code to `cell.contentView.addSubview(...)` instead. – smileyborg Sep 30 '20 at 23:36

3 Answers3

20

Your code was always wrong:

cell.addSubview(textField)

You must never add a subview to a cell. Add the subview to the cell's contentView.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • True! But I was working on an old project which had subview's added to tableview cell directly rather that to content view. I was alarmed once I build my project with Xcode 12, as the app became non responsive in many places. – chakkala Dec 14 '20 at 14:29
  • @Mot My guess is that, since contentView was introduced in iOS 2, it was always correct to add views to contentView instead of the cell itself, but that it was easier to get away with it in the past. – Eugene Dec 15 '20 at 19:51
  • Such a little detail but saved me from a lot of pain!! Kudos @matt! – christostsang Apr 09 '21 at 20:12
2

The same happened to me since I upgraded to iOS 14. This has worked for me when I add the subViews directly to the cell,

cell.contentView.isUserInteractionEnabled = true

Guille
  • 45
  • 3
  • 2
    Excellent catch, this was the issue for me. I guess the default behaviour changed for `contentView` interaction in iOS 14! – Avery Vine Sep 26 '20 at 23:57
  • 1
    But it's still better to not add subviews directly to the cell in the first place. – John Montgomery Oct 15 '20 at 17:05
  • I think it does not make sence. Do you want `cell.contentView.isUserInteractionEnabled = false` Because the Xcode 12 build app, make the contentView on the top, it can handle the touch event and make your other view can not get touch event. – Hugo Oct 20 '20 at 18:50
0

Had similar issue, and been going on around for it... what was issue with my code is that under UITableViewCell I was doing this:

        didSet {
            if contentView.backgroundColor == backgroundColor { return }
            contentView.backgroundColor = backgroundColor
            for v in otherView.subview { v.backgroundColor = backgroundColor }
        }

Removing this line here contentView.backgroundColor = backgroundColor did the trick. Cell is now visible and there is no duplicated contentView

Maybe this will help someone, since I found only answers regarding adding subviews directly to cell instead to cell.contentView

EDIT 1: Okay, just wanted to update you on situation, issue was that my subviews where of type UIStackView and I had used subview where I actually should have used arrangedSubviews

Hope this will help someone

Baki
  • 490
  • 4
  • 19