inputAccessoryView's background view is falling under its own textField and profile picture imageView.
It works fine on regular screen iPhones, but on new iPhones with notches it looks like this:
Here's how it looks animated when keyboard appears: Transition animation on becomeFirstResponder()
Here's my tableView in which I'm trying to add accessoryView:
import UIKit
import SDWebImage
class CommentsTableViewController: UITableViewController {
let viewModel = CommentsViewModel()
let postID: String
let postCaption: String
let postDate: Date
let postAuthor: ZoogramUser
var keyboardAccessoryView: CommentAccessoryView = {
let commentAccessoryView = CommentAccessoryView()
return commentAccessoryView
}()
init(post: UserPost) {
self.postID = post.postID
self.postCaption = post.caption
self.postDate = post.postedDate
self.postAuthor = post.author
super.init(style: .grouped)
self.tableView.register(PostCommentsTableViewCell.self, forCellReuseIdentifier: PostCommentsTableViewCell.identifier)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Comments"
keyboardAccessoryView.delegate = self
configureKeyboardAccessoryView()
viewModel.getComments(for: self.postID) {
self.tableView.reloadData()
}
tableView.backgroundColor = .systemBackground
tableView.keyboardDismissMode = .interactive
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 100
tableView.allowsSelection = false
tableView.separatorStyle = .none
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
becomeFirstResponder()
}
override var inputAccessoryView: UIView? {
keyboardAccessoryView.heightAnchor.constraint(greaterThanOrEqualToConstant: 60).isActive = true
keyboardAccessoryView.backgroundColor = .systemOrange
return keyboardAccessoryView
}
override var canBecomeFirstResponder: Bool {
return true
}
func configureKeyboardAccessoryView() {
guard let photoURL = AuthenticationManager.shared.getCurrentUserProfilePhotoURL() else {
return
}
keyboardAccessoryView.userProfilePicture.sd_setImage(with: photoURL)
}
}
And here's code for my CommentAccessoryView which I use to override inputAccessoryView:
import UIKit
protocol CommentAccessoryViewProtocol {
func postButtonTapped(commentText: String)
}
class CommentAccessoryView: UIView {
var delegate: CommentAccessoryViewProtocol?
var userProfilePicture: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
imageView.clipsToBounds = true
imageView.backgroundColor = .secondarySystemBackground
imageView.contentMode = .scaleAspectFill
return imageView
}()
var commentTextField: AccessoryViewTextField = {
let textField = AccessoryViewTextField()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.backgroundColor = .systemBackground
textField.placeholder = "Enter comment"
textField.clipsToBounds = true
textField.layer.borderWidth = 1
textField.layer.borderColor = UIColor.placeholderText.cgColor
return textField
}()
var postButton: UIButton = {
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.widthAnchor.constraint(equalToConstant: 30).isActive = true
button.heightAnchor.constraint(equalToConstant: 30).isActive = true
button.clipsToBounds = true
button.layer.cornerRadius = 30/2
button.setImage(UIImage(systemName: "arrow.up.circle.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 35)), for: .normal)
button.tintColor = .systemBlue
button.addTarget(self, action: #selector(didTapPostButton), for: .touchUpInside)
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupConstraints()
backgroundColor = .systemBackground
commentTextField.rightView = postButton
commentTextField.rightViewMode = .always
autoresizingMask = .flexibleHeight
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
setViewCornerRadius()
}
func setViewCornerRadius() {
userProfilePicture.layer.cornerRadius = userProfilePicture.frame.height / 2
commentTextField.layer.cornerRadius = commentTextField.frame.height / 2
}
func setupConstraints() {
self.addSubviews(userProfilePicture, commentTextField)
NSLayoutConstraint.activate([
userProfilePicture.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 10),
userProfilePicture.centerYAnchor.constraint(equalTo: self.safeAreaLayoutGuide.centerYAnchor),
userProfilePicture.widthAnchor.constraint(equalToConstant: 40),
userProfilePicture.heightAnchor.constraint(equalToConstant: 40),
commentTextField.leadingAnchor.constraint(equalTo: userProfilePicture.trailingAnchor, constant: 10),
commentTextField.centerYAnchor.constraint(equalTo: userProfilePicture.centerYAnchor),
commentTextField.heightAnchor.constraint(equalToConstant: 40),
commentTextField.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -10),
])
}
override var intrinsicContentSize: CGSize {
return CGSize.zero
}
@objc func didTapPostButton() {
guard let text = commentTextField.text else {
return
}
commentTextField.resignFirstResponder()
delegate?.postButtonTapped(commentText: text)
}
}
I've spent days trying to google a fix for that but nothing helps.
There were posts saying they were able to fix something similar by setting customView's bottom constraint to a safe area with the following method:
override func didMoveToWindow() {
if #available(iOS 11.0, *) {
if let window = window {
let bottomAnchor = bottomAnchor.constraint(lessThanOrEqualToSystemSpacingBelow: window.safeAreaLayoutGuide.bottomAnchor, multiplier: 1.0)
bottomAnchor.isActive = true
}
}
}
But when I use it, AutoLayout starts complaining.
UPDATE: I did what HangarRash recommended, changed CommentAccessoryView from UIView to UIInputView and centering profileImageView and textField to view itself and not to safe area. Now it's a little bit better, but seems to ignore safe area, inputAccessoryView should be above Home indicator but lies beneath it instead. Looking at last cell in TableView and Scroll indicator, it seems like TableView also isn't aware of inputAccessoryView and goes under it.

