作为 UITextView inputAccessoryView 的 SwiftUI 视图具有不正确的框架

Posted

技术标签:

【中文标题】作为 UITextView inputAccessoryView 的 SwiftUI 视图具有不正确的框架【英文标题】:SwiftUI view as a UITextView inputAccessoryView has incorrect frame 【发布时间】:2020-08-23 05:36:25 【问题描述】:

我正在尝试通过 UIHostingController 将 SwiftUI 视图作为附件视图添加到 UITextView。以下是我的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 的边框为绿色。

发生这种情况的任何原因?

【问题讨论】:

【参考方案1】:

我一直在做类似的事情。我正在完全在 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"), style: .plain, target: self, action: #selector(self.linkView(sender:)))
    let bold = UIBarButtonItem(image: UIImage(systemName: "bold"), style: .plain, target: self, action: #selector(self.onBold(sender:)))
    let italic = UIBarButtonItem(image: UIImage(systemName: "italic"), style: .plain, target: self, action: #selector(self.onItalic(sender:)))
    let underline = UIBarButtonItem(image: UIImage(systemName: "underline"), style: .plain, target: nil, action: #selector(self.onUnderline(sender:)))
    let activeLink = activeLinkState ? UIBarButtonItem(image: UIImage(systemName: "link.circle.fill"), style: .plain, target: nil, action: #selector(self.toggleActiveLink(sender:))) : UIBarButtonItem(image: UIImage(systemName: "link.circle"), style: .plain, target: nil, action: #selector(self.toggleActiveLink(sender:)))
    let done = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.doneButtonAction))
    let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    bar.items = [textformat, linkformat, spacer, bold, italic, underline, spacer, activeLink, done]
    bar.sizeToFit()
    self.inputAccessoryView = bar


【讨论】:

以上是关于作为 UITextView inputAccessoryView 的 SwiftUI 视图具有不正确的框架的主要内容,如果未能解决你的问题,请参考以下文章

如何将 UITextView 嵌入 UITableViewCell 与作为委托的自定义单元格?

将 UITextView 作为第一响应者后,表格视图单元格不可选择

使用故事板、自动布局和 Swift 的多行 UILabel 和 UITextView

UITextView becomeFirstResponder 无法正常工作

Swift 4 UITableView 将一个单元格设为 UITextView

UITextView,sizeToFit 行为怪异