在键盘上显示带有按钮的 UIView,例如在 Skype、Viber messengers(Swift、iOS)中
Posted
技术标签:
【中文标题】在键盘上显示带有按钮的 UIView,例如在 Skype、Viber messengers(Swift、iOS)中【英文标题】:Show UIView with buttons over keyboard, like in Skype,Viber messengers (Swift, iOS) 【发布时间】:2015-09-16 01:53:43 【问题描述】:我想创建附件视图,放置在输入附件视图下,通过键盘,例如在 Skype 应用程序或 Viber 中:
我已经问过这样的问题here,但是针对这个问题的建议解决方案并不那么优雅,因为当我将滚动视图拖到顶部时,我希望我的附件 UIView 用键盘向下移动(我使用 UIScrollViewKeyboardDismissModeInteractive)。
所以我创建了一个函数,它找出视图、键盘和我的自定义输入附件视图的放置位置:
func findKeyboardView() -> UIView?
var result: UIView? = nil
let windows = UIApplication.sharedApplication().windows
for window in windows
if window.description.hasPrefix("<UITextEffectsWindow")
for subview in window.subviews
if subview.description.hasPrefix("<UIInputSetContainerView")
for sv in subview.subviews
if sv.description.hasPrefix("<UIInputSetHostView")
result = sv as? UIView
break
break
break
return result
然后我添加一个自定义 UIView 并创建一些约束:
func createAttachView()
attach = MessageChatAttachmentsView(frame: CGRectZero)
let newView = findKeyboardView()
newView!.addSubview(attach!)
newView!.addConstraint(NSLayoutConstraint(item: accessoryView, attribute: .Bottom, relatedBy: .Equal, toItem: attach!, attribute: .Top, multiplier: 1.0, constant: 0.0))
attach!.addConstraint(NSLayoutConstraint(item: attach!, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 260))
attach!.addConstraint(NSLayoutConstraint(item: attach!, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 320))
这会在输入附件视图和键盘上方创建自定义 UIView,当我向上滚动时它会移动。但是当我想按下按钮时,我按下键盘上的一个键。
那么我怎样才能将此视图移动到 UIInputSetHostView 中视图层次结构的顶部?
【问题讨论】:
我认为您应该换入新的inputView
并重新加载输入视图。 developer.apple.com/library/ios/documentation/StringsTextFonts/…
【参考方案1】:
好的,感谢 Brian Nickel,我发现可能不是优雅但非常简单的解决方案。所以我已经覆盖了 inputAccessoryView 以在键盘上创建一个工具栏。所以基本上,如果我按下这个工具栏上的附加按钮,我想看到另一个 inputView,而不是键盘。 所以在我的自定义输入附件视图类中,我只创建了一些隐藏的文本视图:
class MessageChatInputAccessoryView : UIToolbar
var textView:UITextView! //textView for entering text
var sendButton: UIButton! //send message
var attachButton: UIButton! // attach button "+"
var attachTextView:UITextView! --> this one
override init(frame: CGRect)
super.init(frame: frame)
.....
.....
attachTextView = UITextView(frame: CGRectZero)
attachTextView.alpha = 0.0
self.addSubview(attachTextView)
....
所以在我的主视图控制器中,我创建了函数,为这个新创建的 attachTextView 重新初始化 inputView,如下所示:
func attach(sender: UIButton)
if attachMenuIsShown
accessoryView.attachTextView.inputView = accessoryView.textView.inputView
accessoryView.attachTextView.reloadInputViews()
attachMenuIsShown = false
else
accessoryView.attachTextView.becomeFirstResponder()
accessoryView.attachTextView.inputView = MessageChatAttachmentsView(frame: CGRectZero)
accessoryView.attachTextView.reloadInputViews()
attachMenuIsShown = true
所以当我按下附加按钮时,我的 attachTextView 成为第一响应者,然后我重新初始化这个 textView 的输入视图。我在输入附件视图下得到了我的附件视图。当我再次按下附加按钮时,我使用我的主 textView 的默认 inputView 重新初始化 inputView,这是键盘视图。
【讨论】:
嗨 Pavel,我在 iOS13 上尝试了类似的代码,直到 textView 的实际输入成为第一响应者,附件视图才显示。因此attachTexttView不能成为FirstResponder,也不能reloadInputViews。 感谢您的信息。我做了类似的事情,覆盖 var inputView: UIView?并覆盖 var canBecomeFirstResponder: Bool,对于 attachTextView,我为 attachTextView 创建了一个自定义子类。诀窍是需要调用 view..becomeFirstResponder() 当 viewController 的视图 didload 或 willAppear 第一次触发它。以上是关于在键盘上显示带有按钮的 UIView,例如在 Skype、Viber messengers(Swift、iOS)中的主要内容,如果未能解决你的问题,请参考以下文章