Objective-CでiOS 7用のアプリを開発しています。アプリに、いくつかのボタンときれいな背景画像を備えた画面があります。(これは、とシンプルなのXIBだUIButtons
の上にUIImageView
。)
これらのボタンにiOS 7のホーム画面にある視差効果があるとすごくいいと思っていたので、電話を傾けると背景が見えるようになりました。
自分のアプリにその効果を実装するにはどうすればよいですか?
Objective-CでiOS 7用のアプリを開発しています。アプリに、いくつかのボタンときれいな背景画像を備えた画面があります。(これは、とシンプルなのXIBだUIButtons
の上にUIImageView
。)
これらのボタンにiOS 7のホーム画面にある視差効果があるとすごくいいと思っていたので、電話を傾けると背景が見えるようになりました。
自分のアプリにその効果を実装するにはどうすればよいですか?
回答:
iOS 7ではUIMotionEffect
、ユーザーのデバイスの向きに関連するモーション効果を追加するためにAppleが導入されました。たとえば、ホーム画面で視差効果をエミュレートするには、こことここでUIInterpolationMotionEffect
説明されているように、数行のコードだけでサブクラスを使用できます。
Objective-C:
// Set vertical effect
UIInterpolatingMotionEffect *verticalMotionEffect =
[[UIInterpolatingMotionEffect alloc]
initWithKeyPath:@"center.y"
type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
verticalMotionEffect.minimumRelativeValue = @(-10);
verticalMotionEffect.maximumRelativeValue = @(10);
// Set horizontal effect
UIInterpolatingMotionEffect *horizontalMotionEffect =
[[UIInterpolatingMotionEffect alloc]
initWithKeyPath:@"center.x"
type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
horizontalMotionEffect.minimumRelativeValue = @(-10);
horizontalMotionEffect.maximumRelativeValue = @(10);
// Create group to combine both
UIMotionEffectGroup *group = [UIMotionEffectGroup new];
group.motionEffects = @[horizontalMotionEffect, verticalMotionEffect];
// Add both effects to your view
[myBackgroundView addMotionEffect:group];
Swift(@Lucasに感謝):
// Set vertical effect
let verticalMotionEffect = UIInterpolatingMotionEffect(keyPath: "center.y",
type: .TiltAlongVerticalAxis)
verticalMotionEffect.minimumRelativeValue = -10
verticalMotionEffect.maximumRelativeValue = 10
// Set horizontal effect
let horizontalMotionEffect = UIInterpolatingMotionEffect(keyPath: "center.x",
type: .TiltAlongHorizontalAxis)
horizontalMotionEffect.minimumRelativeValue = -10
horizontalMotionEffect.maximumRelativeValue = 10
// Create group to combine both
let group = UIMotionEffectGroup()
group.motionEffects = [horizontalMotionEffect, verticalMotionEffect]
// Add both effects to your view
myBackgroundView.addMotionEffect(group)
また、これをより簡単に行うため、またはこの機能を古いiOSバージョンに追加するための多数のライブラリを見つけることができます。
だれか怠けている場合に備えて、迅速に翻訳されます。これが役に立ったと思ったら、@ veducmの回答に投票してください。
@IBOutlet var background : UIImageView!
func parallaxEffectOnBackground() {
let relativeMotionValue = 50
var verticalMotionEffect : UIInterpolatingMotionEffect = UIInterpolatingMotionEffect(keyPath: "center.y",
type: .TiltAlongVerticalAxis)
verticalMotionEffect.minimumRelativeValue = -relativeMotionValue
verticalMotionEffect.maximumRelativeValue = relativeMotionValue
var horizontalMotionEffect : UIInterpolatingMotionEffect = UIInterpolatingMotionEffect(keyPath: "center.x",
type: .TiltAlongHorizontalAxis)
horizontalMotionEffect.minimumRelativeValue = -relativeMotionValue
horizontalMotionEffect.maximumRelativeValue = relativeMotionValue
var group : UIMotionEffectGroup = UIMotionEffectGroup()
group.motionEffects = [horizontalMotionEffect, verticalMotionEffect]
self.background.addMotionEffect(group)
}
@veducmのソリューションは少し短くなる場合があります。x軸とy軸のmotionEffectsを個別に追加すると、そのxとyのモーションのUIMotionEffectGroupは廃止されます。
UIInterpolatingMotionEffect *motionEffect;
motionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x"
type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
motionEffect.minimumRelativeValue = @(-25);
motionEffect.maximumRelativeValue = @(25);
[bgView addMotionEffect:motionEffect];
motionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y"
type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
motionEffect.minimumRelativeValue = @(-25);
motionEffect.maximumRelativeValue = @(25);
[bgView addMotionEffect:motionEffect];
type
でUIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis
はなくUIInterpolatingMotionEffectTypeTiltAlongVerticalAxis
、それはコードのレイアウトであるとして
const static CGFloat kCustomIOS7MotionEffectExtent = 10.0;
- (void)applyMotionEffects:(UIView *YOUR_VIEW) {
if (NSClassFromString(@"UIInterpolatingMotionEffect")) {
UIInterpolatingMotionEffect *horizontalEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x"
type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
horizontalEffect.minimumRelativeValue = @(-kCustomIOS7MotionEffectExtent);
horizontalEffect.maximumRelativeValue = @( kCustomIOS7MotionEffectExtent);
UIInterpolatingMotionEffect *verticalEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y"
type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
verticalEffect.minimumRelativeValue = @(-kCustomIOS7MotionEffectExtent);
verticalEffect.maximumRelativeValue = @( kCustomIOS7MotionEffectExtent);
UIMotionEffectGroup *motionEffectGroup = [[UIMotionEffectGroup alloc] init];
motionEffectGroup.motionEffects = @[horizontalEffect, verticalEffect];
[YOUR_VIEW addMotionEffect:motionEffectGroup];
}
}
以下は、iOs7 +への影響を統合する簡単なカテゴリです。
NSString *const centerX = @"center.x";
NSString *const centerY = @"center.y";
//#define IS_OS_7_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
@implementation UIView (TLMotionEffect)
- (void)addCenterMotionEffectsXYWithOffset:(CGFloat)offset {
// if(!IS_OS_7_OR_LATER) return;
if(floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) return;
UIInterpolatingMotionEffect *xAxis;
UIInterpolatingMotionEffect *yAxis;
xAxis = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:centerX type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
xAxis.maximumRelativeValue = @(offset);
xAxis.minimumRelativeValue = @(-offset);
yAxis = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:centerY type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
yAxis.minimumRelativeValue = @(-offset);
yAxis.maximumRelativeValue = @(offset);
UIMotionEffectGroup *group = [[UIMotionEffectGroup alloc] init];
group.motionEffects = @[xAxis, yAxis];
[self addMotionEffect:group];
}
@end
UIMotionEffectは、iOS 7で無料の視差の実装を提供します。
http://www.teehanlax.com/blog/introduction-to-uimotioneffect/
https://github.com/michaeljbishop/NGAParallaxMotionを使用すると、視差強度を設定できます。
これは、tableViewまたはcollectionViewに視差を実装しようとしているユーザーを支援します。
まず、テーブルビューのセルを作成し、その中にイメージビューを配置します。
画像の高さをセルの高さよりわずかに高く設定します。セルの高さ= 160の場合、画像の高さを200にします(視差効果を作成し、それに応じて変更できます)。
この2つの変数を、viewControllerまたはtableViewデリゲートが拡張されているクラスに配置します。
let imageHeight:CGFloat = 150.0
let OffsetSpeed: CGFloat = 25.0
- 同じクラスに次のコードを追加します
func scrollViewDidScroll(scrollView: UIScrollView) {
// print("inside scroll")
if let visibleCells = seriesTabelView.visibleCells as? [SeriesTableViewCell] {
for parallaxCell in visibleCells {
var yOffset = ((seriesTabelView.contentOffset.y - parallaxCell.frame.origin.y) / imageHeight) * OffsetSpeedTwo
parallaxCell.offset(CGPointMake(0.0, yOffset))
}
}
}
ここで、seriesTabelViewは私のUItableviewです
そして今、このtableViewのセルに移動して、次のコードを追加します
func offset(offset: CGPoint) {
posterImage.frame = CGRectOffset(self.posterImage.bounds, offset.x, offset.y)
}
- あったposterImageは私のUIImageViewです
これをcollectionViewに実装したい場合は、tableView vairableをcollectionView変数に変更してください
以上です。これが最善の方法かどうかはわかりません。しかし、それは私にとってはうまくいきます。それもあなたのために働くことを願っています。問題があったら教えてください
本当に簡単にできるので、なぜ複雑なコードを参照するのでしょうか。やってみなよ。ワーキング
imageviewの画像を正確にsize of image viewで表示します。デフォルトでは、ビューセット0のアルファ。
//MARK: Scroll View Delegate methods
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
NSLog(@"X: %f Y: %f",scrollView.contentOffset.x,scrollView.contentOffset.y);
CGFloat scrollY = _mainScrollView.contentOffset.y;
CGFloat height = _alphaView.frame.size.height;
CGFloat alphaMonitor = scrollY/height;
_alphaView.alpha = alphaMonitor;
}
迅速な翻訳:
// Set vertical effect
let verticalMotionEffect = UIInterpolatingMotionEffect(keyPath: "center.y", type: .TiltAlongVerticalAxis)
verticalMotionEffect.minimumRelativeValue = -value
verticalMotionEffect.maximumRelativeValue = value
// Set vertical effect
let horizontalMotionEffect = UIInterpolatingMotionEffect(keyPath: "center.x", type: .TiltAlongHorizontalAxis)
verticalMotionEffect.minimumRelativeValue = -value
verticalMotionEffect.maximumRelativeValue = value
let group = UIMotionEffectGroup()
group.motionEffects = [horizontalMotionEffect, verticalMotionEffect]
self.motionEffect = group
self.addMotionEffect(group)