แทนที่จะสร้างมุมมองทั้งสองUIImageViews
ดูเหมือนว่ามีเหตุผลที่จะเพียงแค่เปลี่ยนimage
มุมมองหนึ่งมุมมอง ถ้าฉันทำอย่างนั้นจะมีการจางหายไป / ครอสละลายระหว่างภาพสองภาพมากกว่าการเปลี่ยนทันทีหรือไม่?
แทนที่จะสร้างมุมมองทั้งสองUIImageViews
ดูเหมือนว่ามีเหตุผลที่จะเพียงแค่เปลี่ยนimage
มุมมองหนึ่งมุมมอง ถ้าฉันทำอย่างนั้นจะมีการจางหายไป / ครอสละลายระหว่างภาพสองภาพมากกว่าการเปลี่ยนทันทีหรือไม่?
คำตอบ:
แก้ไข: มีทางออกที่ดีกว่าจาก@algal ด้านล่าง
อีกวิธีในการทำเช่นนี้คือการใช้การเปลี่ยน CAAnimation ที่กำหนดไว้ล่วงหน้า:
CATransition *transition = [CATransition animation];
transition.duration = 0.25;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
transition.delegate = self;
[self.view.layer addAnimation:transition forKey:nil];
view1.hidden = YES;
view2.hidden = NO;
ดูโครงการตัวอย่างดูการเปลี่ยนจาก Apple: https://developer.apple.com/library/content/samplecode/ViewTransitions/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007411
มันอาจจะง่ายมากโดยใช้บล็อกใหม่ตามUIKit animation
วิธีการ
สมมติว่ารหัสต่อไปนี้อยู่ในตัวควบคุมมุมมองและ UIImageView ที่คุณต้องการข้ามการยุบคือมุมมองย่อยของ self.view ที่สามารถเข้าถึงได้ผ่านคุณสมบัติself.imageView
จากนั้นทั้งหมดที่คุณต้องการคือ:
UIImage * toImage = [UIImage imageNamed:@"myname.png"];
[UIView transitionWithView:self.imageView
duration:5.0f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.imageView.image = toImage;
} completion:nil]
เสร็จสิ้น
และเพื่อทำใน Swift มันเป็นเช่นนั้น:
let toImage = UIImage(named:"myname.png")
UIView.transitionWithView(self.imageView,
duration:5,
options: UIViewAnimationOptions.TransitionCrossDissolve,
animations: { self.imageView.image = toImage },
completion: nil)
สวิฟท์ 3, 4 และ 5
let toImage = UIImage(named:"myname.png")
UIView.transition(with: self.imageView,
duration: 0.3,
options: .transitionCrossDissolve,
animations: {
self.imageView.image = toImage
},
completion: nil)
สำหรับ Swift 3.0.1:
UIView.transition(with: self.imageView,
duration:0.5,
options: .transitionCrossDissolve,
animations: { self.imageView.image = newImage },
completion: nil)
ข้อมูลอ้างอิง: https://gist.github.com/licvido/bc22343cacfa3a8ccf88
ใช่สิ่งที่คุณพูดถูกต้องอย่างแน่นอนและนั่นคือวิธีที่จะทำ ฉันเขียนวิธีนี้และใช้วิธีนี้ในการลบภาพของฉัน ฉันจัดการกับCALayer
สิ่งนี้ คุณต้องนำเข้า Core Animation สำหรับสิ่งนี้
+ (void)fadeInLayer:(CALayer *)l
{
CABasicAnimation *fadeInAnimate = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeInAnimate.duration = 0.5;
fadeInAnimate.repeatCount = 1;
fadeInAnimate.autoreverses = NO;
fadeInAnimate.fromValue = [NSNumber numberWithFloat:0.0];
fadeInAnimate.toValue = [NSNumber numberWithFloat:1.0];
fadeInAnimate.removedOnCompletion = YES;
[l addAnimation:fadeInAnimate forKey:@"animateOpacity"];
return;
}
คุณสามารถทำสิ่งที่ตรงกันข้ามเพื่อทำให้ภาพจางหายไป หลังจากที่มันจางหายไป คุณเพิ่งลบออกจาก superview (ซึ่งก็คือUIImageView
) [imageView removeFromSuperview]
.
คุณยังสามารถทำแพคเกจคุณสมบัติการ fade-in ในคลาสย่อยเพื่อให้คุณสามารถใช้เป็น UIImageView ทั่วไปได้ดังตัวอย่างต่อไปนี้:
IMMFadeImageView *fiv=[[IMMFadeImageView alloc] initWithFrame:CGRectMake(10, 10, 50, 50)];
[self.view addSubview:fiv];
fiv.image=[UIImage imageNamed:@"initialImage.png"];
fiv.image=[UIImage imageNamed:@"fadeinImage.png"]; // fades in
การใช้งานที่เป็นไปได้ดังต่อไปนี้
หมายเหตุ: วิธีการที่คุณใช้setImage:
ฟังก์ชั่นเฟดในฟังก์ชั่นสามารถเปลี่ยนแปลงได้และอาจเป็นหนึ่งในตัวอย่างที่ยอดเยี่ยมอื่น ๆ ที่อธิบายไว้ในคำตอบอื่น ๆ สำหรับคำถามนี้ - การสร้างเพิ่มเติมแบบทันทีUIImageView
ขณะที่ฉันกำลังทำอยู่ที่นี่ เป็นค่าใช้จ่ายที่ยอมรับไม่ได้ในสถานการณ์เฉพาะของคุณ
IMMFadeImageView.h :
#import <UIKit/UIKit.h>
@interface IMMFadeImageView : UIImageView
@property (nonatomic,assign) float fadeDuration;
@end
IMMFadeImageView.m :
#import "IMMFadeImageView.h"
@implementation IMMFadeImageView
@synthesize fadeDuration;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.fadeDuration=1;
}
return self;
}
-(void)setImage:(UIImage *)newImage{
if(!self.image||self.fadeDuration<=0){
super.image=newImage;
} else {
UIImageView *iv=[[UIImageView alloc] initWithFrame:self.bounds];
iv.contentMode=self.contentMode;
iv.image=super.image;
iv.alpha=1;
[self addSubview:iv];
super.image=newImage;
[UIView animateWithDuration:self.fadeDuration delay:0 options:UIViewAnimationCurveEaseInOut animations:^{
iv.alpha=0;
} completion:^(BOOL finished) {
[iv removeFromSuperview];
}];
}
}
รหัสข้างต้นอาศัยสมมติฐานสองสามข้อ (รวมถึง ARC ที่เปิดใช้งานในโครงการ XCode ของคุณ) มีวัตถุประสงค์เพื่อพิสูจน์แนวคิดเท่านั้นและเพื่อความชัดเจนและความสนใจโฟกัสนั้นยังคงเกี่ยวข้องโดยไม่ต้องใส่รหัสที่ไม่เกี่ยวข้องสำคัญ โปรดอย่าเพิ่งคัดลอกวางสุ่มสี่สุ่มห้า
ฉันต้องการการเปลี่ยนแปลงเพื่อทำซ้ำอย่างไม่มีกำหนด ใช้การทดลองและข้อผิดพลาดมากมายสำหรับอันนี้ แต่ในที่สุดฉันก็ได้รับผลลัพธ์ที่ฉันต้องการ นี่คือโค้ดขนาดสั้นสำหรับการเพิ่มภาพเคลื่อนไหวไปยัง UIImageView ใน UITableViewCell
นี่คือรหัสที่เกี่ยวข้อง:
@interface SomeViewController ()
@property(nonatomic, strong) NSMutableArray *imagesArray;
@property(nonatomic, assign) NSInteger varietyImageAnimationIndex;
@property(nonatomic, assign) BOOL varietyImagesAnimated;
@end
@implementation SomeViewController
@synthesize imagesArray;
@synthesize varietyImageAnimationIndex;
@synthesize varietyImagesAnimated;
...
// NOTE: Initialize the array of images in perhaps viewDidLoad method.
-(void)animateImages
{
varietyImageAnimationIndex++;
[UIView transitionWithView:varietyImageView
duration:2.0f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
varietyImageView.image = [imagesArray objectAtIndex:varietyImageAnimationIndex % [imagesArray count]];
} completion:^(BOOL finished) {
[self animateImages];
}];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
[cell.imageView setImage:[imagesArray objectAtIndex:0]];
[self setVarietyImageView:cell.imageView];
if (! varietyImagesAnimated)
{
varietyImagesAnimated = YES;
[self animateImages];
}
...
return cell;
}
หลังจากเล่นไปเรื่อยๆUIView.transition()
และได้รับปัญหาเกี่ยวกับ.transitionCrossDissolve
ตัวเลือก (ฉันพยายามที่จะทำให้ภาพเคลื่อนไหวเปลี่ยนแปลงภายใน UIImageView เดียวและการเปลี่ยนแปลงเกิดขึ้นทันทีโดยไม่มีภาพเคลื่อนไหว) ฉันพบว่าคุณเพียงแค่ต้องเพิ่มตัวเลือกอีกหนึ่งตัวSwift 4.2 ):
UIView.transition(with: self.imageView,
duration: 1,
options: [.allowAnimatedContent, .transitionCrossDissolve],
animations: { self.imageView.image = newImage },
completion: nil)
นอกจากนี้: หากคุณมีภาพย่อยบน imageView ของคุณภาพนั้นจะถูกวาดใหม่ด้วยและสามารถป้องกันภาพเคลื่อนไหวได้ ตัวอย่างเช่นฉันมี subview พร้อมเบลอที่ imageView ของฉันและในกรณีที่ภาพเคลื่อนไหวไม่ทำงาน ดังนั้นฉันจึงเปลี่ยนลำดับชั้นการดูของฉันและย้ายเบลอไปยังมุมมองของตัวเองและวางไว้เหนือ imageView
นี่คือฉันคิดว่าวิธีที่สั้นที่สุดในการทำมัน สร้างอนิเมชั่น UIView และคอมมิทเข้าไปใน imageView ของคุณ
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[myImageView setAlpha:0.0];
[UIView commitAnimations];
โดยใช้highlightedImage
คุณสมบัตินี้สามารถทำได้ง่ายขึ้นอีกเล็กน้อย นี่คือตัวอย่างใน Swift 3 ขั้นแรกให้ตั้งค่าทั้งรูปภาพปกติและไฮไลต์:
let imageView = UIImageView(image: UIImage(named: "image"), highlightedImage: UIImage(named: "highlightedImage"))
และเมื่อคุณต้องการเปลี่ยนระหว่างภาพเคลื่อนไหวเหล่านั้น:
UIView.transition(with: imageView, duration: 0.3, options: .transitionCrossDissolve, animations: { self.imageView.isHighlighted = !self.imageView.isHighlighted}, completion: .none)