// // PopupView.m // AIIM // // Created by qitewei on 2025/5/29. // #import "PopupView.h" @interface PopupView () @property (nonatomic, strong) UIControl *backgroundControl; @property (nonatomic, weak) UIView *containerView; @property (nonatomic, assign) BOOL showing; @end @implementation PopupView - (instancetype)init { self = [super init]; if (self) { [self commonInit]; } return self; } - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self commonInit]; } return self; } - (void)commonInit { _position = PopupPositionCenter; _animationType = PopupAnimationTypeFromBottom; _dismissOnBackgroundTap = YES; _offset = 0; _containerType = PopupContainerTypeView; _backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; _backgroundControl = [[UIControl alloc] init]; _backgroundControl.backgroundColor = _backgroundColor; [_backgroundControl addTarget:self action:@selector(backgroundTapped) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:_backgroundControl]; } - (void)layoutSubviews { [super layoutSubviews]; _backgroundControl.frame = self.bounds; if (_customView) { CGRect frame = _customView.frame; switch (_position) { case PopupPositionTop: frame.origin.y = _offset; break; case PopupPositionCenter: frame.origin.y = (self.bounds.size.height - frame.size.height) / 2 + _offset; break; case PopupPositionBottom: frame.origin.y = self.bounds.size.height - frame.size.height + _offset; break; } frame.origin.x = (self.bounds.size.width - frame.size.width) / 2; _customView.frame = frame; } } #pragma mark - Public Methods - (void)showInView:(UIView *)view { if (_showing) return; // 确定容器视图 if (_containerType == PopupContainerTypeWindow) { _containerView = [UIApplication sharedApplication].delegate.window; } else { _containerView = view; } if (!_containerView) { NSLog(@"Error: No container view available"); return; } // 设置frame self.frame = _containerView.bounds; _backgroundControl.frame = self.bounds; _backgroundControl.backgroundColor = _backgroundColor; // 添加自定义视图 if (_customView) { [self addSubview:_customView]; [self setNeedsLayout]; } // 添加到容器 [_containerView addSubview:self]; // 初始状态 CGFloat startAlpha = 0; CGRect finalFrame = _customView.frame; CGRect startFrame = finalFrame; switch (_animationType) { case PopupAnimationTypeFromBottom: startFrame.origin.y = self.bounds.size.height; break; case PopupAnimationTypeFromTop: startFrame.origin.y = -startFrame.size.height; break; case PopupAnimationTypeFade: startAlpha = 0; break; } _customView.frame = startFrame; _customView.alpha = startAlpha; self.alpha = 0; // 执行动画 [UIView animateWithDuration:0.3 animations:^{ self.alpha = 1; self.customView.alpha = 1; self.customView.frame = finalFrame; } completion:^(BOOL finished) { self.showing = YES; }]; } - (void)dismiss { if (!_showing) return; CGRect endFrame = _customView.frame; CGFloat endAlpha = 0; // 根据动画类型设置结束状态 switch (_animationType) { case PopupAnimationTypeFromBottom: endFrame.origin.y = self.bounds.size.height; break; case PopupAnimationTypeFromTop: endFrame.origin.y = -endFrame.size.height; break; case PopupAnimationTypeFade: // 淡出只需要改变alpha break; } [UIView animateWithDuration:0.3 animations:^{ if (self.animationType != PopupAnimationTypeFade) { self.customView.frame = endFrame; }else{ self.customView.alpha = endAlpha; } self.alpha = 0; } completion:^(BOOL finished) { [self.customView removeFromSuperview]; [self removeFromSuperview]; self.showing = NO; if (self.dismissCompletion) { self.dismissCompletion(); } }]; } - (void)backgroundTapped { if (_dismissOnBackgroundTap) { [self dismiss]; } } #pragma mark - Setters - (void)setCustomView:(UIView *)customView { if (_customView != customView) { [_customView removeFromSuperview]; _customView = customView; [self addSubview:_customView]; [self setNeedsLayout]; } } - (void)setBackgroundColor:(UIColor *)backgroundColor { _backgroundColor = backgroundColor; _backgroundControl.backgroundColor = backgroundColor; } @end