UIScrollView 与 UIWebViews

2024-05-22

stackoverflow 上似乎有很多关于这个主题的问题,但没有一个涉及 3.0 中的更新。经过几个小时的研究后,我终于发现,完全支持嵌套滚动视图(在我的例子中是滚动视图内的网页视图),但是给出的示例在http://developer.apple.com/iphone/library/documentation/WindowsViews/Conceptual/UIScrollView_pg/Introduction/Introduction.html http://developer.apple.com/iphone/library/documentation/WindowsViews/Conceptual/UIScrollView_pg/Introduction/Introduction.html是非常基本的。

我有一个启用分页的主滚动视图,Web 视图布局为子视图,这样我就可以左右分页更改不同的 Web 视图,而且还可以在子视图内上下滚动。

从本质上讲,这似乎工作得很好,但是我不知道的是,一旦用户已经开始滚动 Web 视图,如何阻止父滚动视图向左或向右分页。本质上我想将滚动锁定到它开始的方向。有趣的是,如果我首先开始分页,那么效果很好,但是如果我首先开始向上或向下滚动,它也会同时允许分页(在同一个开始-移动-结束循环期间)。

例如,股票应用程序可以正确锁定滚动。


编辑:这在 iOS 4.0 上完全被破坏了。一旦我弄清楚出了什么问题,我就会更新这个。

由于 UIWebView 与 3.0 中引入的自动嵌套滚动效果不太好,并且不再支持将 TouchBegin/Moved/Ended 发送到 UIScrollView,这就是我的想法。

我在所有其他视图之上添加了一个透明的 UIView 子类,并使其捕获所有触摸。 当触摸开始时,我将其转发到当前活动的 UIWebView 并启动一个短计时器(或者更确切地说是另一个使用 usleep() 休眠一会儿的线程 - 根据我的经验,当大量触摸事件发生时,主线程可能会被锁定)传入和计时器可能会走得很远)。

在touchesMoved中,我检查我启动的计时器是否尚未过期 - 如果还没有过期,并且 fabs(location.x - lastLocation.x) > fabs(location.y - lastLocation.y) 那么看起来用户正在尝试页面(这可以通过乘数进行调整,但目前这似乎只是最佳位置)。 如果确定用户正在尝试分页,我会发送 Web 视图 TouchesCancelled 并开始相应地调整滚动视图的 contentOffset.x。

在touchesEnded中,如果确定用户正在翻页,我会应用一些牛顿物理学来查看触摸以及滚动的一些动力延续是否足以跨越到下一页(超过一半的页面)下一页可见)。如果是这样,我将根据滚动的速度设置滚动动画以继续。

警告:由于尝试了十亿种不同的东西,这段代码很糟糕。我还没有机会清理它。希望这对某人有帮助。

-(void)timer {
    usleep(250000);
    expired = YES;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    paging = NO;
    expired = NO;
    determined = NO;


    if(navManager == nil) {
        navManager = [[[[UIApplication sharedApplication] delegate] viewController] navManager];
    }

    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self];

    touchStartX = location.x;
    touchStarted = touch.timestamp;

    [NSThread detachNewThreadSelector:@selector(timer) toTarget:self withObject:nil];

    [[navManager.currentNavItem.webView hitTest:CGPointZero withEvent:event] touchesBegan:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    if(!paging) {
        [[navManager.currentNavItem.webView hitTest:CGPointZero withEvent:event] touchesCancelled:touches withEvent:event];
    }

}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    if(!paging) {
        [[navManager.currentNavItem.webView hitTest:CGPointZero withEvent:event] touchesEnded:touches withEvent:event];
    }
    else {
        UITouch *touch = [touches anyObject];
        CGPoint location = [touch locationInView:self];
        NSTimeInterval touchLasted = touch.timestamp - touchStarted;
        CGFloat touchLen = location.x - touchStartX;
        float dir = touchLen/fabs(touchLen);
        float touchSpeed = touchLen/touchLasted;
        float deAccelRate = -3000.0;
        float timeToDeAccel = (-touchSpeed) / deAccelRate;
        float averageVelocity = touchSpeed / 2.0;
        float couldTravel = averageVelocity*timeToDeAccel;

        if(couldTravel > navManager.scrollView.frame.size.width/2.0) {
            couldTravel = navManager.scrollView.frame.size.width/2.0;
        }
        couldTravel = dir*couldTravel;

        NSLog(@"could travel: %f, touchSpeed: %f, timeToDeAccel = %f, averageVelocity: %f", couldTravel, touchSpeed, timeToDeAccel, averageVelocity);

        int page = round((navManager.scrollView.contentOffset.x - couldTravel) / navManager.scrollView.frame.size.width);
        if(page < 0) 
            page = 0;
        else if(page > round(navManager.scrollView.contentSize.width / navManager.scrollView.frame.size.width) - 1) 
            page = round(navManager.scrollView.contentSize.width / navManager.scrollView.frame.size.width) - 1;

        CGPoint newOffset = CGPointMake(page*navManager.scrollView.frame.size.width, navManager.scrollView.contentOffset.y);
        float needToMove = fabs(newOffset.x - navManager.scrollView.contentOffset.x);
        float timeToAnimate = needToMove / averageVelocity;

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDelegate:nil];
        [UIView setAnimationDuration:timeToAnimate];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
        navManager.scrollView.contentOffset = newOffset;
        [UIView commitAnimations];
    }
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self];
    CGPoint lastLocation = [touch previousLocationInView:self];

    if(!determined && !expired) {

        if(fabs(location.x - lastLocation.x) > fabs(location.y - lastLocation.y)) {
            NSLog(@"PAGE!!");
            paging = YES;
            [[navManager.currentNavItem.webView hitTest:CGPointZero withEvent:event] touchesCancelled:touches withEvent:event];
        }
        else
            [navManager.scrollView touchesCancelled:touches withEvent:event];

        determined = YES;
    }

    if(!paging) 
        [[navManager.currentNavItem.webView hitTest:CGPointZero withEvent:event] touchesMoved:touches withEvent:event];

    else {
        float xScroll = navManager.scrollView.contentOffset.x-(location.x - lastLocation.x);

        CGPoint newOffset = CGPointMake(xScroll, navManager.scrollView.contentOffset.y);
        navManager.scrollView.contentOffset = newOffset;
    }
}

还有一些东西需要添加,以使其感觉更原生,但这应该是一个很好的起点。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UIScrollView 与 UIWebViews 的相关文章

  • jQuery/JavaScript:仅选择子级的第一个“层”

    我试图仅选择给定类型的子元素的第一 层 而不选择嵌套在另一个限定元素内的元素 例如 在 div div class special div class special div div div div class special div di
  • jqgrid嵌套子网格第四级子网格总是返回子网格的第一个rowid

    jqGrid v4 3 2 ie9荣获7家企业 我使用以下代码来生成子网格 http www trirand com blog jqgrid jqgrid html http www trirand com blog jqgrid jqgr
  • 具有同步功能的 iPhone 离线应用程序

    我正在考虑构建一个可以在离线状态下和在线状态下一样运行的应用程序 由于应用程序在离线状态下无法与服务器通信 因此需要进行某种程度的同步 在规划 iPhone 同步离线操作时 有哪些值得阅读和开始思考的好工具 与苹果已经提供的工具来帮助解决这
  • UIDatePicker 仅显示月份和日期

    我想要一个UIDatePicker用户可以选择月份和日期 但不能选择年份 我知道闰年有额外的一天 所以为了简单起见 让我们把这一天扔掉 有没有办法删除年份列或有 2 个带有月 日的卷轴 其作用类似于UIDatePicker 所选月份中不存在
  • 如何判断用户是否已经滚动到UITableView的底部?

    如何确定用户是否已滚动到 UITableView 的最后一个单元格 底部 UITableView继承自UIScrollView 滚动视图暴露了一个contentOffset财产 文件here http developer apple com
  • 使用 NSOutputStream 通过套接字发送数据的正确方法

    我刚刚开始在 iOS 上进行套接字编程 我正在努力确定 的使用NSStreamEventHasSpaceAvailable活动为NSOutputStreams 一方面 苹果官方文档 清单2 https developer apple com
  • 翻转、生长和平移动画

    Look at 这个视频 http youtu be qIqv3OH9XIU t 1m12sMLB At Bat 应用程序的一部分 基本上 我只是想呈现一个modalViewController与UIModalPresentationFor
  • 我如何知道网页视图已加载完成

    我有网络视图 因为我正在加载pdf文件 pdf 文件大小为 2 mb 因此需要时间 我想添加指标 为此 我如何知道我的文件已加载到网络视图中 UIWebView 委托 http developer apple com library ios
  • 恢复从未付款过的用户的应用内购买

    我正在尝试在我的应用程序中测试应用程序内购买 当我与购买了应用程序内购买的测试用户恢复应用程序内购买时 一切正常 但是当我尝试与用户恢复应用内购买时didn t在我期望框架调用以下方法之前进行应用内购买 paymentQueue resto
  • 寻找嵌套列表中的最低值?

    我正在尝试编写一个函数 它接受一个列表并可以打印该列表中的最小整数 现在我试图弄清楚在嵌套列表中该怎么做 如果最低数字位于这些嵌套列表之一中 那么总的来说它将打印该数字 我的代码在这里 def listMin list2 3 4 2 99
  • 将嵌套列表转换为嵌套列表

    我知道可以将项目列表从一种类型转换为另一种类型 但是如何将嵌套列表转换为嵌套 List 已经尝试过的解决方案 List
  • 像 Google Play 商店一样在垂直 RecyclerView 中动态不同图像水平 RecyclerView

    我一直在关注这个教程 http android pratap blogspot co za 2015 12 horizo ntal recyclerview in vertical html http android pratap blog
  • 如何在 NSMutableArray 中实现“按值分组”?

    我正在使用 NSMutableArray 我想像在 SQL 中那样按日期获取值group by log date logMuArray log currenttime 4 30pm log date 11 12 2011 log durat
  • iPhone 应用程序中的异步、同步、线程

    我正处于一个应用程序的设计阶段 该应用程序将利用 REST Web 服务 并且在使用异步 同步和线程方面遇到了困境 这是场景 假设您有三个选项可供深入研究 每个选项都有自己的基于 REST 的资源 我可以使用同步请求延迟加载每个请求 但这会
  • 在 iPhone 中缝合图片

    我想并排缝合2张png 在Cocoa中 我会使用 NSImage initWithSize 然后只是drawInRect 但是 UIImage 没有 initWithSize 类 我现在该怎么做 Use UIGraphicsBeginIma
  • NSNotificationCenter 为“观察者”和“对象”保留什么类型的引用?

    任何人都可以澄清 阐明有关情况 NSNotificationCenter addObserver selector name object 观察者 和 对象 参数的通知中心保留哪些类型的引用 从通知中心删除观察者的最佳实践是什么 多线程应用
  • 将通配符包标识符转换为单个 ID

    我在应用程序商店中有一个使用通配符包标识符的应用程序 我想实现应用内购买 这需要非通配符ID 如何将现有应用的通配符 ID 转换为静态 ID 以进行应用内购买和推送通知 应用程序的捆绑标识符在更新之间必须始终保持相同 但 AppID 实际上
  • 如何获取原始触摸屏数据?

    我知道我可以在 iPhone 应用程序中获取触摸事件 但这些触摸事件都被我过滤掉了 如果我将设备按在脸上 它会过滤掉这些触摸事件 因为它可以检测到它不是手指 我如何获得原始触摸事件 而不以任何方式过滤 没有用于此目的的公共 API 您可以获
  • * foreach 里面的 foreach codeigniter 2?

    在 codeigniter 2 1 中 我尝试按类别显示频道 因此 如果我有一个名为 电影 的类别 我应该会看到电影中的频道列表 我尝试使用嵌套的 foreach 循环来完成此任务 但似乎无法使其工作 我的表结构是这样的 但更复杂 我的型号
  • 如何以方向友好的方式在选项卡栏上显示 UIDatePicker?

    我想滑入UIDatePicker当我的用户点击我的表格视图日期字段时 就像在标准联系人应用程序中一样 当用户点击生日字段时 还有一个额外的致命细节 它位于标签栏应用程序中 我想要UIDatePicker滑过标签栏 当用户将手机横向放置时仍然

随机推荐

  • 如何避免多系列折线图d3.js的工具提示重叠

    我已经在多系列折线图上创建了工具提示 如下所示在这里回答 https stackoverflow com questions 34886070 d3 js multiseries line chart with mouseover tool
  • 在 R 中,如何获得某些向量值的所有可能组合?

    背景 我有一个需要一些参数的函数 我想要获得所有可能的参数组合的函数结果 一个简化的例子 f lt function x y return paste x y sep colors c red green blue days c Monda
  • h264 参考帧

    我正在寻找一种在 h264 流中查找参考帧的算法 我在不同的解决方案中看到的最常见的方法是查找访问单元分隔符和 IDR 类型的 NAL 不幸的是 我检查的大多数流没有 IDR 类型的 NAL 我将不胜感激的帮助 问候 雅采克 H264 帧由
  • 如何在 Kotlin 中强制执行空的非空字符串?

    我经常想保存一个不能为空的字符串or blank 空白不够好 编译器处理String 很好地防止 null 我们可以使用aNullableString isNullOrBlank 检查它是否为空或空白 但是 这要求在使用空白支票的所有地方都
  • 在覆盖 UIView 的右下角创建四分之一透明孔

    您好 我想在覆盖 UIView 的右下角创建一个四分之一透明孔 我可以使用下面的代码解决它 但它看起来不正确 因为我在视图之外创建了一个矩形 我尝试过的 implementation PartialTransparentView id in
  • Visual Studio 复制资源 .cs 文件

    Visual Studio 已经开始表现出一个相当令人恼火的怪癖 当我编辑资源文件 使用设计器视图或直接编辑 XML 时 它会创建重复的资源 Designer cs 文件 这会导致项目无法构建 示例 假设我的资源文件名为 ProjectSQ
  • 无效的数组分配

    我不知道我将地址分配给其他二维数组的问题出在哪里 请帮我解决这个问题 int main int a 3 2 int b 2 0 1 a 2 b return 0 prog cpp 8 9 error invalid array assign
  • 如何生成源代码来创建我正在调试的对象?

    我的典型场景 我处理的遗留代码有一个错误 只有生产中的客户端才会遇到 我附加了一个调试器并找出如何重现该问题their系统给定their输入 但是 我还不知道为什么会发生错误 现在我想在本地系统上编写一个自动化测试来尝试重现然后修复错误 最
  • 如何在Python中按字母顺序对字符串中的字母进行排序

    有没有一种简单的方法可以在Python中按字母顺序对字符串中的字母进行排序 So for a ZENOVW 我想返回 ENOVWZ 你可以做 gt gt gt a ZENOVW gt gt gt join sorted a ENOVWZ
  • 如何从 PyEphem 获取物体的地球惯性或地心坐标?

    我想获得各种物体的坐标XYZ坐标 而不是它们出现在天空中的位置 我对 感兴趣 ECE 以地心为中心 惯性 https en wikipedia org wiki Earth centered inertial 不随地球自转 ECEF 以地心
  • 如何找到 AS3 中 xml 子级的数量

    所以现场文档说这是在 XML 对象上调用 length 对于 XML 对象 此方法始终 返回整数 1 length XMLList 类的方法返回一个 对于 XMLList 对象 值为 1 仅包含一个值 我在 xml 上调用它 如下所示
  • 什么是 .un~ 文件或者为什么终端中的 Vim 会创建 .un~ 文件?

    我注意到我有一些以 un 例如我有一个 vividchalk vim un 但我不确定它是从哪里来的 看起来它们是我在终端中使用 Vim 时创建的 这些文件是什么 当我关闭正在编辑的文件时 可以让它们自行删除吗 当你编辑和保存文件时 Vim
  • Scrapy仅抓取网站的一部分

    您好 我有以下代码来扫描给定站点中的所有链接 from scrapy item import Field Item from scrapy contrib spiders import CrawlSpider Rule from scrap
  • Python abc 模块:扩展抽象基类和异常派生类会导致令人惊讶的行为

    扩展抽象基类和从 对象 派生的类可以按照您的预期工作 如果您尚未实现所有抽象方法和属性 则会出现错误 奇怪的是 用扩展 Exception 的类替换对象派生类允许您创建不实现所有必需的抽象方法和属性的类的实例 例如 import abc T
  • 如何更改单选按钮与其文本之间的间距?

    我有以下 HTML
  • 在 MVC 控制器内打开 websocket 通道

    有没有人有在 MVC 控制器内打开 websocket 连接的良好经验 技术栈 ASPNET Core 1 0 RC1 MVC dnx46 System Net WebSockets 为什么使用 MVC 而不是中间件 为了整体一致性 路由
  • 使用 Rgraphviz 中的 pos 参数来固定节点位置

    基于这个问题当弧与另一弧重叠时自动弯曲 https stackoverflow com questions 45721802 automatically curving an arc when it is overlapping with
  • FireDac 添加下划线 1 以区分具有相同名称的 2 个列名

    我有一个连接 2 个表的选择 因此这些表中存在具有相似名称的列 因此现在在检索结果时 FireDac 将下划线 1 添加到第二个列名称以区分这两个表 Select from Table1 inner join Table2 on Table
  • Safari 不触发表单提交

    对于一个项目 我有两个选择表单字段 它们通过 jquery 触发器 提交 发送 这在 Firefox 和 Chrome 中运行良好 但在 Safari 中没有任何反应 这是 HTML 代码
  • UIScrollView 与 UIWebViews

    stackoverflow 上似乎有很多关于这个主题的问题 但没有一个涉及 3 0 中的更新 经过几个小时的研究后 我终于发现 完全支持嵌套滚动视图 在我的例子中是滚动视图内的网页视图 但是给出的示例在http developer appl