iOS 11 breaks row selection

591 views Asked by At

I've recently tested my app in iOS 11 and for some reason I'm not able to select one of the first 12 rows in a dynamically populated table view. The didSelectRow isn't even triggered for these rows. The other rows work fine, but even when scrolling down and back up (the cells should have been re-used again by then) the first 12 rows don't work.

Even on a static table view all cells that appear on screen when switching to that view controller will not respond, neither will controls inside them, even when they are in different sections. Cells that are out of screen initially again work fine.

I'll be trying to test this in an app with boilerplate code, but is this a known bug? I couldn't find anything online about it.

I've tested this after updating the devices to iOS 11, then again from Xcode 9 beta 6 without changes to the code, and again after migrating to Swift 4. Same behaviour inside the simulator. Up to iOS 10 everything is fine, only with iOS 11 the problem occurs.

This will break my app for users in two weeks, I need to fix it, so any help or advice very much appreciated!

UPDATE: As Paulw11 suggested, there is indeed another view blocking the rows. This was notable as row 12 could only be selected in the lower part of the cell, but not in the upper part.

The cause for this issue is the following code:

extension UIViewController {

  func setBackgroundImage(forTableView tableView: UITableView) {
    let bgImage = UIImage(named: "Background Image.png")

    let bgImageView = UIImageView(image: bgImage)
    tableView.backgroundView = bgImageView

    let rect = bgImageView.bounds
    let effect = UIBlurEffect(style: UIBlurEffectStyle.dark)
    let blurView = UIVisualEffectView(effect: effect)

    let height: CGFloat

    switch screenSize.height {
    case 480, 568: height = 455
    case 736:      height = 623
    default:       height = 554
    }

    blurView.frame = CGRect(x: 0, y: 0, width: rect.width, height: height)

    let container = UIView(frame: rect)
    bgImageView.addSubview(blurView)

    let bgOverlay = UIImage(named: "Background Overlay.png")
    let bgOverlayImageView = UIImageView(image: bgOverlay)
    bgOverlayImageView.alpha = 0.15
    bgImageView.addSubview(bgOverlayImageView)

    self.view.insertSubview(container, at: 1)

  }
}

Somehow since iOS 11 this background image seems to be rendered in front of the cells. Not inserting the container view into the table view's view will solve the issue. I've tried setting the zPosition of the container's layer but it does not help. How can I move the background image behind the cells again. It's weird that this behaviour would change from iOS 10 to 11...

UPDATE 2: Inserting the container at index -1 fixes the issue:

self.view.insertSubview(container, at: -1)

I don't get why this works, though, shouldn't this index be out of range?

UPDATE 3: As Paulw11 pointed out below, the container is completely useless, it was left over from testing and removing it fixes the issue.

1

There are 1 answers

0
Paulw11 On BEST ANSWER

The container view seems to be appearing in front of the other views and preventing touches from making it through to the table view.

As an aside, I would see if you can refactor this to use constraints; It always worries me when you see hard-coded screen sizes, as that may break when new devices are released.