• IOS 特定于设备的开发:基于加速计的滚动视图


        倾斜滚轮使用设备的内置加速计来控制在UIScrollView的内容周围移动。当用户调增设备时,材料会相应的下落,他不会把视图定位在屏幕上,而是把内容视图滚动到一个新的偏移位置。

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

       作为代替,下面程序假定稳定的位置是通过z轴指向大约45度的方向,即用户把iPhone或iPad窝在手中的自然位置,这处于正面朝上和正面朝前方的中间位置。从这个歪斜的位置来回倾斜,使屏幕在调整期间保持最大的可见性。

       这个程序中的另一处改变是低得多加速常量。这使屏幕上的运动能够更慢的发生,让用户更容易降低速度并恢复导航。

    #define SIGN(_NUM_) ((_NUM_ < 0) ? (-1) : 1) 
    #define MIN(A,B) __NSMIN_IMPL__(A,B,__COUNTER__) 
    #define MAX(A,B) __NSMAX_IMPL__(A,B,__COUNTER__)
    
    @implementation TestBedViewController
    {
        UIScrollView *sv;
        
        float xoff;
        float xaccel;
        float xvelocity;
        
        float yoff;
        float yaccel;
        float yvelocity;
    }
    
    - (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);
        
        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) loadView
    {
        [super loadView];
        sv = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
        self.view = sv;
    }
    
    - (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;
                 
                 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];
             }];
         }];
    }
  • 相关阅读:
    在一台Linux服务器上安装多个MySQL实例(二)--使用单独的MySQL配置文件
    在一台Linux服务器上安装多个MySQL实例(一)--使用mysqld_multi方式
    MySQL复制(四)--多源(主)复制
    MySQL复制(三)--基于全局事物标识符(GTID)配置复制
    类加载机制详解
    字符串常量池理解
    JVM内存模型
    Java设计模式之单例模式
    forkjoin及其性能分析,是否比for循环快?
    集合排序Comparable和Comparator有什么区别?
  • 原文地址:https://www.cnblogs.com/haibosoft/p/4179048.html
Copyright © 2020-2023  润新知