无实体Home键iPhone的inputAccessoryView布局适配问题
无实体Home键iPhone上inputAccessoryView布局异常问题
问题描述
- 在无实体Home键的刘海屏iPhone上,自定义
inputAccessoryView的背景视图被自身的textField和头像ImageView遮挡,常规屏幕iPhone显示正常;同时键盘弹出时的过渡动画存在异常。 - 更新后遗留问题:将
CommentAccessoryView从UIView改为UIInputView,并将子视图居中到视图本身而非安全区域后,仍存在两个问题:inputAccessoryView未识别安全区域,被底部Home指示器遮挡;- UITableView内容被
inputAccessoryView遮挡。
相关代码
CommentsTableViewController代码
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) } }
CommentAccessoryView代码
import UIKit protocol CommentAccessoryViewProtocol { func postButtonTapped(commentText: String) } class CommentAccessoryView: UIInputView { var delegate: CommentAccessoryViewProtocol? var userProfilePicture: UIImageView = { let imageView = UIImageView() imageView.translatesAutoresizingMaskIntoConstraints = false imageView.contentMode = .scaleAspectFill imageView.clipsToBounds = true imageView.backgroundColor = .secondarySystemBackground 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, inputViewStyle: UIInputView.Style) { super.init(frame: frame, inputViewStyle: inputViewStyle) 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.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) } }
尝试过的无效代码
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 } } }
解决方案
1. 修复inputAccessoryView被Home指示器遮挡问题
- 调整子视图布局约束,将锚点从视图本身改为
safeAreaLayoutGuide,确保内容避开底部安全区域:
修改CommentAccessoryView的setupConstraints方法:func setupConstraints() { self.addSubviews(userProfilePicture, commentTextField) NSLayoutConstraint.activate([ // 头像约束 userProfilePicture.leadingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leadingAnchor, constant: 10), userProfilePicture.centerYAnchor.constraint(equalTo: self.safeAreaLayoutGuide.centerYAnchor), userProfilePicture.widthAnchor.constraint(equalToConstant: 40), userProfilePicture.heightAnchor.constraint(equalToConstant: 40), userProfilePicture.bottomAnchor.constraint(lessThanOrEqualTo: self.safeAreaLayoutGuide.bottomAnchor, constant: -8), // 输入框约束 commentTextField.leadingAnchor.constraint(equalTo: userProfilePicture.trailingAnchor, constant: 10), commentTextField.centerYAnchor.constraint(equalTo: userProfilePicture.centerYAnchor), commentTextField.heightAnchor.constraint(equalToConstant: 40), commentTextField.trailingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.trailingAnchor, constant: -10), commentTextField.bottomAnchor.constraint(lessThanOrEqualTo: self.safeAreaLayoutGuide.bottomAnchor, constant: -8), ]) } - 修正
intrinsicContentSize,让系统正确计算视图高度:override var intrinsicContentSize: CGSize { return CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric) }
2. 修复UITableView内容被遮挡问题
- 在
CommentsTableViewController的viewDidLoad中添加内边距自动适配设置:tableView.contentInsetAdjustmentBehavior = .always - 移除
inputAccessoryView重写中重复添加的约束,避免AutoLayout冲突:
将高度约束和背景色设置移到viewDidLoad中:override func viewDidLoad() { // ... 其他原有代码 keyboardAccessoryView.heightAnchor.constraint(greaterThanOrEqualToConstant: 60).isActive = true keyboardAccessoryView.backgroundColor = .systemOrange } override var inputAccessoryView: UIView? { return keyboardAccessoryView }
内容的提问来源于stack exchange,提问作者adseeAnn
相关产品推荐
相关产品推荐

