你说你的图像是2048宽,你的观点是1024宽。我不知道这是否意味着您已经复制了1024宽度图像的内容以制作2048宽度图像。
无论如何,这是我的建议。我们需要云层和动画保存在实例变量:
@implementation ViewController {
CALayer *cloudLayer;
CABasicAnimation *cloudLayerAnimation;
}
而不是设置云图层的内容到云端形象,我们设置它的背景颜色从图像创建的图案颜色。这样一来,我们就可以设置为任何我们想要的图层边界和图像将被平铺,填补了界限:
-(void)cloudScroll {
UIImage *cloudsImage = [UIImage imageNamed:@"TitleClouds.png"];
UIColor *cloudPattern = [UIColor colorWithPatternImage:cloudsImage];
cloudLayer = [CALayer layer];
cloudLayer.backgroundColor = cloudPattern.CGColor;
然而,CALayer的坐标系统将把原点在左下角,而不是左上角, Y轴增加。这意味着该模式将被颠倒。我们可以解决这个问题通过翻转Y轴:
cloudLayer.transform = CATransform3DMakeScale(1, -1, 1);
默认情况下,图层的锚点是在它的中心。这意味着设置图层的位置设置了其中心的位置。通过设置左上角的位置来定位图层会更容易。我们可以这样做,通过其锚点移动到其左上角:
cloudLayer.anchorPoint = CGPointMake(0, 1);
该层的宽度必须是图像的宽度加上含有视图的宽度。这样,当我们滚动图层以便图像的右边缘可见时,图像的另一个副本将被绘制到第一个副本的右边。
CGSize viewSize = self.cloudsImageView.bounds.size;
cloudLayer.frame = CGRectMake(0, 0, cloudsImage.size.width + viewSize.width, viewSize.height);
现在,我们已经准备好了层添加到视图:
[self.cloudsImageView.layer addSublayer:cloudLayer];
现在让我们设置了动画。记住我们改变了图层的锚点,所以我们可以通过设置左上角的位置来控制它的位置。我们希望层的左上角,以在视图的左上角开始:
CGPoint startPoint = CGPointZero;
,我们要移动的图像的宽度离开层的左上角:
CGPoint endPoint = CGPointMake(-cloudsImage.size.width, 0);
动画设置的其余部分与您的代码相同。我改变了持续时间为3秒来进行测试:
cloudLayerAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
cloudLayerAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
cloudLayerAnimation.fromValue = [NSValue valueWithCGPoint:startPoint];
cloudLayerAnimation.toValue = [NSValue valueWithCGPoint:endPoint];
cloudLayerAnimation.repeatCount = HUGE_VALF;
cloudLayerAnimation.duration = 3.0;
我们将调用另一个方法将动画实际连接到层:
[self applyCloudLayerAnimation];
}
下面是应用动画的方法:
- (void)applyCloudLayerAnimation {
[cloudLayer addAnimation:cloudLayerAnimation forKey:@"position"];
}
当应用程序进入后台(因为用户切换到另一个应用程序),系统会从云层中移除动画。所以当我们再次进入前景时我们需要重新附加它。这就是为什么我们有applyCloudLayerAnimation
方法。我们需要在应用程序进入前台时调用该方法。
在viewDidAppear:
,我们就可以开始观测应用已经进入前台,它告诉我们的通知:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
我们需要停止观察通知时,我们的视野中消失,或者当视图控制器被释放:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
}
当视图控制器实际收到通知,我们需要重新申请动画:
- (void)applicationWillEnterForeground:(NSNotification *)note {
[self applyCloudLayerAnimation];
}
这里的所有代码放在一起,便于复制和粘贴:
- (void)viewDidLoad {
[self cloudScroll];
[super viewDidLoad];
}
-(void)cloudScroll {
UIImage *cloudsImage = [UIImage imageNamed:@"TitleClouds.png"];
UIColor *cloudPattern = [UIColor colorWithPatternImage:cloudsImage];
cloudLayer = [CALayer layer];
cloudLayer.backgroundColor = cloudPattern.CGColor;
cloudLayer.transform = CATransform3DMakeScale(1, -1, 1);
cloudLayer.anchorPoint = CGPointMake(0, 1);
CGSize viewSize = self.cloudsImageView.bounds.size;
cloudLayer.frame = CGRectMake(0, 0, cloudsImage.size.width + viewSize.width, viewSize.height);
[self.cloudsImageView.layer addSublayer:cloudLayer];
CGPoint startPoint = CGPointZero;
CGPoint endPoint = CGPointMake(-cloudsImage.size.width, 0);
cloudLayerAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
cloudLayerAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
cloudLayerAnimation.fromValue = [NSValue valueWithCGPoint:startPoint];
cloudLayerAnimation.toValue = [NSValue valueWithCGPoint:endPoint];
cloudLayerAnimation.repeatCount = HUGE_VALF;
cloudLayerAnimation.duration = 3.0;
[self applyCloudLayerAnimation];
}
- (void)applyCloudLayerAnimation {
[cloudLayer addAnimation:cloudLayerAnimation forKey:@"position"];
}
- (void)viewDidUnload {
[self setCloudsImageView:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
}
- (void)applicationWillEnterForeground:(NSNotification *)note {
[self applyCloudLayerAnimation];
}
如何让这个循环在从后台返回后继续(最小化应用程序)? – Mutawe 2012-11-05 13:40:52