0

I have a view controller with two elements: a UITableView and a UIView that contains a UITextField. I am also using the IQKeyboardManager library so that my UITextField is visible. Here is the code that controls them:

override func viewDidLoad() {
    super.viewDidLoad()
    self.hideKeyboardWhenTappedAround()
    tableView.register(UINib(nibName: "CommentCell", bundle: nil), forCellReuseIdentifier: "CommentCell")
    tableView.dataSource = self
    self.view.addSubview(tableView)
    commentTextField.delegate = self
    NotificationCenter.default.addObserver(self,
                                               selector: #selector(handle(keyboardShowNotification:)),
                                               name: UIResponder.keyboardDidShowNotification,
                                               object: nil)
    let textFieldHeight = commentCompositionView.frame.size.height
    let navBarHeight = navigationController?.navigationBar.frame.size.height ?? 0.0
    tableView.frame = CGRect(x: 0, y: keyboardHeight, width: screenSize.width, height: screenSize.height - (textFieldHeight + navBarHeight + keyboardHeight + 20))
    print("Did load: \(tableView.frame.size.height)")
}
    
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(true)
    commentTextField.becomeFirstResponder()
    print("Did Appear: \(tableView.frame.size.height)")
}
    
    
    
func textFieldDidBeginEditing(_ textField: UITextField) {
    let textFieldHeight = commentCompositionView.frame.size.height
    let navBarHeight = navigationController?.navigationBar.frame.size.height ?? 0.0
    tableView.frame = CGRect(x: 0, y: keyboardHeight, width: screenSize.width, height: screenSize.height - (textFieldHeight + navBarHeight + keyboardHeight + 20))
    print("Did begin: \(tableView.frame.size.height)")
}
    
func textFieldDidEndEditing(_ textField: UITextField) {
    let textFieldHeight = commentCompositionView.frame.size.height
    let navBarHeight = navigationController?.navigationBar.frame.size.height ?? 0.0
    tableView.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height - (textFieldHeight + navBarHeight + 20))
    print("Did end: \(tableView.frame.size.height)")
}

My problem is that when the view loads the UITableView's height is too large and I cannot see the top of the table view. When I click out of and then back into the UITableView it works just fine but the first load does not work.

here is a sample of output where the view loads, I click out of the UITextField and then click back into it:

Did load: 465.0
Did begin: 465.0
Did Appear: 465.0
Did end: 465.0
Did begin: 211.0
Did end: 465.0
Did begin: 211.0

It seems to me that given that I am setting the height in viewDidLoad that the first three print statements should instead be 211.0. What am I doing wrong?

Edit

I found what the issue is but am unsure of how to solve it. When the view first loads keyboardHeight is 0.0. It is not until I have closed and reopened the keyboard that it gives me an accurate number.

I am using this answer to get keyboardHeight

David
  • 769
  • 1
  • 6
  • 28
  • Have you tried implementing your layout code in `viewDidLayoutSubviews`? This is all likely caused by the view not correctly being layed out at the time you request the size – Bram Aug 13 '21 at 20:05
  • @Bram I just tried moving the line where I set `tableView.frame` from `viewDidLoad` to `viewDidLayoutSubviews` and I get the same result. – David Aug 13 '21 at 20:09
  • I also tried it in `viewWillLayoutSubviews`, same problem – David Aug 13 '21 at 20:11
  • @David how is your table view created? if it's in storyboard than you can't change frame of it, you need to setup your constraints – Phil Dukhov Aug 14 '21 at 06:29
  • @Philip my table view is created programmatically. I am able to change the size of it. The problem is that the size is not changing at the correct times. – David Aug 14 '21 at 13:18

1 Answers1

0

My problem was I needed to set the UITableView height in viewDidAppear once I did that my problem was solved:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(true)
    commentTextField.becomeFirstResponder()
    let textFieldHeight = commentCompositionView.frame.size.height
    let navBarHeight = navigationController?.navigationBar.frame.size.height ?? 0.0
    tableView.frame = CGRect(x: 0, y: keyboardHeight, width: screenSize.width, height: screenSize.height - (textFieldHeight + navBarHeight + keyboardHeight + 20))
}
David
  • 769
  • 1
  • 6
  • 28