一、弹窗样式类(这里实现最常见也是最简单的弹窗样式:背景灰色半透明、主图、❎,其中图片点击可跳转,❎关闭弹窗)
1、头文件
#import <UIKit/UIKit.h>
@interface CustomPopupViewController : UIViewController <UIViewControllerTransitioningDelegate>
// 初始化方法,传入要显示的图片名称
- (instancetype)initWithImageName:(UIImage *)imageName linkURL:(NSString *)linkURL;
// 关闭弹窗的方法
- (void)dismissPopup;
@property (copy, nonatomic) NSString *linkURL; // 跳转链接
@end
2、实现文件
#import "CustomPopupViewController.h"
#import "CustomTransition.h" // 引入自定义转场动画类
@interface CustomPopupViewController ()
@property (strong, nonatomic) UIImageView *imageView;
@property (strong, nonatomic) UIButton *closeButton;
@end
@implementation CustomPopupViewController
- (instancetype)initWithImageName:(UIImage *)imageName linkURL:(NSString *)linkURL {
self = [super initWithNibName:nil bundle:nil];
if (self) {
self.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; // 透明黑色背景
UIImage *image = imageName;
if (!image) {
NSLog(@"Image %@ not found.", imageName);
return nil;
}
CGFloat aspectRatio = image.size.height / image.size.width;
CGSize imageSize;
CGFloat imageWidth = ZOOM(301); // 图片定宽 301
imageSize = CGSizeMake(imageWidth, imageWidth * aspectRatio); // 根据图片原比例来指定图片视图的宽、高
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, imageSize.width, imageSize.height)];
self.imageView.center = self.view.center;
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.imageView.image = image;
[self.view addSubview:self.imageView];
// 让关闭按钮(叉号❎)始终在活动弹窗的右上角(框内)
self.closeButton = [[UIButton alloc] initWithFrame:CGRectZero];
[self.view addSubview:self.closeButton];
[self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.height.mas_equalTo(ZOOM(24));
make.right.equalTo(self.imageView.mas_right);
make.top.equalTo(self.imageView.mas_top);
}];
[self.closeButton setBackgroundImage:[UIImage imageNamed:@"退出_button"] forState:UIControlStateNormal];
[self.closeButton addTarget:self action:@selector(dismissPopup) forControlEvents:UIControlEventTouchUpInside];
self.linkURL = linkURL; // 活动弹窗跳转链接
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageTapped:)];
tapGesture.numberOfTapsRequired = 1;
[self.imageView addGestureRecognizer:tapGesture];
tapGesture.cancelsTouchesInView = NO;
self.imageView.userInteractionEnabled = YES;
}
return self;
}
- (void)imageTapped:(UITapGestureRecognizer *)gestureRecognizer {
if (self.linkURL && ![self.linkURL isEqualToString:@""]) {
[self dismissPopup]; // 先执行弹窗关闭
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:self.linkURL]]; // 再进行活动弹窗链接跳转
}
}
- (void)dismissPopup {
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
// 作为UIViewControllerTransitioningDelegate的实现
// 弹窗出现
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
CustomTransition *transition = [[CustomTransition alloc] init];
transition.isPresenting = YES; // 传递弹窗出现标志
return transition;
}
// 弹窗消散
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
CustomTransition *transition = [[CustomTransition alloc] init];
transition.isPresenting = NO; // 传递弹窗消失标志
return transition;
}
@end
二、弹窗动画类(这里实现最简单也是最常见的呈现和散出效果)
1、头文件
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface CustomTransition : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic, assign) BOOL isPresenting; // 是否为弹窗出现的标志
@end
NS_ASSUME_NONNULL_END
2、实现文件
#import "CustomTransition.h"
@implementation CustomTransition
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return 0.3; // 动画持续的时间
}
// 转变动画
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView = [transitionContext containerView];
if (self.isPresenting) { // 如果正在呈现弹窗
toViewController.view.alpha = 0.0;
[containerView insertSubview:toViewController.view atIndex:0];
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toViewController.view.alpha = 1.0;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
} else { // 如果正在关闭弹窗
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
fromViewController.view.alpha = 0.0;
} completion:^(BOOL finished) {
[fromViewController.view removeFromSuperview];
[transitionContext completeTransition:YES];
}];
}
}
@end
三、弹窗的使用(在要使用这个活动弹窗的类中实现代码)
#import "CustomPopupViewController.h"
// 改变这里的图片和链接进行使用
CustomPopupViewController *customPopupVC = [[CustomPopupViewController alloc] initWithImageName:image linkURL:linkURL];
customPopupVC.modalPresentationStyle = UIModalPresentationOverFullScreen;
customPopupVC.transitioningDelegate = customPopupVC;