SwiftUI视图作为UITextView inputAccessoryView具有错误的框架

问题描述

我正在尝试通过UITextView将SwiftUI视图作为附件视图添加UIHostingController。以下是我的UIInputView配置

struct AccessoryView: View { /* SwiftUI View */ } 

class AccessoryInputView: UIInputView {

    private let controller: UIHostingController<AccessoryView>

    init(_ attachmentItem: Binding<AttachmentItemType>) {
        let parentView = AccessoryView(selectedAttachmentItem: attachmentItem)
        self.controller = UIHostingController<AccessoryView>(rootView: parentView)
        super.init(frame: CGRect(x: 0,y: 0,width: 0,height: 44),inputViewStyle: .default)

        self.controller.view.translatesAutoresizingMaskIntoConstraints = false
        self.controller.view.backgroundColor = UIColor.clear
        self.addSubview(self.controller.view)

        self.layer.borderWidth = 2
        self.layer.borderColor = UIColor.blue.cgColor
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        NSLayoutConstraint.activate([
            self.widthAnchor.constraint(equalTo: self.controller.view.widthAnchor),self.heightAnchor.constraint(equalTo: self.controller.view.heightAnchor),self.centerXAnchor.constraint(equalTo: self.controller.view.centerXAnchor),self.centerYAnchor.constraint(equalTo: self.controller.view.centerYAnchor)
        ])
    }
}

我用蓝色绘制了UIInputView的边框,并用红色绘制了AccessoryView周围的边框。如您在屏幕快照中所见,SwiftUI视图偏移了几个点。 UITextView的边框为绿色。

为什么会这样?

here

解决方法

我一直在做类似的事情。我完全在SwiftUI中构建RTF文档编辑器,而我的输入附件视图就是通过这种方式完成的。我只要在定义或想要显示inputAccessoryView的地方都调用此函数,就像在makeUIView中一样,我有这一行“ textView.setInputAccessory()”。下面的选择器全部在我的扩展程序中定义。

extension UITextView {
internal func setInputAccessory()
{
    let activeLinkState = UserDefaults.standard.bool(forKey: "activeLink")
    let bar = UIToolbar()
    let textformat = UIBarButtonItem(image: UIImage(systemName: "textformat"),style: .plain,target: self,action: #selector(self.editView(sender:)))
    let linkformat = UIBarButtonItem(image: UIImage(systemName: "link"),action: #selector(self.linkView(sender:)))
    let bold = UIBarButtonItem(image: UIImage(systemName: "bold"),action: #selector(self.onBold(sender:)))
    let italic = UIBarButtonItem(image: UIImage(systemName: "italic"),action: #selector(self.onItalic(sender:)))
    let underline = UIBarButtonItem(image: UIImage(systemName: "underline"),target: nil,action: #selector(self.onUnderline(sender:)))
    let activeLink = activeLinkState ? UIBarButtonItem(image: UIImage(systemName: "link.circle.fill"),action: #selector(self.toggleActiveLink(sender:))) : UIBarButtonItem(image: UIImage(systemName: "link.circle"),action: #selector(self.toggleActiveLink(sender:)))
    let done = UIBarButtonItem(barButtonSystemItem: .done,action: #selector(self.doneButtonAction))
    let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace,action: nil)
    bar.items = [textformat,linkformat,spacer,bold,italic,underline,activeLink,done]
    bar.sizeToFit()
    self.inputAccessoryView = bar
}
}