【问题标题】:Static background image location in obj-c (similar to background-attachment: fixed)obj-c 中的静态背景图片位置(类似于 background-attachment:fixed)
【发布时间】:2013-09-29 11:06:21
【问题描述】:

我正在尝试创建一个视图,无论它如何移动,都会将其背景图像保持在同一位置。因此,如果拖动视图,背景会保持不变,类似于 css3 中的background-attachment:fixed。

我的问题是clipsToBounds = YES 似乎不起作用。图像仍然占据整个屏幕并且不会被剪辑到父框架。有什么想法吗?

@implementation StaticBackgroundView {
    UIImageView *imageView;
}

// Must be init'd from code or won't work
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"myImage.png"]];
        imageView.clipsToBounds = YES;
        self.clipsToBounds = YES;

        [self addSubview:imageView];
        [self sendSubviewToBack:imageView];
    }
    return self;
}

- (void) setFrame:(CGRect)frame
{
    // Call the parent class to move the view
    [super setFrame:frame];

    // Do your custom code here.
    NSLog(@"Setframe");
    imageView.frame = CGRectMake(-1*frame.origin.x, frame.origin.y, imageView.frame.size.width, imageView.frame.size.height);
}

【问题讨论】:

    标签: ios objective-c css


    【解决方案1】:

    每当 StaticBackgroundView 移动时 - 背景图像中心也必须调整。

    在下面给出的示例中,每次在 PanGesture 更新期间移动 StaticBackgroundView 时都会调用 updateBackgroundImage。

    -(void)updateBackgroundImage
    {
        imageView.center = CGPointMake(( (imageView.image.size.width*0.5) - self.center.x) + (self.bounds.size.width*0.5)
                                   ,     ((imageView.image.size.height*0.5) - self.center.y) + (self.bounds.size.height*0.5));
    }
    

    如果您将 StaticBackgroundView 向右移动,图像将向左移动,并且在 StaticBackgroundView 下方看起来保持静止。

    下面的示例代码允许您使用手指移动 StaticBackgroundView 并在下方显示静态图像:

    StaticBackgroundView.h

    #import <UIKit/UIKit.h>
    @interface StaticBackgroundView : UIView
    -(void)updateBackgroundImage;
    @end
    

    StaticBackgroundView.m

    #import "StaticBackgroundView.h"
    
    @implementation StaticBackgroundView {
        UIImageView *imageView;
    }
    
    // Must be init'd from code or won't work
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            NSLog(@"StaticBackgroundView:initWithFrame");
    
            if([[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPhone)
            {
                if ([[UIScreen mainScreen] bounds].size.height == 568)
                {
                    NSLog(@"iPhone5 image");
                    imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"myImage-568h"]];
                }
                else
                {
                    NSLog(@"iPhone4 image");
                    imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"myImage"]];
                }
            }
            self.clipsToBounds = YES;
            [self updateBackgroundImage];
            [self addSubview:imageView];
            [self sendSubviewToBack:imageView];
        }
        return self;
    }
    
    -(void)updateBackgroundImage
    {
        imageView.center = CGPointMake(( (imageView.image.size.width*0.5) - self.center.x) + (self.bounds.size.width*0.5)
                                   ,     ((imageView.image.size.height*0.5) - self.center.y) + (self.bounds.size.height*0.5));
    }
    

    ViewController.m

    #import "ViewController.h"
    #import "StaticBackgroundView.h"
    
    @interface ViewController ()
    
    @property (strong, nonatomic)  StaticBackgroundView *outletStaticView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    
        self.outletStaticView = [[StaticBackgroundView alloc] initWithFrame:CGRectMake(100, 100, 120, 150)];
        [self.view addSubview:self.outletStaticView];
    
        UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    
        [self.outletStaticView addGestureRecognizer:panGestureRecognizer];
    }
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    
    -(void)handlePan:(UIPanGestureRecognizer *)gestureRecognizer
    {
    
        if([gestureRecognizer state] == UIGestureRecognizerStateChanged)
        {
    
            CGPoint translation = [gestureRecognizer translationInView:self.view];
    
            gestureRecognizer.view.center = CGPointMake(gestureRecognizer.view.center.x + translation.x, gestureRecognizer.view.center.y + translation.y);
    
            [gestureRecognizer setTranslation:CGPointMake(0, 0) inView:self.view];
    
            StaticBackgroundView * theView = (StaticBackgroundView*)gestureRecognizer.view;
            [theView updateBackgroundImage];
    
        }
    
    }
    @end
    

    【讨论】:

    • 如果我关心的视图是平移的目标,这没关系,但如果另一个视图完全是位置变化的原因呢?或者如果视图是动画的?
    • 你在吗?有什么想法可以解决这个问题吗?
    • 如果视图是动画,那么你就不走运了。您只能获取开始和结束动画转换数据 - 而不是在制作动画时
    • 如果另一个视图导致更改,则相应地调整handlePan。另一个视图的平移值会调整静态背景视图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    • 2012-08-21
    • 2015-03-10
    相关资源
    最近更新 更多