1

次のコードを使用して、 UISwipeGestureRecognizerで左右にスワイプし、iPhoto と同様の方法でアプリに写真を表示します。

    CATransition *animation = [CATransition animation];
    [animation setDuration:0.5];
    [animation setType:kCATransitionPush];
    [animation setSubtype:kCATransitionFromRight];
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    [[self.imageHolder layer] addAnimation:animation forKey:@"SwitchToView"];

これにより、下の図に示すように、次の画像がスライドインされ、古い画像がスライドアウトされます。

画像 1:

画像 1

遷移:

移行ビュー

画像 2:

画像 2

これを iPhoto のように作成する方法を考えていたときに、代わりにUIPanGestureRecognizerを使用する必要があります。

iPhoto と同じように、指でアニメーションを「制御」する必要があります。つまり、次の画像へのドラッグを開始してから、ドラッグ方向を逆にすることができます。また、iPhoto と同様に、最初の画像よりも多くの次の画像が表示されているときに指を離すと、次の画像がスライドインするようにします (これは上の遷移図では発生していません。 iPhoto のこの時点で私の指をスライドさせると、最初の画像に戻ります。

私は以前にUIPanGestureRecognizerを使用したことがないので、誰かが私を助けてくれればそれは素晴らしいことです.

編集:

Leviから提供されたコードを使用して、3 つのサンプル画像でうまく機能するソリューションを作成しました。UIPanGestureRecognizerの使用に興味がある他の人にとって、コードは次のとおりです。

インターフェース:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UIGestureRecognizerDelegate>
{
int imageIndex;
}

@property (nonatomic, strong) UIImageView* imageView;
@property (nonatomic, strong) UIImageView* leftImageView;
@property (nonatomic, strong) UIImageView* rightImageView;

@end

実装:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
[super viewDidLoad];

self->imageIndex = 0;

float xFactor;

UIInterfaceOrientation currentOrientation = self.interfaceOrientation;
if(UIInterfaceOrientationIsLandscape(currentOrientation)){

    xFactor = 256;

}
else{

    xFactor = 0;

}

self.imageView = [[UIImageView alloc] initWithFrame:self.view.frame];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.imageView.image = [UIImage imageNamed:@"69B4356B-1CB2-4A2F-867E-9C086251DF11-12668-0000036A534E9B6D"];
self.imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

CGRect leftFrame = self.view.frame;
leftFrame.origin.x -= leftFrame.size.width+xFactor;
self.leftImageView = [[UIImageView alloc] initWithFrame:leftFrame];
self.leftImageView.contentMode = UIViewContentModeScaleAspectFit;
self.leftImageView.image = [UIImage imageNamed:@"42517D93-F8BF-42E7-BB44-53B099A482AA-12668-0000036A49BCECAA"];
self.leftImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

CGRect rightFrame = self.view.frame;
rightFrame.origin.x += rightFrame.size.width+xFactor;
self.rightImageView = [[UIImageView alloc] initWithFrame:rightFrame];
self.rightImageView.contentMode = UIViewContentModeScaleAspectFit;
self.rightImageView.image = [UIImage imageNamed:@"C6AC2508-243B-464B-A71F-96DD7F18673D-12668-00000369F3AFD3FC"];
self.rightImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

[self.view addSubview:self.imageView];
[self.view addSubview:self.leftImageView];
[self.view addSubview:self.rightImageView];

UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[self.view addGestureRecognizer:recognizer];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];

}

- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateEnded) {
    CGRect leftFrame = self.leftImageView.frame;
    CGRect currentFrame = self.imageView.frame;
    CGRect rightFrame = self.rightImageView.frame;

    float duration = 0.0;

    float factor;

    UIInterfaceOrientation currentOrientation = self.interfaceOrientation;
    if(UIInterfaceOrientationIsPortrait(currentOrientation)){

        factor = 768;
    }
    else{
        factor = 1024;
    }

    if (self.imageView.center.x < 0) { // Present the right image
        duration = 0.3 * ABS(self.rightImageView.frame.origin.x / factor);
        leftFrame.origin.x = -2 * factor;
        currentFrame.origin.x = -1 * factor;
        rightFrame.origin.x = 0;
        self->imageIndex = 1;

    } else if (self.imageView.center.x > factor) { // Present the left image
        duration = 0.3 * ABS(self.leftImageView.frame.origin.x / factor);
        leftFrame.origin.x = 0;
        currentFrame.origin.x = factor;
        rightFrame.origin.x = 2 * factor;
        self->imageIndex = -1;

    } else { // leave the middle image
        duration = 0.3 * ABS(self.imageView.frame.origin.x / factor);
        leftFrame.origin.x = -1 * factor;
        currentFrame.origin.x = 0;
        rightFrame.origin.x = factor;
        self->imageIndex = 0;

    }

    [UIView animateWithDuration:duration
                          delay:0
                        options:UIViewAnimationOptionCurveEaseInOut
                     animations:^{
                         self.leftImageView.frame = leftFrame;
                         self.imageView.frame = currentFrame;
                         self.rightImageView.frame = rightFrame;
                     } completion:^(BOOL finished) {
                     }];

} else {
    CGPoint translation = [recognizer translationInView:recognizer.view];
    CGPoint leftCenter = self.leftImageView.center;
    CGPoint currentCenter = self.imageView.center;        
    CGPoint rightCenter = self.rightImageView.center;

    leftCenter.x += translation.x;
    currentCenter.x += translation.x;
    rightCenter.x += translation.x;
    self.leftImageView.center = leftCenter;
    self.imageView.center = currentCenter;
    self.rightImageView.center = rightCenter;

    [recognizer setTranslation:CGPointMake(0, 0) inView:self.imageView];
}

}

- (void)willAnimateRotationToInterfaceOrientation:
(UIInterfaceOrientation)toInterfaceOrientation
                                     duration:(NSTimeInterval)duration
{ 
CGPoint leftCenter = self.leftImageView.center;
CGPoint currentCenter = self.imageView.center;
CGPoint rightCenter = self.rightImageView.center;

if(UIInterfaceOrientationIsPortrait(toInterfaceOrientation)){

    leftCenter.x = 384+(((-self->imageIndex)-1)*768);
    currentCenter.x = 384+((-self->imageIndex)*768);
    rightCenter.x = 384+(((-self->imageIndex)+1)*768);

}
else{

    leftCenter.x = 512+(((-self->imageIndex)-1)*1024);
    currentCenter.x = 512+((-self->imageIndex)*1024);
    rightCenter.x = 512+(((-self->imageIndex)+1)*1024);

}

self.leftImageView.center = leftCenter;
self.imageView.center = currentCenter;
self.rightImageView.center = rightCenter;

}

@end
4

2 に答える 2

1

写真アプリケーションのようなスクロール動作が必要な場合は、を使用しないでくださいUIGestureRecognizerUIPageViewControllerwithを使用するUIPageViewControllerTransitionStyleScrollか、iOS6より前のバージョンをサポートする必要がある場合は、を使用しUIScrollViewます。

を使用した例については、AppleのサンプルプロジェクトPhotoScrollerUIScrollViewを確認してください。

于 2012-12-15T19:45:14.140 に答える
1

UIPanGestureRecognizer画像ビューに を追加できます。次のようなことを行うメソッドが割り当てられます。

- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
    if (recognizer.state == UIGestureRecognizerStateEnded) {

    } else {
        CGPoint translation = [recognizer translationInView:recognizer.view];
        CGPoint center = recognizer.view.center;
        UIImageView *imageViewToPresent = nil;
        if (translation.x > 0) {
            imageViewToPresent = [self leftImageView];
        } else {
            imageViewToPresent = [self leftImageView];
        }
        CGPoint actualCenter = recognizer.view.center;
        CGPoint nextCenter = imageViewToPresent.center;
        actualCenter.x += translation.x;
        nextCenter.x += translation.x;
        recognizer.view.center = actualCenter;
        imageViewToPresent.view.center = nextCenter;
        [recognizer setTranslation:CGPointMake(0, 0) inView:self.imageView];
    }
}

そのUIGestureRecognizerStateEnded部分では、どの写真を表示するかを決めることができます。

または、ページングを有効にして ScrollView を使用するだけです。同じ効果があるはずです。ただし、すべての画像を同時にロードする必要があります。Pan Recognizer を使用するには、3 つの画像ビュー (左、右、現在) が必要です。

お役に立てれば!

編集:

ヘッダー ファイルに、さらに 2 つの画像ビューを追加する必要があります。

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UIGestureRecognizerDelegate>

@property (nonatomic, strong) UIImageView* imageView;
@property (nonatomic, strong) UIImageView* leftImageView;
@property (nonatomic, strong) UIImageView* rightImageView;

@end

実装は次のようになります。

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.imageView = [[UIImageView alloc] initWithFrame:self.view.frame];
    self.imageView.contentMode = UIViewContentModeScaleAspectFit;
    self.imageView.image = [UIImage imageNamed:@"69B4356B-1CB2-4A2F-867E-9C086251DF11-12668-0000036A534E9B6D"];
    self.imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    CGRect leftFrame = self.view.frame;
    leftFrame.origin.x -= leftFrame.size.width;
    self.leftImageView = [[UIImageView alloc] initWithFrame:leftFrame];
    self.leftImageView.contentMode = UIViewContentModeScaleAspectFit;
    self.leftImageView.image = [UIImage imageNamed:@"42517D93-F8BF-42E7-BB44-53B099A482AA-12668-0000036A49BCECAA"];
    self.leftImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    CGRect rightFrame = self.view.frame;
    rightFrame.origin.x += rightFrame.size.width;
    self.rightImageView = [[UIImageView alloc] initWithFrame:rightFrame];
    self.rightImageView.contentMode = UIViewContentModeScaleAspectFit;
    self.rightImageView.image = [UIImage imageNamed:@"C6AC2508-243B-464B-A71F-96DD7F18673D-12668-00000369F3AFD3FC"];
    self.rightImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    [self.view addSubview:self.imageView];
    [self.view addSubview:self.leftImageView];
    [self.view addSubview:self.rightImageView];

    UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    [self.view addGestureRecognizer:recognizer];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];

}

- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
    if (recognizer.state == UIGestureRecognizerStateEnded) {
        CGRect leftFrame = self.leftImageView.frame;
        CGRect currentFrame = self.imageView.frame;
        CGRect rightFrame = self.rightImageView.frame;
        float duration = 0.0;
        if (self.imageView.center.x < 0) { // Present the right image
            duration = 0.3 * ABS(self.rightImageView.frame.origin.x / self.view.frame.size.width);
            leftFrame.origin.x = -2 * self.view.frame.size.width;
            currentFrame.origin.x = -1 * self.view.frame.size.width;
            rightFrame.origin.x = 0;
        } else if (self.imageView.center.x > self.view.frame.size.width) { // Present the left image
            duration = 0.3 * ABS(self.leftImageView.frame.origin.x / self.view.frame.size.width);
            leftFrame.origin.x = 0;
            currentFrame.origin.x = self.view.frame.size.width;
            rightFrame.origin.x = 2 * self.view.frame.size.width;
        } else { // leave the middle image
            duration = 0.3 * ABS(self.imageView.frame.origin.x / self.view.frame.size.width);
            leftFrame.origin.x = -1 * self.view.frame.size.width;
            currentFrame.origin.x = 0;
            rightFrame.origin.x = self.view.frame.size.width;
        }

        [UIView animateWithDuration:duration
                              delay:0
                            options:UIViewAnimationOptionCurveEaseInOut
                         animations:^{
            self.leftImageView.frame = leftFrame;
            self.imageView.frame = currentFrame;
            self.rightImageView.frame = rightFrame;
        } completion:^(BOOL finished) {
        }];
    } else {
        CGPoint translation = [recognizer translationInView:recognizer.view];
        CGPoint currnetCenter = self.imageView.center;
        CGPoint leftCenter = self.leftImageView.center;
        CGPoint rightCenter = self.rightImageView.center;

        currnetCenter.x += translation.x;
        leftCenter.x += translation.x;
        rightCenter.x += translation.x;
        self.imageView.center = currnetCenter;
        self.leftImageView.center = leftCenter;
        self.rightImageView.center = rightCenter;


        [recognizer setTranslation:CGPointMake(0, 0) inView:self.imageView];
    }

}

@end

もちろん、まだ作業が必要です (たとえば、3 つ以上のハードコードされたイメージをサポートするなど)。IBOutlets を使用し、Interface Builder から自動サイズ変更マスクを設定すると、回転の問題に役立つ場合があります。

楽しむ!

于 2012-12-15T19:50:09.333 に答える