您现在的位置是:首页 > 文章详情

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

日期:2017-05-01点击:214

本节书摘来自异步社区《iOS 6高级开发手册(第4版)》一书中的第1章,第1.9节秘诀:基于加速计的滚动视图,作者 【美】Erica Sadun,更多章节内容可以访问云栖社区“异步社区”公众号查看

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章的文件夹。

原文链接:https://yq.aliyun.com/articles/97351
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章