我有一个包含 UITextView 的 UIView。我想在键盘可见时向上移动 UIView。所以想法是change the Y position .
有时,当键盘仍然可见时,UIView 会返回到其初始 Y 位置。即使我专注于输入,它也不会再回来了。我真的不知道为什么。
https://d17oy1vhnax1f7.cloudfront.net/items/2K0z3P1j1x2f0X2X1B2v/ci.gif
PS:键盘在Gif中出现了3次。它是循环的,所以很难区分结束。
我做了什么,首先我添加了通知观察者:
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillChangeFrame), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
然后我定义了键盘切换处理程序:
func keyboardWillChangeFrame(notification: NSNotification) {
let info = notification.userInfo!
let keyboardFrame: CGRect = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
self.keyboardInfo["isVisible"] = self.view.frame.size.height - keyboardFrame.origin.y != 0
self.keyboardInfo["height"] = keyboardFrame.size.height
self.keyboardInfo["animationDuration"] = info[UIKeyboardAnimationDurationUserInfoKey] as! Double
self.keyboardInfo["animationCurve"] = info[UIKeyboardAnimationCurveUserInfoKey] as! UInt
if self.keyboardInfo["isVisible"] as! Bool {
self.moveCommentInputUp()
} else {
self.moveCommentInputDown()
}
}
之后,我定义了将评论输入 View 向上/向下移动的方法:
func moveCommentInputUp() {
print("Moving up... ", self.commentFormView.frame.origin.y, " to ", self.view.frame.size.height - (self.keyboardInfo["height"] as! CGFloat) - self.commentFormView.frame.size.height)
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationDuration(self.keyboardInfo["animationDuration"] as! TimeInterval)
UIView.setAnimationCurve(UIViewAnimationCurve(rawValue: Int(self.keyboardInfo["animationCurve"] as! UInt))!)
UIView.setAnimationBeginsFromCurrentState(true)
ViewUtil.changeViewFrame(view: self.commentFormView, yPosition: self.view.frame.size.height - (self.keyboardInfo["height"] as! CGFloat) - self.commentFormView.frame.size.height)
ViewUtil.removeShadowToView(self.commentFormLauncherButton)
UIView.commitAnimations()
}
func moveCommentInputDown() {
print("Moving down... ", self.commentFormView.frame.origin.y, " to ", self.view.frame.size.height)
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationDuration(self.keyboardInfo["animationDuration"] as! TimeInterval)
UIView.setAnimationCurve(UIViewAnimationCurve(rawValue: Int(self.keyboardInfo["animationCurve"] as! UInt))!)
UIView.setAnimationBeginsFromCurrentState(true)
ViewUtil.changeViewFrame(view: self.commentFormView, yPosition: self.view.frame.size.height)
ViewUtil.addShadowToView(commentFormLauncherButton, position: CGSize(width: 0, height: 5))
UIView.commitAnimations()
}
按钮的 Action 是
@IBAction func showCommentForm(_ sender: UIButton) {
self.commentInput.becomeFirstResponder()
}
日志(请参阅 Gif)显示 View 从 568(屏幕底部)再次移动到 568
// The numbers show the initial and the final value of the keyboard Y position
// Click on button to focus the input
Moving up... 568.0 to 282.0
// Tap anywhere
Moving down... 282.0 to 568.0
// Click again on button to focus the input
Moving up... 568.0 to 282.0
///// Write "hhh". The view is gone, I don't know why.
// Tap anywhere
Moving down... 568.0 to 568.0 // The view seems to move from 568 to 568, hugh
// Click on button to focus the input
Moving up... 568.0 to 282.0 // This didn't work apparently
// Tap anywhere
Moving down... 568.0 to 568.0 // 568 to 568 again
我错过了什么吗?
系统:iOS 9、Xcode 8、Swift 3
最佳答案
好的,这是一个不需要 CocoaPods 的解决方案。
我的方法涉及在键盘出现和消失时设置 textField 底部约束的常量。这意味着您需要创建对文本字段底部约束的引用。
@IBOutlet weak var textFieldBottomConstraint: NSLayoutConstraint!
我开始在 viewDidLoad 中设置 NSNotification.Name.UIKeyboardWillShow 和 UIKeyboardWillHide 的观察者,而不是 UIKeyboardWillChangeFrame:
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
接下来我设置选择器及其函数来设置文本字段底部约束的常量:
func handleKeyboardNotification(notification: NSNotification) {
if let userInfo = notification.userInfo {
let keyboardFrameValue = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)
let keyboardFrame = keyboardFrameValue?.cgRectValue
let isKeyboardShowing = notification.name == NSNotification.Name.UIKeyboardWillShow
textFieldBottomConstraint.constant = isKeyboardShowing ? keyboardFrame!.height + 4 : 4
self.view.layoutIfNeeded()
}
}
请注意,textFieldBottomConstraint 是底部约束的引用变量。
这样做的目的是让 textField 在键盘出现或消失时设置它的底部约束,并且不会遇到您遇到的奇怪故障。
希望这对您有所帮助,请不要犹豫,要求澄清!
致谢 YouTuber 让我们构建该应用程序吧!通过此视频提供解决方案:
关于ios - 当键盘可见时更改 Y 原点时出现奇怪的 UIView 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39604177/
如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe
我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作
我正在编写一个方法,它将在一个类中定义一个实例方法;类似于attr_accessor:classFoocustom_method(:foo)end我通过将custom_method函数添加到Module模块并使用define_method定义方法来实现它,效果很好。但我无法弄清楚如何考虑类(class)的可见性属性。例如,在下面的类中classFoocustom_method(:foo)privatecustom_method(:bar)end第一个生成的方法(foo)必须是公共(public)的,第二个(bar)必须是私有(private)的。我怎么做?或者,如何找到调用我的cust
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下