Layout UIButtonBarButton布局在iPad而非iPhone上输入UITextView时出现警告

Layout UIButtonBarButton布局在iPad而非iPhone上输入UITextView时出现警告,layout,uikit,uitextview,swift5,Layout,Uikit,Uitextview,Swift5,我有一个简单的反馈表单,它是TabBarController中两个ViewController之一。没有故事板,所有编程用户界面(UIKit),通用应用程序。在iPad上输入textView时,控制台会抛出布局警告: "<NSAutoresizingMaskLayoutConstraint:0x2808aa5d0 h=--& v=--& _UIButtonBarButton:0x129e8c6d0.height == 0 (active)>&qu

我有一个简单的反馈表单,它是TabBarController中两个ViewController之一。没有故事板,所有编程用户界面(UIKit),通用应用程序。在iPad上输入textView时,控制台会抛出布局警告:

    "<NSAutoresizingMaskLayoutConstraint:0x2808aa5d0 h=--& v=--& _UIButtonBarButton:0x129e8c6d0.height == 0   (active)>",
    "<NSLayoutConstraint:0x2808a9d60 V:|-(6)-[_UIUCBKBSelectionBackground:0x129e8d4e0]   (active, names: '|':_UIButtonBarButton:0x129e8c6d0 )>",
    "<NSLayoutConstraint:0x2808a9e00 _UIUCBKBSelectionBackground:0x129e8d4e0.bottom == _UIButtonBarButton:0x129e8c6d0.bottom - 6   (active)>"
“”,
"",
""
这不会发生在iPhone上。除此之外,该表单工作正常。我不知道这是从哪里来的,也不知道如何解决。任何提示,谢谢

更新;现在,在输入时,我的所有文本视图和文本字段上都会显示此信息。14.2事件

视图控制器代码:

import UIKit
import MessageUI

struct MailOption {
    let url: URL!
    let titel: String
}

class FeedbackViewController: UIViewController, MFMailComposeViewControllerDelegate ,UINavigationControllerDelegate {
    //MARK: - Properties
    let logoImageView = ProjectImageView(frame: .zero)
    let appVersionLabel = ProjectTitleLabel(withTextAlignment: .center, andFont: UIFont.preferredFont(forTextStyle: .title3), andColor: .label, numberOfLines: 2)
    let developerLabel = ProjectTitleLabel(withTextAlignment: .center, andFont: UIFont.preferredFont(forTextStyle: .footnote), andColor: .tertiarySystemBackground, numberOfLines: 1)
    let feedbackTextView = ProjectTextView()
    let spacerView = UIView()
    let sendButton = ProjectButton(withBackgroundColor: .systemOrange, andTitle: "Send")
    
    var feedbackTextViewPlaceholder = ProjectTextViewPlaceholderTextFor.feedback
    
    let emailTo = ProjectEmailAddresses.g
    var emailBody = ""
    let emailSubject = "Feedback on \(Bundle.main.displayName ?? "Unknown"), version \(Bundle.main.version ?? "")"

    //MARK: - ViewController Methods
    override func viewDidLoad() {
        super.viewDidLoad()
        
        configureViewController()
        configureView()
        configureAppVersionLabel()
        configureFeedbackTextView()
        configureSendButton()
    }

    //MARK: - Actions
    @objc private func endEditing() {
        view.endEditing(true)
    }
    
    @objc func adjustForKeyboard(notification: Notification) {
        //Reset to origin position
        self.view.frame.origin.y = 0
        
        if notification.name.rawValue == "UIKeyboardWillChangeFrameNotification" {
            if feedbackTextView.isFirstResponder {
                self.view.frame.origin.y -= feedbackTextView.frame.origin.y + 10
            } 
        } else {
            self.view.frame.origin.y = 0
        }
    }
    
    @objc private func sendButtonTapped() {
        //Extra check on feedback being present
        guard let feedback = feedbackTextView.text, feedback.isNotEmpty else { return }

        emailBody = feedback
        let subjectEncoded = emailSubject.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
        let bodyEncoded = emailBody.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!

        let gMail = MailOption(url: URL(string: "googlegmail://co?to=\(emailTo)&subject=\(subjectEncoded)&body=\(bodyEncoded)"), titel: "GMail")
        let outlook = MailOption(url: URL(string: "ms-outlook://compose?to=\(emailTo)&subject=\(subjectEncoded)&body=\(bodyEncoded)"), titel: "Outlook")
        let spark = MailOption(url: URL(string: "readdle-spark://compose?recipient=\(emailTo)&subject=\(subjectEncoded)&body=\(bodyEncoded)"), titel: "Spark")
        
        let availableUrls = [gMail, outlook, spark].filter { (mailOption) -> Bool in
            return mailOption.url != nil && UIApplication.shared.canOpenURL(mailOption.url)
        }

        showEmailOptions(for: availableUrls)
    }

    //MARK: - Mail functionality
    func showEmailOptions(for mailOptions: [MailOption]) {
        //Create action sheet
        let ac = UIAlertController(title: "Choose your preferred method of sending mail", message: nil, preferredStyle: .actionSheet)
        
        //Add Apple Mail action if that is available
        if MFMailComposeViewController.canSendMail() {
            ac.addAction(UIAlertAction(title: "Apple Mail", style: .default, handler: { (_) in
                self.sendAppleMail()
            }))
        }
        
        //Add other available actions
        for option in mailOptions {
            ac.addAction(UIAlertAction(title: option.titel, style: .default, handler: { (_) in
                UIApplication.shared.open(option.url, options: [:], completionHandler: { _ in
                    self.showSuccess()
                })
            }))
        }
        
        //Cancel action
        ac.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
        
        //Needed for iPads
        if UIDevice.current.userInterfaceIdiom == .pad {
            ac.popoverPresentationController?.sourceView = sendButton
            ac.popoverPresentationController?.permittedArrowDirections = [.down, .up]
        }
        
        present(ac, animated: true)
    }
    
    func sendAppleMail() {
        //we already checked for availability of the Mail App!
        let composer = MFMailComposeViewController()
        
        composer.mailComposeDelegate = self
        composer.setToRecipients([emailTo])
        composer.setSubject(emailSubject)
        composer.setMessageBody(emailBody, isHTML: false)
        
        present(composer, animated: true)
    }
    
    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        if result == .sent {
            self.showSuccess()
        }
        
        controller.dismiss(animated: true)
    }
    
    private func showSuccess() {
        self.presentProjectAlertOnMainThread(withTitle: "Feedback sent!", andMessage: "Thank you for your input!", andDismissButtonTitle: "OK", andConfirmButtonTitle: nil, completion: { _ in
            self.feedbackTextView.text = ""
            self.sendButton.isEnabled = false
        })
    }
    
    //MARK: - UI & Layout
    private func configureViewController() {
        feedbackTextView.delegate = self
        
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(endEditing)))
        
        let notificationCenter = NotificationCenter.default
        notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil)
        notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
    }
    
    private func configureView() {
        let padding: CGFloat = 20
        
        logoImageView.layer.cornerRadius = 5
        logoImageView.contentMode = .scaleAspectFit

        appVersionLabel.setContentHuggingPriority(.required, for: .vertical)
        developerLabel.setContentHuggingPriority(.required, for: .vertical)
        
        spacerView.translatesAutoresizingMaskIntoConstraints = false
        
        let seperator = Separator(frame: .zero)
        
        let stackView = UIStackView(arrangedSubviews: [logoImageView, appVersionLabel, developerLabel, seperator, feedbackTextView, spacerView, sendButton])
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical
        stackView.alignment = .center
        stackView.spacing = 10
        stackView.distribution = .fill
        
        view.addSubview(stackView)
        
        NSLayoutConstraint.activate([
            stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: padding),
            stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            stackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -padding),
            
            logoImageView.heightAnchor.constraint(equalToConstant: 88),
            logoImageView.widthAnchor.constraint(equalTo: logoImageView.heightAnchor),
            logoImageView.centerXAnchor.constraint(equalTo: stackView.centerXAnchor),
            
            seperator.leadingAnchor.constraint(equalTo: stackView.leadingAnchor, constant: padding),
            seperator.trailingAnchor.constraint(equalTo: stackView.trailingAnchor, constant: -padding),
            
            feedbackTextView.widthAnchor.constraint(equalTo: stackView.widthAnchor, constant: -(2 * padding)),
            feedbackTextView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.33),
            
            spacerView.heightAnchor.constraint(greaterThanOrEqualToConstant: 22),
            spacerView.widthAnchor.constraint(equalTo: stackView.widthAnchor),
            
            sendButton.widthAnchor.constraint(equalTo: stackView.widthAnchor, constant: -(2 * padding)),
            sendButton.heightAnchor.constraint(equalToConstant: 44)
        ])

    }
    
    private func configureAppVersionLabel() {
        guard let appName = Bundle.main.displayName, let appVersion = Bundle.main.version else {
            appVersionLabel.text = "Unknown"
            return
        }
        appVersionLabel.text = "\(appName)\n\(appVersion)"
        
        developerLabel.text = "developer"
    }
    
    @objc private func configureFeedbackTextView() {
        feedbackTextView.text = feedbackTextViewPlaceholder
        feedbackTextView.textColor = feedbackTextView.text == ProjectTextViewPlaceholderTextFor.feedback ? .tertiaryLabel : .label
    }
    
    private func configureSendButton() {
        sendButton.addTarget(self, action: #selector(sendButtonTapped), for: .touchUpInside)
        sendButton.isEnabled = false
    }
}

//MARK: - Delegate UITextView
extension FeedbackViewController: UITextViewDelegate {
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        //2000 chars restriction
        return textView.text.count + (text.count - range.length) <= 2000
    }
    
    func textViewDidBeginEditing(_ textView: UITextView) {
        if textView.textColor == UIColor.tertiaryLabel {
            textView.text = ""
            textView.textColor = .label
        }
    }
    
    func textViewDidEndEditing(_ textView: UITextView) {
        if textView.text.isEmpty {
            textView.text = ProjectTextViewPlaceholderTextFor.feedback
            textView.textColor = .tertiaryLabel
            feedbackTextViewPlaceholder = ""
        } else {
            feedbackTextViewPlaceholder = textView.text
        }
    }
    
    func textViewDidChange(_ textView: UITextView) {
        feedbackTextViewPlaceholder = textView.text
        
        if let text = textView.text, text.isNotEmpty, text != ProjectTextViewPlaceholderTextFor.feedback {
            sendButton.isEnabled = true
        } else {
            sendButton.isEnabled = false
        }
    }
}
导入UIKit
导入消息用户界面
结构邮件选项{
让url:url!
让我们来看看提特尔:字符串
}
类反馈ViewController:UIViewController、MFMailComposeViewController、UINavigationController、Elegate{
//标记:-属性
让logoImageView=ProjectImageView(帧:.0)
让appVersionLabel=ProjectTitleLabel(带TextAlignment:.center和Font:UIFont.preferredFont(forTextStyle:.title3)和Color:.label,行数:2)
让developerLabel=ProjectTitleLabel(带TextAlignment:.center和Font:UIFont.preferredFont(forTextStyle:.footnote)和Color:.tertiarySystemBackground,行数:1)
让feedbackTextView=ProjectTextView()
让视图=UIView()
让sendButton=ProjectButton(背景色:.systemOrange,标题:“发送”)
var feedbackTextViewPlaceholder=projecttextviewplaceholder.feedback
让emailTo=ProjectEmailAddresses.g
var emailBody=“”
让emailSubject=“关于\(Bundle.main.displayName??“未知”)的反馈”,版本\(Bundle.main.version??)
//MARK:-ViewController方法
重写func viewDidLoad(){
super.viewDidLoad()
configureViewController()
配置视图()
configureAppVersionLabel()
配置反馈文本视图()
configureSendButton()
}
//马克:行动
@objc专用函数endEditing(){
view.endEditing(真)
}
@objc func adjustForKeyboard(通知:通知){
//复位到原点位置
self.view.frame.origin.y=0
如果notification.name.rawValue==“UIKeyboardWillChangeFrameNotification”{
如果feedbackTextView.isFirstResponder{
self.view.frame.origin.y-=feedbackTextView.frame.origin.y+10
} 
}否则{
self.view.frame.origin.y=0
}
}
@objc专用函数sendButtonTapped(){
//额外检查反馈是否存在
guard let feedback=feedbackTextView.text,feedback.isNotEmpty else{return}
emailBody=反馈
让subjectEncoded=emailSubject.addingPercentEncoding(允许使用以下字符:.urlHostAllowed)!
让bodyEncoded=emailBody.addingPercentEncoding(使用允许的字符:.urlHostAllowed)!
让gMail=MailOption(url:url)(字符串:“googlegmail://co?to=\(emailTo)&subject=\(subjectEncoded)&body=\(bodyEncoded)”),titel:“GMail”)
让outlook=MailOption(url:url)(字符串:“ms-outlook://compose?to=\(emailTo)&subject=\(subjectEncoded)&body=\(bodyEncoded)”),titel:“Outlook”)
让spark=mailpoption(url:url(string:readdle-spark://compose?recipient=\(emailTo)&subject=\(subjectEncoded)&body=\(bodyEncoded)”,titel:“Spark”)
让availableUrls=[gMail,outlook,spark].filter{(mailOption)->Bool-in
return mailpoption.url!=nil&&UIApplication.shared.canOpenURL(mailpoption.url)
}
showEmailOptions(适用于:availableUrls)
}
//标记:-邮件功能
func showEmailOptions(适用于mailOptions:[MailOption]){
//创建行动表
让ac=UIAlertController(标题:“选择您的首选发送邮件的方法”,消息:无,首选样式:。操作表)
//添加Apple Mail操作(如果可用)
如果MFMailComposeViewController.canSendMail(){
ac.addAction(UIAlertAction)(标题:“Apple Mail”,样式:。默认值,处理程序:{(u)in
self.sendappemail()
}))
}
//添加其他可用操作
对于mailOptions中的选项{
ac.addAction(UIAlertAction)(标题:option.titel,样式:。默认值,处理程序:{(389;)in
UIApplication.shared.open(option.url,options:[:],completionHandler:{in
self.showSuccess()
})
}))
}
//取消操作
ac.addAction(UIAlertAction(标题:“取消”,样式:。取消,处理程序:nil))
//iPad需要
如果UIDevice.current.userInterfaceIdiom==.pad{
ac.popoverPresentationController?.sourceView=sendButton
ac.popoverPresentationController?.permittedArrowDirections=[.down、.up]
}
当前(ac,动画:真)
}
func sendappemail(){
//我们已经检查了邮件应用程序的可用性!
让composer=MFMailComposeViewController()
composer.mailComposeDelegate=self
composer.setToRecipients([emailTo])
编写器.setSubject(emailSubject)
composer.setMessageBody(emailBody,isHTML:false)
现在(作曲家,动画:真)
}
func-mailcomosecontroller(u控制器:mfmailcomoseviewcontroller,didFinishWith结果:MFMailComposeResult,错误:error?){
如果结果==.sent{
self.showSuccess()
}
控制器。解除(动画:真)
}
私人func showSuccess(){
presentProjectAlertOnMainThread(标题为:“已发送反馈!”,消息为:“感谢您的输入!”,dismissButtonTile为“确定”,confirButtonTitle:nil,完成:{in
self.feedbackTextView.text=“”
self.sendButton.isEnabled=false
})
}
//标记:-用户界面和布局
公共关系