《iOS 6高级开发手册(第4版)》——1.9节秘诀:基于加速计的滚动视图

1.9 秘诀:基于加速计的滚动视图
iOS 6高级开发手册(第4版)
好几位读者要求我在本书这一版中包括进一个倾斜滚轮秘诀。倾斜滚轮使用设备的内置加速计来控制在UIScrollView的内容周围的移动。当用户调整设备时,材料会相应地“下落”。它不会把视图定位在屏幕上,而是把内容视图滚动到一个新的偏移位置。

创建这个界面的挑战在于:确定设备在什么地方应该具有它的静止轴(resting axis)。大多数人最初建议当显示屏靠着它的背部时应该是稳定的,并且z轴方向笔直地指向上方。事实证明:这实际上是一种相当糟糕的设计选择。要使用那根轴,就意味着在导航期间屏幕必须实际地偏离观看者。随着设备旋转离开视图,用户将不能完全看到屏幕上所发生的事情,尤其是在固定的位置使用设备时,站在高处查看设备有时也会产生这种效果。

作为替代,秘诀1-5假定稳定的位置是通过z轴指向大约45°的方向,即用户把iPhone或iPad握在手中的自然位置,这处于正面朝上和正面朝前方的中间位置。对秘诀1-5中的数学运算做了相应的调整。从这个歪斜的位置来回倾斜,使屏幕在调整期间保持最大的可见性。

与秘诀1-4相比,这个秘诀中的另一处改变是低得多的加速常量。这使屏幕上的运动能够更慢地发生,让用户更容易降低速度并恢复导航。

秘诀1-5 倾斜滚轮

- (void)accelerometer:(UIAccelerometer *)accelerometer
    didAccelerate:(UIAcceleration *)acceleration
{
    // extract the acceleration components
    float xx = -acceleration.x;
    float yy = (acceleration.z + 0.5f) * 2.0f; // between face-up and face-forward

    // Has the direction changed?
    float accelDirX = SIGN(xvelocity) * -1.0f;
    float newDirX = SIGN(xx);
    float accelDirY = SIGN(yvelocity) * -1.0f;
    float newDirY = SIGN(yy);

    // Accelerate. To increase viscosity lower the additive value
    if (accelDirX == newDirX) xaccel = (abs(xaccel) + 0.005f) * SIGN(xaccel);
    if (accelDirY == newDirY) yaccel = (abs(yaccel) + 0.005f) * SIGN(yaccel);

    // Apply acceleration changes to the current velocity
    xvelocity = -xaccel * xx;
    yvelocity = -yaccel * yy;
    }

- (void) tick
{
    xoff += xvelocity;
    xoff = MIN(xoff, 1.0f);
    xoff = MAX(xoff, 0.0f);

    yoff += yvelocity;
    yoff = MIN(yoff, 1.0f);
    yoff = MAX(yoff, 0.0f);

    // update the content offset based on the current velocities
    CGFloat xsize = sv.contentSize.width - sv.frame.size.width;
    CGFloat ysize = sv.contentSize.height - sv.frame.size.height;
    sv.contentOffset = CGPointMake(xoff * xsize, yoff * ysize);
}

- (void) viewDidAppear:(BOOL)animated
{
    NSString *map = @"http://maps.weather.com/images/\
        maps/current/curwx_720x486.jpg";
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        [queue addOperationWithBlock:
        ^{
            // Load the weather data
            NSURL *weatherURL = [NSURL URLWithString:map];
                NSData *imageData = [NSData dataWithContentsOfURL:weatherURL];
            // Update the image on the main thread using the main queue
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                UIImage *weatherImage = [UIImage imageWithData:imageData];
                UIImageView *imageView =
                    [[UIImageView alloc] initWithImage:weatherImage];
                CGSize initSize = weatherImage.size;
                CGSize destSize = weatherImage.size;
                // Ensure that the content size is significantly bigger
                // than the screen can show at once
                    while ((destSize.width < (self.view.frame.size.width * 4)) ||
                           (destSize.height < (self.view.frame.size.height * 4)))
                    {
                        destSize.width += initSize.width;
                        destSize.height += initSize.height;
                    }

                    imageView.userInteractionEnabled = NO;
                    imageView.frame = (CGRect){.size = destSize};
                    sv.contentSize = destSize;

                    [sv addSubview:imageView];

                    // Activate the accelerometer
                    [[UIAccelerometer sharedAccelerometer] setDelegate:self];

                    // Start the physics timer
                    [NSTimer scheduledTimerWithTimeInterval: 0.03f
                        target: self selector: @selector(tick)
                        userInfo: nil repeats: YES];
                }];
        }];
}

获取这个秘诀的代码

要查找这个秘诀的完整示例项目,可以浏览https://github.com/erica/iOS-6-Advanced-Cookbook,并进入第1章的文件夹。

时间: 2024-08-31 10:34:02

《iOS 6高级开发手册(第4版)》——1.9节秘诀:基于加速计的滚动视图的相关文章

《iOS 6高级开发手册(第4版)》——1.4节秘诀:取回额外的设备信息

1.4 秘诀:取回额外的设备信息 iOS 6高级开发手册(第4版) sysctl()和sysctlbyname()允许获取系统信息.这些标准的UNIX函数用于询问操作系统有关硬件和OS的详细信息.看一眼Macintosh上的/usr/include/sys/sysctl.h包括文件,就能对所提供的范围类型有一个感觉.在那里,能够找到一份可以用作这些函数的参数常量的详尽列表. 这些常量使你能够检查核心信息,比如系统的CPU频率.可用的内存量等.秘诀1-2演示了这种功能.它引入了一个UIDevice

《iOS 6高级开发手册(第4版)》——2.8节秘诀:声明文档支持

2.8 秘诀:声明文档支持 iOS 6高级开发手册(第4版) 应用程序文档并不仅限于它们创建或者从Internet下载的文件.如你在前一个秘诀中所发现的,应用程序可能处理某些文件类型.它们可能打开从其他应用程序传递过来的项目.你已经从发送方的角度见过了文档共享,它使用"open in"(打开在)控制器把文件导出到其他应用程序.现在应该从接收方的角度探讨它. 应用程序在它们的Info.plist属性列表中声明它们对某些文件类型的支持.Launch Services(启动服务)系统将读取该

《iOS 6高级开发手册(第4版)》——2.5节秘诀:Quick Look预览控制器

2.5 秘诀:Quick Look预览控制器 iOS 6高级开发手册(第4版) Quick Look预览控制器类允许用户预览许多文档类型.这个控制器支持文本.图像.PDF.RTF.iWork文件.Microsoft Office文档(Office 97及更高版本,包括doc.ppt.xls等)和逗号分隔的值(comma-separated value,csv)文件.你提供一种受支持的文件类型,Quick Look控制器将为用户显示它.集成的系统提供的活动视图控制器有助于共享预览的文档,如图2-6

《iOS 6高级开发手册(第4版)》——2.9节秘诀:创建基于URL的服务

2.9 秘诀:创建基于URL的服务 iOS 6高级开发手册(第4版) Apple的内置应用程序提供了多种可以通过URL调用访问的服务.可以要求Safari打开Web页面,让Maps显示一幅地图,或者使用mailto:风格的URL开始在Mail中撰写一封信件.URL模式指出现在冒号之前的URL的第一部分,比如http或ftp. 这些服务可以工作,因为iOS知道如何将URL模式匹配到应用程序.以http:开头的URL将在Mobile Safari中打开.mailto:URL总会链接到Mail.你可能

《iOS 6高级开发手册(第4版)》——1.2节添加设备能力限制

1.2 添加设备能力限制 iOS 6高级开发手册(第4版) 应用程序的Info.plist属性列表使你能够在向iTunes提交应用程序时指定应用程序的要求.这些限制允许告诉iTunes应用程序需要哪些设备特性. 每个iOS单元都会提供一个独特的特性集.一些设备会提供照相机和GPS能力,另外一些则不会.一些设备具有机载陀螺仪.自动聚焦,以及其他强大的选项.你可以指定在设备上运行应用程序时需要哪些特性. 在Info.plist文件中包括UIRequiredDeviceCapabilities键时,i

《iOS 6高级开发手册(第4版)》——2.3节秘诀:监测Documents文件夹

2.3 秘诀:监测Documents文件夹 iOS 6高级开发手册(第4版) iOS文档并没有受困在它们的沙盒中,你可以并且应该与用户共享它们.应该允许用户直接控制他们的文档,以及访问他们可能在设备上创建的任何资料.一个简单的Info.plist设置将使iTunes能够显示用户的Documents文件夹的内容,并使那些用户能够根据需要添加和删除资料. 在将来某个时间,你可能使用一个简单的NSMetadataQuery监测器来监视Documents文件夹并报告更新.在编写本书时,元数据监视还没有扩

《iOS 6高级开发手册(第4版)》——1.14节跟踪用户

1.14 跟踪用户 iOS 6高级开发手册(第4版) 跟踪是开发者的一种不幸的现实生活.Apple不赞成使用UIDevice属性,该属性提供了绑定到设备硬件的唯一标识符.Apple利用两个标识符属性取代UIDevice属性.它使用identifierForAdvertising属性返回当前设备所独有的一个特定于设备的字符串,并使用identifierForVendor属性提供一个绑定到每位应用程序供应商的字符串.无论使用的是哪个应用程序,这都应该会返回相同的唯一字符串,它不是顾客id.不同设备上

《iOS 6高级开发手册(第4版)》——2.7节秘诀:使用文档交互控制器

2.7 秘诀:使用文档交互控制器 iOS 6高级开发手册(第4版) UIDocumentInteractionController类允许应用程序给用户展示一个选项菜单,允许他们以各种方式使用文档文件,利用这个类,用户可以利用以下特性. iOS应用程序之间的文档共享(即"在某个应用程序中打开这个文档"). 使用QuickLook进行文档预览. 活动控制器选项,比如打印.共享和社交网络. 你已经在本章前面的动作中见过后两种特性.文档交互类在这些特性顶部添加了应用程序间的共享,如图2-7所示

《iOS 6高级开发手册(第4版)》——1.10节秘诀:Core Motion基础

1.10 秘诀:Core Motion基础 iOS 6高级开发手册(第4版) Core Motion框架集中了运动数据处理.该框架是在iOS 4 SDK中引入的,用于取代你刚才阅读到的直接加速计访问.它提供了对3个关键的机载传感器的集中式监测.这些传感器由陀螺仪.磁力计和加速计组成,其中陀螺仪用于测量设备的旋转,磁力计提供了一种测量罗盘方位的方式,加速计用于检测沿着3根轴的重力变化.第四个入口点称为设备移动(device motion),它把全部3种传感器都结合进单个监测系统中. Core Mo

《iOS 6高级开发手册(第4版)》——1.7节同步获取当前的加速计角度

1.7 同步获取当前的加速计角度iOS 6高级开发手册(第4版)有时,你可能想在不用把自己设定为完全委托的情况下查询加速计.下面的方法打算在UIDevice类别内使用,允许与x/y平面(iOS设备的正面)一起同步返回当前的设备角度.为此,可输入一个新的运行循环,等待加速计事件,从那个回调中获取当前的角度,然后让运行循环返回那个角度: - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAccelerati