swift如何将inputAccessoryView停靠在UIToolbar上方(不是底部)

Posted

技术标签:

【中文标题】swift如何将inputAccessoryView停靠在UIToolbar上方(不是底部)【英文标题】:swift how to dock inputAccessoryView above UIToolbar (not to the bottom) 【发布时间】:2016-05-19 15:01:17 【问题描述】:

我已经实现了在键盘上方正确显示的自定义 inputAccessoryView。

问题是在屏幕底部我有 UIToolbar。 当键盘关闭时,我的自定义 inputAccessoryView 停靠在屏幕底部并覆盖 UIToolBar。

当键盘关闭时,有没有办法将 inputAccessoryView 停靠在 UIToolbar 上方?

【问题讨论】:

您可以编辑您的问题以显示代码吗? 【参考方案1】:

不容易,因为inputAccessoryView 将始终位于您的视图上方,因为它位于不同的窗口中。它会带来很多并发症。

您是否尝试过在 self.view 层次结构中使用 UIKeyboardWillShowNotificationUIKeyboardWillHideNotification 和附件视图?

首先在您的视图控制器中订阅通知

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIKeyboardWillHideNotification, object: nil)

然后也在你的视图控制器中

func keyboardWillShow(notification:NSNotification) 

    self.transitionWithKeyboardInfo(notification.userInfo!)



func transitionWithKeyboardInfo(userInfo:NSDictionary) 

    let durationNumber = userInfo[UIKeyboardAnimationDurationUserInfoKey]
    let duration = durationNumber?.doubleValue

    let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey]
    let animationCurveRaw = animationCurveRawNSN?.unsignedLongValue ?? UIViewAnimationOptions.CurveEaseInOut.rawValue
    let animationCurve = UIViewAnimationOptions(rawValue: animationCurveRaw)

    let endFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey]
    let keyboardEndFrame = self.view.convertRect(endFrameValue!.CGRectValue, fromView:nil)

    UIView.animateWithDuration(duration!, delay: 0.0, options: animationCurve, animations: 

       // Now use keyboardEndFrame.size.height to move your view upwards

       // you can find out if you're dismissing or showing and do different animations here

        , completion: nil)

不要忘记删除dealloc / viewWillDisappear中的通知观察

NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)

使用ScrollViewDidScroll 进行交互式附件视图移动...

var startingPoint:CGPoint


func scrollViewWillBeginDragging(scrollView: UIScrollView)    

    self.startingPoint = scrollView.panGestureRecognizer.locationInView(scrollView)


func scrollViewDidScroll(scrollView: UIScrollView)    

    let currentPoint = scrollView.panGestureRecognizer.locationInView(scrollView)

    let deltaY = currentPoint.y - self.startingPoint.y

如果你触摸到拦截附件视图框架,这应该是你需要解决的所有问题......然后你可以决定如何用键盘转换它......最简单的是谷歌环聊所做的事情并转换附件将键盘作为单独的实体查看...这可能不是您想要的 100%,但过了一段时间,我接受了它并让它看起来不错。

【讨论】:

这件事是我还需要滑动键盘(self.tableView.keyboardDismissMode = .Interactive),在这种情况下,我的 inputAccessoryView 应该在向下滑动时跟随键盘。我想首先让 inputAccessoryView 跟随键盘,然后在到达 uitoolbar 时使 inputAccessory 视图保持在 uitoolbar 上方 这个还是可以的,但是比较复杂。使用tableView / scrollView / 的scrollIndicatorInsetscontentInset 向下拖动使用scrollViewDidScroll 移动accessoryView 你会发现它只会在你触摸键盘时移动,所以你需要检测您何时触摸了附件视图并开始该过程,然后如果这是不可接受的。以 Google Hangouts 为例。 Magoo,你知道,我被卡住了 :(scrollViewDidScroll 功能完美运行,但我无法检测到我的附件视图何时被触摸。我尝试使用 touchesMoved(touches: Set<UITouch>, withEvent...) 功能但似乎我现在对UIViewController 不起作用。我也尝试过UITapGestureRecognizer,但是当触摸结束时它给了我坐标而不是正确的坐标。有没有办法知道附件视图被触摸了?然后如何我要自己移动附件视图吗?(据我所知附件视图是根据键盘移动自动移动的) 正如我现在在函数scrollViewDidScroll 中看到的scrollView.contentOffset 并不是手指移动的真实点。它们是一些滚动偏移量。我对吗?所以我的视图移动速度没有键盘移动那么快。我也尝试了UITapGestureRecognizer,它工作正常 - 显示了我按下和移动的真实点,但现在的问题是交互式键盘关闭模式没有完全可以工作 - 我可以移动键盘上方的视图(我现在使用的是普通视图,而不是附件视图)但是当我将手指移到它上面时键盘没有移动:( 这是一项极其复杂的任务 :D 所以不要放弃!但我找到了一种方法。使用scrollViewWillBeginDragging 并以同样的方式存储CGPoint self.startingPoint = [scrollView.panGestureRecognizer locationInView:scrollView];,在scrollViewDidScroll 中使用CGPoint currentPoint = [scrollView.panGestureRecognizer locationInView:scrollView]; 将为您提供当前点...然后您可以执行currentPoint.x - self.startingPoint.xcurrentPoint.y - self.startingPoint.y 以获得增量改变:)

以上是关于swift如何将inputAccessoryView停靠在UIToolbar上方(不是底部)的主要内容,如果未能解决你的问题,请参考以下文章

swift 如何将Swift 3内置的cocoapod更新为Swift 4

如何将以下代码从 Swift 2 转换为 Swift 5?

Swift:如何将字符串放入 \()? [复制]

Swift:如何将 MapView 放入 UIView(?)

如何在 Swift 中从 NSData 显示 PDF - 如何将 PDF 保存到文档文件夹 Swift - 如何在 Swift 中通过 WebView 从保存的 NSData 显示 PDF

如何将此 NSClassFromString 代码转换为 Swift?