title: Swift - Characters in text field are not visible
body: <p>In my application I have several custom designed games to practice spelling and grammar. The whole process was working just fine until iOS 11 released.</p>
  
  <p><strong>An overview of how my application works:</strong></p>
  
  <ul>
  <li>the game receives a random word and picture from our server and automatically creates a stack of text fields (in a horizontal stack view)</li>
  <li>the amount of text fields is similar to the amount of letters of the received word (e.g. the word "throw" would create five text fields next to each other)</li>
  <li>the view is linked to a custom keyboard that is displayed until all questions are answered correctly</li>
  <li>the text fields reset themselves if the user's input is not similar to the expected answer</li>
  </ul>
  
  <p><strong>The problem since iOS 11</strong></p>
  
  <p>Only the first two questions don't show the user's input in their respective text fields (the first letter always seem to work). The console also confirms that the input and the comparison of the letters does indeed work, but the text fields stay empty all the time. The game even resets perfectly and goes to the next question if the word has been answered correctly. <strong>The weird thing is that question 3, 4 and 5 do not have this problem.</strong></p>
  
  <p>In the example below you can see what is going on. The first question ("plant") only shows the first letter. The second question ("clap") does the same thing. The third question ("bite") does not have this problem. My custom cursor works just fine and automatically jumps to the next box.</p>
  
  <p><a href="https://i.stack.imgur.com/LEBPY.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/LEBPY.png" alt="The first three questions"></a></p>
  
  <p><strong>Swift Code (functionality only)</strong></p>
  
  <pre><code>let TEXT_FIELD_TAG = 1000
  let CURSOR_INDEX = 0
  
  var game: GameDictionary? {
      didSet {
  
          self.m_Client.GetMediaImage(game?.Image) { (image) in
              self.imageView.image = image
          }
  
          self.selectedIndex = 0
          self.answerChars = (game?.Content?.map { String($0).lowercased() })!
          self.views = (0..&lt;self.answerChars.count).map { _ in UITextField() }
  
          var index: NSInteger = TEXT_FIELD_TAG
  
          for textField in self.views {
              textField.backgroundColor = .white
              textField.textColor = Constants.MAIN_THEME_COLOR
              textField.font = UIFont(name: Constants.GAME_FONT_TYPE_1, size: scaledFontSize(fontSize: 36))
              textField.textAlignment = .center
              textField.delegate = self
              textField.layer.cornerRadius = 10
              textField.autocapitalizationType = .none
              textField.tag = index
              textField.isUserInteractionEnabled = true
  
              // Create the cursor object and animate the blinking
              let cursor = UIView(frame: CGRect(x: scaledViewSize(viewSize: 10), y: scaledViewSize(viewSize: 10), width: 2, height: scaledViewSize(viewSize: 30)))
              cursor.backgroundColor = Constants.MAIN_THEME_COLOR
              cursor.isHidden = true
  
              UIView.animate(withDuration: 1, delay: 0, options: .repeat, animations: {() -&gt; Void in
                  cursor.alpha = 0
              }, completion: {(_ animated: Bool) -&gt; Void in
                  cursor.alpha = 1
                  }
              )
  
              textField.addSubview(cursor)
              self.container.addArrangedSubview(textField)
  
              index+=1
          }
      }
  }
  
  // MARK: Question handlers
  override func prepareForReuse() {
      super.prepareForReuse()
  
      inputArray.removeAll()
      answerChars.removeAll()
  
      self.selectedIndex = 0
  
      for view in self.views {
          view.removeFromSuperview()
      }
  
      self.views.removeAll()
  }
  
  override func onFocus() {
      self.resetCursorTextField()
  
      keyboardLauncher.onKeyPressed = { character in
          self.views[self.selectedIndex].text = character
          self.textChanged(sender: self.views[self.selectedIndex])
      }
  
      keyboardLauncher.showKeyboard()
      keyboardLauncher.enableKeyboard()
  }
  
  func resetCursorTextField() {
      for (index, textfield) in self.views.enumerated() {
          textfield.subviews[CURSOR_INDEX].isHidden = (index == 0) ? false : true
      }
  }
  
  func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -&gt; Bool {
      guard let text = textField.text else { return true }
      let newLength = text.count + string.count - range.length
      return newLength &lt;= 1
  }
  
  func textFieldShouldBeginEditing(_ textField: UITextField) -&gt; Bool {
      return false
  }
  
  func resetInputViews() {
      inputArray.removeAll()
  
      self.selectedIndex = 0
      self.resetCursorTextField()
  
      for tag in TEXT_FIELD_TAG...(TEXT_FIELD_TAG + (self.answerChars.count) - 1) {
          let textField = self.container.viewWithTag(tag) as! UITextField!
          textField?.text = ""
  
          if (tag == TEXT_FIELD_TAG) {
              textField?.becomeFirstResponder()
          }
      }
  }
  
  func textChanged(sender: UITextField) {
      if (sender.text?.count)! &gt; 0 {
          inputArray.append((sender.text?.lowercased())!)
  
          if self.answerChars[self.selectedIndex] != inputArray.last! {
              self.delegate?.updateAnswer(inputArray.joined(), false)
              self.resetInputViews()
  
          } else {
              self.selectedIndex+=1
  
              let nextField = sender.superview?.viewWithTag(sender.tag + 1) as! UITextField!
              nextField?.becomeFirstResponder()
  
              sender.subviews[CURSOR_INDEX].isHidden = true
              nextField?.subviews[CURSOR_INDEX].isHidden = false
  
              if self.answerChars.count == inputArray.count {
                  playCorrectAnswer()
                  isCompleted = true
  
                  keyboardLauncher.disableKeyboard()
  
                  self.textField?.isEnabled = false
                  self.delegate?.updateAnswer(inputArray.joined(), true)
                  self.delegate?.nextQuestion(self)
              }
          }
      }
  }
  </code></pre>
  
  <p><strong>CellForItemAtIndexpath</strong></p>
  
  <pre><code>func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -&gt; UICollectionViewCell {
      if indexPath.item == self.m_Collection?.count {
          let cell = collectionView.dequeueReusableCell(withReuseIdentifier: gameScoreOverviewCell, for: indexPath) as! GameScoreOverviewCell
          cell.closeViewButton.addTarget(self, action: #selector(closeView(sender:)), for: .touchUpInside)
          cell.rulesButton.addTarget(self, action: #selector(handleAlertScoreOverview(sender:)), for: .touchUpInside)
  
          return cell
      }
  
      let game = self.m_Collection![indexPath.item]
  
      if game.StarryGrade == StarryGrade.Grade4 &amp;&amp; game.Level == Level.Level1 {
  
          let cell = collectionView.dequeueReusableCell(withReuseIdentifier: fourthGradeCellLevel1, for: indexPath) as! GameCellFourthGradeLevel1
          cell.cancelButton.addTarget(self, action: #selector(closeViewWithAlert(sender:)), for: .touchUpInside)
          cell.questionLabel.text = "Question \(indexPath.item + 1) of \(self.m_Collection!.count)"
          cell.game = game
          cell.delegate = self
  
          keyBoardIsVisible = true
  
          return cell  
      } 
  }
  </code></pre>