你說你的圖像是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