草庐IT

objective-c - UIWebView 向下滚动输入焦点仅限 iOS 6

coder 2023-07-26 原文

我正在模式中加载 UIWebView。该网页有一些输入完全按照 iOS 5 中的预期工作。但是在 iOS 6 中,只要输入获得焦点,键盘就会自动“居中”表单,即使输入有足够的空间显示在上面键盘。由于一些输入位于页面的顶部,这迫使它们不可见,因此用户看不到他们正在输入的内容。向上滚动以查看输入会导致键盘停止工作,直到关闭并重新聚焦输入(然后再次将其滚动到 View 之外)。这是 iOS 6 中的预期行为吗?当输入获得焦点时(如 iOS 5 的工作方式),有什么方法可以防止 webview 滚动吗?

最佳答案

在不了解您代码的内部工作原理的情况下,我将尽力提供帮助。如果不出意外,我希望提供一些思考。你问了两个问题:

这是 iOS6 中的预期行为吗?

您所看到的肯定很奇怪。 webView 将表单居中而不是将输入字段居中,这很奇怪。而且它绝对不应该导致事件输入字段滚出 View 。此外,键盘似乎停止工作,这很奇怪。但是,预计在 iOS 5 和 6 中会出现与 webView 滚动相关的不同行为。如您所说,iOS 5 将 inputField 滚动到 View 中,而 iOS6 将其置于中心。

有什么方法可以防止 webview 在输入获得焦点时滚动(就像 iOS 5 的工作方式一样)?

是的。我在下面提供了执行此操作的代码——即停止 webView 滚动。如果这正是您想要做的,那就太好了。但是,停止 webView 滚动与获得与 iOS5 相同的行为是不一样的。尽管如此,我还是想按照您的要求为您提供此选项。

#import "ViewController.h"

@interface ViewController () <UIScrollViewDelegate> {
    CGPoint origin;
}

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.google.com"]];
    [self.webView loadRequest:request];
    self.webView.scrollView.delegate = self;

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];

    // NOTE THAT SIMPLY DISABLING THE SCROLL WILL NOT PREVENT KEYBOARD SCROLL
    //[self.webView.scrollView setScrollEnabled:NO];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)keyboardWillShow {
    NSLog(@"keyboard");
    origin = self.webView.scrollView.contentOffset;

}

-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
    NSLog(@"scroll");
    [self.webView.scrollView setContentOffset:origin];
}

@end

如果您想要一致的滚动行为...

我花了一些时间来编写这个滚动修改。您可以使用它作为引用来制作您自己的在 iOS 5 和 6 中保持一致的滚动行为。在这段代码中: 当用户单击网页上的文本输入框时,代码将通过保持页面滚动到其当前位置来停止默认滚动行为。不幸的是,没有办法取消所有滚动,而是你必须覆盖滚动。一旦默认滚动被“抑制”,它就会获取事件输入框的位置并滚动到该位置。这会将事件输入框放在屏幕顶部。您可以根据自己的喜好进行修改。比如你可以使用[UIScrollView scrollRectToVisible]让它更像iOS5。

#import "ViewController.h"

@interface ViewController () <UIScrollViewDelegate> {
    CGPoint origin;
    CGPoint activeElementOrigin;
    BOOL pauseScroll;
}

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.google.com"]];
    [self.webView loadRequest:request];
    self.webView.scrollView.delegate = self;

    pauseScroll = NO;
    origin = CGPointZero;

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardDidShow)
                                                 name:UIKeyboardDidShowNotification
                                               object:nil];
}

- (void)keyboardWillShow {
    NSLog(@"keyboard");
    pauseScroll = YES;
    origin = self.webView.scrollView.contentOffset;
}

- (void)keyboardDidShow {
    NSLog(@"keyboard DID SHOW");
    pauseScroll = NO;
    [self.webView.scrollView setContentOffset:activeElementOrigin animated:YES];
}

-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
    NSLog(@"scroll");

    if (pauseScroll) {
        [self.webView.scrollView setContentOffset:origin animated:NO];

        NSString *javaScript = [NSString stringWithFormat:@"function f(){ var textField = document.activeElement; return textField.getBoundingClientRect().top; } f();"];
        NSString *textFieldRectTop = [self.webView stringByEvaluatingJavaScriptFromString:javaScript];
        activeElementOrigin = origin;
        activeElementOrigin.y = [textFieldRectTop floatValue]-10;
    }
}


@end

如果这段代码对您有帮助,您能将赏金奖励给我就太好了。 我将不胜感激。

关于objective-c - UIWebView 向下滚动输入焦点仅限 iOS 6,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13071195/

有关objective-c - UIWebView 向下滚动输入焦点仅限 iOS 6的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  3. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  4. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在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返回它复制的字节数,但是当我还没有下

  5. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  6. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  7. objective-c - 在设置 Cocoa Pods 和安装 Ruby 更新时出错 - 2

    我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U

  8. ruby - 鸭子输入字符串、符号和数组的优雅方式? - 2

    这是针对我无法破坏的现有公共(public)API,但我确实希望对其进行扩展。目前,该方法采用字符串或符号或任何其他在作为第一个参数传递给send时有意义的内容我想添加发送字符串、符号等列表的功能。我可以只使用is_a吗?数组,但还有其他发送列表的方法,这不是很像ruby​​。我将调用列表中的map,所以第一个倾向是使用respond_to?:map。但是字符串也会响应:map,所以这行不通。 最佳答案 如何将它们全部视为数组?String的行为与仅包含String的Array相同:deffoo(obj,arg)[*arg].eac

  9. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  10. ruby - 你会如何在 Ruby 中表达成语 "with this object, if it exists, do this"? - 2

    在Ruby(尤其是Rails)中,您经常需要检查某物是否存在,然后对其执行操作,例如:if@objects.any?puts"Wehavetheseobjects:"@objects.each{|o|puts"hello:#{o}"end这是最短的,一切都很好,但是如果你有@objects.some_association.something.hit_database.process而不是@objects呢?我将不得不在if表达式中重复两次,如果我不知道实现细节并且方法调用很昂贵怎么办?显而易见的选择是创建一个变量,然后测试它,然后处理它,但是你必须想出一个变量名(呃),它也会在内存中

随机推荐