Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
Прием - Вы, делают два экземпляра UIImageView. Вы подкачиваете их промежуточные вызовы к UIView +beginAnimations и +commitAnimations.
Ничто различное от того, что было объяснено, но в коде, это доступные переходы:
typedef enum {
UIViewAnimationTransitionNone,
UIViewAnimationTransitionFlipFromLeft,
UIViewAnimationTransitionFlipFromRight,
UIViewAnimationTransitionCurlUp,
UIViewAnimationTransitionCurlDown,
} UIViewAnimationTransition;
Код (Помещенный это в обратный вызов как touchesEnded) :
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:[self superview] cache:YES];
// -- These don't work on the simulator and the curl up will turn into a fade -- //
//[UIView setAnimationTransition: UIViewAnimationTransitionCurlUp forView:[self superview] cache:YES];
//[UIView setAnimationTransition: UIViewAnimationTransitionCurlDown forView:[self superview] cache:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:1.0];
// Below assumes you have two subviews that you're trying to transition between
[[self superview] exchangeSubviewAtIndex:0 withSubviewAtIndex:1];
[UIView commitAnimations];
Существует несколько способов сделать это, и я соглашаюсь с Ben View Transitions, яркий пример. Если бы Вы ищете простые полноэкранные переходы, я просто считал бы запущение нового служебного приложения и взгляда toggleView методом в RootViewController.m
. Попытайтесь выключить UIViewAnimationTransitionFlipFromLeft
и UIViewAnimationTransitionFlipFromRight
к UIViewAnimationTransitionCurlUp
и UIViewAnimationTransitionCurlDown
для действительно хорошего эффекта перехода (это только работает над устройством).
вот что я сделал: затухание. Я поставил еще один UIImageView с тем же UIImage и размером tmp. я заменяю UIImage базового UIImageView. Затем я кладу правильное изображение на основу (все еще покрытое tmp).
Следующий шаг - - установить альфа tmp равным нулю, - чтобы растянуть базовый UIImageView в правильном соотношении нового UIImage на основе высоты основания.
Вот код:
UIImage *img = [params objectAtIndex:0]; // the right image
UIImageView *view = [params objectAtIndex:1]; // the base
UIImageView *tmp = [[UIImageView alloc] initWithImage:view.image]; // the one which will use to fade
tmp.frame = CGRectMake(0, 0, view.frame.size.width, view.frame.size.height);
[view addSubview:tmp];
view.image = img;
float r = img.size.width / img.size.height;
float h = view.frame.size.height;
float w = h * r;
float x = view.center.x - w/2;
float y = view.frame.origin.y;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
tmp.alpha = 0;
view.frame = CGRectMake(x, y, w, h);
[UIView commitAnimations];
[tmp performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1.5];
[tmp performSelector:@selector(release) withObject:nil afterDelay:2];
Я только что просматривал ваш пост и у меня было точно такое же требование. Проблема всех вышеперечисленных решений в том, что вам придется встроить логику перехода в ваш контроллер. В этом смысле подход не является модульным. Вместо этого я написал этот подкласс UIImageView:
TransitionImageView.h file:
#import <UIKit/UIKit.h>
@interface TransitionImageView : UIImageView
{
UIImageView *mOriginalImageViewContainerView;
UIImageView *mIntermediateTransitionView;
}
@property (nonatomic, retain) UIImageView *originalImageViewContainerView;
@property (nonatomic, retain) UIImageView *intermediateTransitionView;
#pragma mark -
#pragma mark Animation methods
-(void)setImage:(UIImage *)inNewImage withTransitionAnimation:(BOOL)inAnimation;
@end
TransitionImageView.m file:
#import "TransitionImageView.h"
#define TRANSITION_DURATION 1.0
@implementation TransitionImageView
@synthesize intermediateTransitionView = mIntermediateTransitionView;
@synthesize originalImageViewContainerView = mOriginalImageViewContainerView;
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Initialization code
}
return self;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (void)dealloc
{
[self setOriginalImageViewContainerView:nil];
[self setIntermediateTransitionView:nil];
[super dealloc];
}
#pragma mark -
#pragma mark Animation methods
-(void)setImage:(UIImage *)inNewImage withTransitionAnimation:(BOOL)inAnimation
{
if (!inAnimation)
{
[self setImage:inNewImage];
}
else
{
// Create a transparent imageView which will display the transition image.
CGRect rectForNewView = [self frame];
rectForNewView.origin = CGPointZero;
UIImageView *intermediateView = [[UIImageView alloc] initWithFrame:rectForNewView];
[intermediateView setBackgroundColor:[UIColor clearColor]];
[intermediateView setContentMode:[self contentMode]];
[intermediateView setClipsToBounds:[self clipsToBounds]];
[intermediateView setImage:inNewImage];
// Create the image view which will contain original imageView's contents:
UIImageView *originalView = [[UIImageView alloc] initWithFrame:rectForNewView];
[originalView setBackgroundColor:[UIColor clearColor]];
[originalView setContentMode:[self contentMode]];
[originalView setClipsToBounds:[self clipsToBounds]];
[originalView setImage:[self image]];
// Remove image from the main imageView and add the originalView as subView to mainView:
[self setImage:nil];
[self addSubview:originalView];
// Add the transparent imageView as subview whose dimensions are same as the view which holds it.
[self addSubview:intermediateView];
// Set alpha value to 0 initially:
[intermediateView setAlpha:0.0];
[originalView setAlpha:1.0];
[self setIntermediateTransitionView:intermediateView];
[self setOriginalImageViewContainerView:originalView];
[intermediateView release];
[originalView release];
// Begin animations:
[UIView beginAnimations:@"ImageViewTransitions" context:nil];
[UIView setAnimationDuration:(double)TRANSITION_DURATION];
[UIView setAnimationDelegate:self];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
[[self intermediateTransitionView] setAlpha:1.0];
[[self originalImageViewContainerView] setAlpha:0.0];
[UIView commitAnimations];
}
}
-(void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
// Reset the alpha of the main imageView
[self setAlpha:1.0];
// Set the image to the main imageView:
[self setImage:[[self intermediateTransitionView] image]];
[[self intermediateTransitionView] removeFromSuperview];
[self setIntermediateTransitionView:nil];
[[self originalImageViewContainerView] removeFromSuperview];
[self setOriginalImageViewContainerView:nil];
}
@end
Вы можете даже переопределить метод -setImage
UIImageView и вызвать мой метод -setImage:withTransitionAnimation:
. Если это сделано таким образом, убедитесь, что вы вызываете [super setImage:]
вместо [self setImage:]
в методе -setImage:withTransitionAnimation:
, чтобы это не закончилось бесконечным рекурсивным вызовом!
-Raj