내 뷰 컨트롤러의 iOS 7 시차 효과


112

Objective-C에서 iOS 7 용 앱을 개발 중입니다. 내 앱에는 몇 개의 버튼과 예쁜 배경 이미지가있는 화면이 있습니다. (이 UIButtons위에 있는 간단한 xib입니다 UIImageView.)

이 버튼이 iOS 7 홈 화면과 같은 시차 효과가 있으면 멋질 거라고 생각했는데, 휴대폰을 기울이면 배경이 보입니다.

내 앱에서 그 효과를 어떻게 구현할 수 있습니까?


1
이 도서관에서 찾아 보게 github.com/Przytua/UIView-MWParallax
CRDave

: SWIFT를 들어, 그와 시도 github.com/ArvindPrakashJoshi/AJParallaxEffect
아빈

답변:


273

iOS 7에서 Apple UIMotionEffect은 사용자 기기의 방향과 관련된 모션 효과를 추가하기 위해 도입 되었습니다. 예를 들어, 홈 화면에서 시차 효과를 에뮬레이션하려면 여기여기에UIInterpolationMotionEffect 설명 된대로 몇 줄의 코드만으로 하위 클래스를 사용할 수 있습니다 .

목표 -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 버전에이 기능을 추가 할 수있는 라이브러리를 찾을 수 있습니다.


2
NGAParallaxMotion은 이전 iOS 버전이 아닌 iOS 7 이상용입니다. UIView에 대한 범주를 제공하여 .parallaxIntensity 값을 설정하고 한 줄의 코드로 UIMotionEffect 매개 변수를 설정할 수 있습니다.
Dan Fabulich 2013 년

2
감사! 지원되는 버전 및 요구 사항을 포함하도록 답변을 업데이트했습니다.
veducm

1
실제로는 전면보기가 아닌 배경보기에 모션 효과를 추가하고 싶습니다. 하지만 그 외에는이 코드가 훌륭하게 작동합니다! 감사.
gstroup

1
사용자가 효과를 비활성화했는지 확인하는 방법을 아는 사람이 있습니까? stackoverflow.com/questions/19132000/...
에릭

3
@gstroup 사실, 홈 화면에서 전경과 배경이 모두 움직입니다. 그러나 시차 효과를 적용 할 레이어를 하나만 선택했다면 배경이 가장 좋을 것이라는 데 동의합니다.
Rubberduck 2014-01-08

16

누군가가 게으 르면 신속하게 번역됩니다. 유용하다고 생각되면 @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)
}

감사합니다 @Lucas! 빠른 샘플도 포함하도록 답변을 업데이트했습니다. 이것은 이것을 기반으로합니다. 자유롭게 검토하고 필요한 사항을 변경하십시오.
veducm

7

@veducm의 솔루션은 조금 더 짧을 수 있습니다. x 및 y 축 motionEffect를 별도로 추가하면 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];

2
그냥이 단축 버전을 사용하는 사람은, 최초의 모션 효과 요구가있을하는 경우까지 머리 등 typeUIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis하지 UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis가 코드에서와 같이 배치
Flexicoder

1
@BooHoo 그룹으로 추가하는 것은 더 이상 사용되지 않습니까? 어디에서 봅니까? 이 글을 쓰는 시점에서 Apple 문서에는 쓸모가 없다는 것이 없습니다. 그룹화의 전체 목적은 성능을 향상시키는 것입니다. 그룹의 모든 효과는 한 번만 렌더링됩니다. 별도로 적용 할 때는 별도로 렌더링해야합니다. 내가 틀렸다면 자유롭게 고쳐주세요. (그리고 그것에 대한 Apple의 문서를 알려주세요.)
David Lari

6
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];
     }
}

1
귀하의 제안에 따라 대답 업데이트 @ 롭
damithH

5

다음은 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

https://github.com/jvenegas/TLMotionEffect


1
이 링크가 질문에 답할 수 있지만 여기에 답변의 필수 부분을 포함하고 참조 용 링크를 제공하는 것이 좋습니다. 링크 된 페이지가 변경되면 링크 전용 답변이 무효화 될 수 있습니다.
마치에이 SWIC

여기에 전체 GitHub의 프로젝트를 통합하기 힘들 것입니다
Bejil에게

1
전체 프로젝트를 가져올 필요는 없으며 답변을 편집하여 보여준 것처럼 필수적인 부분 만 가져올 수 있습니다. 이것은 Github가 다운되거나 리포지토리를 당기거나 하늘이 무너지는 경우 코드가 계속 붙어 있도록하기위한 것입니다.
Maciej Swic 2014


3

이것은 tableView 또는 collectionView에 대한 시차를 구현하려는 사람을 도울 것입니다.

  • 우선 tableview에 대한 셀을 만들고 이미지보기를 그 안에 넣습니다.

  • 이미지 높이를 셀 높이보다 약간 높게 설정하십시오. 셀 높이 = 160이면 이미지 높이를 200으로 설정합니다 (시차 효과를 만들기 위해 그에 따라 변경할 수 있음).

  • 이 두 변수를 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 변수로 변경하십시오.

그리고 그게 다야. 이것이 최선의 방법인지 확실하지 않습니다. 그러나 그것은 나를 위해 작동합니다. 그것이 당신에게도 효과가 있기를 바랍니다. 문제가 있으면 알려주세요


2

복잡한 코드를 참조하는 이유는 정말 간단 합니다. 먹어봐.

imageview에서 이미지보기의 정확한 크기를 봅니다. 뷰 세트 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;
}

-1

신속한 번역 :

// 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.