2014-09-12 43 views
2

使用UIInterpolatingMotionEffect,扭轉iPhone,並且可以移動圖像。「推」匹配UIInterpolatingMotionEffect? (即在UIInterpolatingMotionEffect上訪問「物理」)

現在想象一下,使用UICollisionBehavior和UIDynamicItemBehavior,您將在屏幕上「反彈」紅色塊。當用戶扭曲iPhone時:我希望這些盒子能夠用「SIMILAR PHYSICS FEEL」開始移動,以使用UIInterpolatingMotionEffect。

http://tinypic.com/player.php?v=b67mlc%3E&s=8#.VBVEq0uZNFx

旁白:UX解釋:有彈性的效果(例如:短信在iPhone上)具有相同的「感覺」作爲iOS的視差圖像效果。 (通過「感覺」我的意思是相同的速度,加速度。)這將是第三個效果:就像視差它會「稍微移動一些東西」,但它們會「繼續移動」,反彈一點。 (可以說,有點結合了彈性列表效果和視差圖像效果的感覺。)

現在:使用CMAccelerometerData進行描述並使用UIPushBehaviorModeInstantaneous應用推送相對容易。但是這是很多雜亂的代碼。

相比之下,UIInterpolatingMotionEffect是可笑容易使用。

本質上,我怎樣才能從UIInterpolatingMotionEffect(我將作爲推送使用)獲取值。乾杯!


類似的想法...

Simply display the values of UIInterpolatingMotionEffect?

它要求簡單地說:怎麼能輕易地從UIInterpolatingMotionEffect 「只得到」 的價值觀?即看起來不可思議的人必須去仔細分類CALayer等。

+0

是的,我不知道鏈接到加速度計的任何UIKit動態行爲,所以您可能仍然需要通過'CMMotionManager'過程。順便說一下,我不確定我會採用與加速度計信息相關的推送,而是根據「CMMotionManager」信息調整「UIGravityBehavior」或「UIAttachmentBehavior」。這取決於所需的UX。我猜你也可以在設備傾斜度達到某個閾值時進行推動,但這不是我想要吸引的用戶體驗(沒有雙關語意圖)。 – Rob 2014-09-13 17:12:29

+0

您可能會建議如何簡化代碼,您可能希望將代碼的重要部分添加到您的問題中。這也可能使所需的用戶體驗更清晰一些,因爲我很難與UIPushBehavior協調「類似於UIInterpolatingMotionEffect」(就像我說的,它感覺更像是一個「改變的附件」而不是「推送」 )。 – Rob 2014-09-13 17:16:52

+0

R ...(1)非常感謝百萬對重力/附件的建議,我會徹底嘗試這種方法。 (2)注意,確實,相關問題可能是對問題的更好表達。 (一旦我獲得這些價值,我很容易「知道該做什麼」;看起來不可思議,但很難獲得這些價值!)(3)重新體現「UX價值」 - 我在問題中添加了幾個詞語和視頻。當然,人們可以看到iOS中的短信推送效應和iOS中的視差bg效應,因爲完全無用而愚蠢(許多消費者確實感覺到這一點)。當然「這只是一種效果」) – Fattie 2014-09-14 07:40:27

回答

3

這是一個有趣的想法,通過UIInterpolatingMotionEffect來更新某些行爲,但我並不認爲它是爲此設計的。如果你想根據加速度計信息更新行爲,我個人會認爲CMMotionManager是理想的。

所需的用戶體驗在視頻剪輯中並不完全清晰,但看起來像視頻讓手機沿傾斜方向繼續滑動,直到您停止傾斜手機。如果這是你想要什麼,我傾向於用UIKit的動態UIGravityBehavior結婚CMMotionManager

self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:container]; 

UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:container.subviews]; 
collision.translatesReferenceBoundsIntoBoundary = YES; 
[self.animator addBehavior:collision]; 

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:container.subviews]; 
gravity.gravityDirection = CGVectorMake(0, 0); 
[self.animator addBehavior:gravity]; 

self.motionManager = [[CMMotionManager alloc] init]; 

typeof(self) __weak weakSelf = self; 

[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) { 
    if (weakSelf.referenceAttitude == nil) { 
     weakSelf.referenceAttitude = motion.attitude; 
    } else { 
     CMAttitude *attitude = motion.attitude; 
     [attitude multiplyByInverseOfAttitude:weakSelf.referenceAttitude]; 
     gravity.gravityDirection = CGVectorMake(attitude.roll * 5.0, attitude.pitch * 5.0); 
    } 
}]; 

如果你希望他們根據的態度精確地移動,停止運動,當你停止移動設備(像UIInterpolatingMotionEffect一樣),你可以使用一個UIAttachmentBehavior,是這樣的:

UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:viewToAttachTo attachedToAnchor:viewToAttachTo.center]; 
[self.animator addBehavior:attachment]; 

self.motionManager = [[CMMotionManager alloc] init]; 
self.motionManager.deviceMotionUpdateInterval = 1.0/20.0; 

typeof(self) __weak weakSelf = self; 

CGPoint originalAnchorPoint = viewToAttachTo.center; 

[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) { 
    if (weakSelf.referenceAttitude == nil) { 
     weakSelf.referenceAttitude = motion.attitude; 
    } else { 
     CMAttitude *attitude = motion.attitude; 
     [attitude multiplyByInverseOfAttitude:weakSelf.referenceAttitude]; 
     attachment.anchorPoint = CGPointMake(originalAnchorPoint.x + attitude.roll * 10.0, originalAnchorPoint.y + attitude.pitch * 10.0); 
    } 
}]; 

注意,在這兩個的這些例子,我從當設備的方向施加調整行爲作爲設備轉移用戶啓動了應用程序。因此,我捕獲了CMAttitude屬性,referenceAttitude是用戶啓動應用程序時設備的態度,然後在後續更新中使用multiplyByInverseOfAttitude以應用與原始方向有關的重力。顯然,如果你想要的話,你也可以採用預定的態度。

但希望上面說明了解決這種UX的一種方法。

+0

不可思議的示例代碼謝謝!我會嘗試一下並進行比較。作爲一個好奇心,我會把目前我們精煉的代碼放進去,它在任何「塊塊」上看起來都很棒。 – Fattie 2014-09-20 15:13:03

+0

精彩的回答,請記住一個注意事項 - 「因爲處理過的事件可能以高速率到達,所以不推薦使用主操作隊列。」 – Rizon 2015-04-25 00:30:51

+0

同意。你可以使用'deviceMotionUpdateInterval'(就像我的第二個例子)或者使用後臺隊列(但是如果你使用後臺隊列,那麼不要只是轉過頭去發送更新回主隊列;你必須使用調度源或其他從運動事件中分離UI更新的機制)。 – Rob 2015-04-26 13:48:57