123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- //
- // YMCaptchaPopupView.m
- // MSYOUPAI
- //
- // Created by macmini on 2025/6/7.
- // Copyright © 2025 MS. All rights reserved.
- //
- #import "YMCaptchaPopupView.h"
- @interface YMCaptchaPopupView ()<UITextFieldDelegate>
- @property (nonatomic, strong) UIView *backgroundMaskView;
- @property (nonatomic, strong) UIView *contentView;
- @property (nonatomic, strong) UILabel *titleLabel;
- @property (nonatomic, strong) UITextField *inputTextField;
- @property (nonatomic, strong) UIImageView *captchaImageView;
- @property (nonatomic, strong) UIButton *cancelButton;
- @property (nonatomic, strong) UIButton *confirmButton;
- @end
- @implementation YMCaptchaPopupView
- - (instancetype)initWithFrame:(CGRect)frame {
- self = [super initWithFrame:frame];
- if (self) {
- [self setupUI];
- [self loadCaptchaImage];
- }
- return self;
- }
- - (void)setupUI {
- self.backgroundColor = [UIColor clearColor];
- // Background Mask
- self.backgroundMaskView = [[UIView alloc] initWithFrame:self.bounds];
- self.backgroundMaskView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
- self.backgroundMaskView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- [self addSubview:self.backgroundMaskView];
- UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismiss)];
- [self.backgroundMaskView addGestureRecognizer:tapGesture];
- // Content View
- self.contentView = [[UIView alloc] init];
- self.contentView.backgroundColor = [UIColor whiteColor];
- self.contentView.layer.cornerRadius = 10.0;
- self.contentView.clipsToBounds = YES;
- [self.contentView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithActionBlock:^(id _Nonnull sender) { }]];
- [self addSubview:self.contentView];
- // Title Label
- self.titleLabel = [[UILabel alloc] init];
- self.titleLabel.text = @"图形验证";
- self.titleLabel.font = [UIFont boldSystemFontOfSize:18.0];
- self.titleLabel.textAlignment = NSTextAlignmentCenter;
- [self.contentView addSubview:self.titleLabel];
- // Input TextField
- self.inputTextField = [[UITextField alloc] init];
- self.inputTextField.font = [UIFont systemFontOfSize:14 weight:(UIFontWeightRegular)];
- self.inputTextField.placeholder = @"请输入验证码(不区分大小写)";
- self.inputTextField.borderStyle = UITextBorderStyleRoundedRect;
- self.inputTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;
- self.inputTextField.delegate = self;
- [self.contentView addSubview:self.inputTextField];
- // Captcha ImageView
- self.captchaImageView = [[UIImageView alloc] init];
- self.captchaImageView.backgroundColor = [UIColor lightGrayColor]; // Placeholder color
- self.captchaImageView.contentMode = UIViewContentModeScaleToFill;
- self.captchaImageView.userInteractionEnabled = YES;
- self.captchaImageView.clipsToBounds = YES;
- self.captchaImageView.layer.cornerRadius = 5; // Approximate from image
- // You might want to add a tap gesture to refresh the captcha
- // For example:
- UITapGestureRecognizer *captchaTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(refreshCaptcha)];
- [self.captchaImageView addGestureRecognizer:captchaTap];
- [self.contentView addSubview:self.captchaImageView];
- // Cancel Button
- self.cancelButton = [UIButton buttonWithType:UIButtonTypeSystem];
- [self.cancelButton setTitle:@"取消" forState:UIControlStateNormal];
- [self.cancelButton setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
- self.cancelButton.titleLabel.font = [UIFont systemFontOfSize:16.0];
- self.cancelButton.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:1.0]; // Light gray background
- self.cancelButton.layer.cornerRadius = 25; // Approximate from image
- [self.cancelButton addTarget:self action:@selector(cancelButtonTapped) forControlEvents:UIControlEventTouchUpInside];
- [self.contentView addSubview:self.cancelButton];
- // Confirm Button
- self.confirmButton = [UIButton buttonWithType:UIButtonTypeSystem];
- [self.confirmButton setTitle:@"确定" forState:UIControlStateNormal];
- [self.confirmButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
- self.confirmButton.titleLabel.font = [UIFont systemFontOfSize:16.0];
- self.confirmButton.backgroundColor = [UIColor colorWithRed:1.0 green:0.4 blue:0.5 alpha:1.0]; // Pinkish color
- self.confirmButton.layer.cornerRadius = 25; // Approximate from image
- [self.confirmButton addTarget:self action:@selector(confirmButtonTapped) forControlEvents:UIControlEventTouchUpInside];
- [self.contentView addSubview:self.confirmButton];
-
- [self setupLayoutConstraints];
- }
- - (void)setupLayoutConstraints {
- self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
- self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
- self.inputTextField.translatesAutoresizingMaskIntoConstraints = NO;
- self.captchaImageView.translatesAutoresizingMaskIntoConstraints = NO;
- self.cancelButton.translatesAutoresizingMaskIntoConstraints = NO;
- self.confirmButton.translatesAutoresizingMaskIntoConstraints = NO;
- CGFloat contentWidth = CGRectGetWidth(UIScreen.mainScreen.bounds) - 60;
- CGFloat contentHeight = adapt(220); // Adjusted height
- [NSLayoutConstraint activateConstraints:@[
- [self.contentView.centerXAnchor constraintEqualToAnchor:self.centerXAnchor],
- [self.contentView.centerYAnchor constraintEqualToAnchor:self.centerYAnchor],
- [self.contentView.widthAnchor constraintEqualToConstant:contentWidth],
- [self.contentView.heightAnchor constraintEqualToConstant:contentHeight],
- [self.titleLabel.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:20],
- [self.titleLabel.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:20],
- [self.titleLabel.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-20],
- [self.inputTextField.topAnchor constraintEqualToAnchor:self.titleLabel.bottomAnchor constant:40],
- [self.inputTextField.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:20],
- [self.inputTextField.heightAnchor constraintEqualToConstant:50],
-
- [self.captchaImageView.leadingAnchor constraintEqualToAnchor:self.inputTextField.trailingAnchor constant:10],
- [self.captchaImageView.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-20],
- [self.captchaImageView.centerYAnchor constraintEqualToAnchor:self.inputTextField.centerYAnchor],
- [self.captchaImageView.widthAnchor constraintEqualToConstant:100], // Adjust as needed
- [self.captchaImageView.heightAnchor constraintEqualToConstant:49],
-
- [self.inputTextField.trailingAnchor constraintEqualToAnchor:self.captchaImageView.leadingAnchor constant:-10],
- [self.cancelButton.topAnchor constraintEqualToAnchor:self.inputTextField.bottomAnchor constant:30],
- [self.cancelButton.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:20],
- [self.cancelButton.heightAnchor constraintEqualToConstant:50],
- [self.cancelButton.trailingAnchor constraintEqualToAnchor:self.contentView.centerXAnchor constant:-10],
- [self.confirmButton.topAnchor constraintEqualToAnchor:self.inputTextField.bottomAnchor constant:30],
- [self.confirmButton.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-20],
- [self.confirmButton.heightAnchor constraintEqualToConstant:50],
- [self.confirmButton.leadingAnchor constraintEqualToAnchor:self.contentView.centerXAnchor constant:10],
- ]];
- }
- - (void)loadCaptchaImage {
- [self getCaptchaImageCompletion:^(UIImage *image) {
- if (image) {
- self.captchaImageView.image = image;
- } else {
- self.captchaImageView.image = ImageByName(@"ym_sound_showcase_refresh_icon");
- }
- }];
- }
- - (void)inputTextChanged:(UITextField *)textField {
- NSString *text = textField.text;
- if (text.length > 4) {
- textField.text = [text substringToIndex:3];
- }
- }
- #pragma mark - UITextFieldDelegate
- - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
-
- // 如果是删除操作,允许
- if (string.length == 0) {
- return YES;
- }
-
- // 使用正则表达式判断是否只包含字母和数字
- NSString *pattern = @"^[a-zA-Z0-9]+$";
- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
- return [predicate evaluateWithObject:string];
- }
- #pragma mark - Actions
- - (void)cancelButtonTapped {
- // if ([self.delegate respondsToSelector:@selector(captchaViewDidCancel)]) {
- // [self.delegate captchaViewDidCancel];
- // }
-
- if (self.cancelButtonTappedBlock) {
- self.cancelButtonTappedBlock();
- }
- [self dismiss];
- }
- - (void)confirmButtonTapped {
- if (self.confirmButtonTappedBlock) {
- self.confirmButtonTappedBlock(self.inputTextField.text);
- }
- [self dismiss];
-
- // if ([self.delegate respondsToSelector:@selector(captchaViewDidConfirmWithInput:)]) {
- // [self.delegate captchaViewDidConfirmWithInput:self.inputTextField.text];
- // }
-
-
- // Optionally dismiss after confirm, or let the delegate handle it
- // [self dismiss];
- }
- #pragma mark - Public Methods
- - (void)showInView:(UIView *)view {
- self.frame = view.bounds;
- [view addSubview:self];
- self.alpha = 0;
- self.contentView.transform = CGAffineTransformMakeScale(0.5, 0.5);
- [UIView animateWithDuration:0.3 animations:^{
- self.alpha = 1;
- self.contentView.transform = CGAffineTransformIdentity;
- }];
- }
- - (void)dismiss {
- [UIView animateWithDuration:0.3 animations:^{
- self.alpha = 0;
- self.contentView.transform = CGAffineTransformMakeScale(0.5, 0.5);
- } completion:^(BOOL finished) {
- [self removeFromSuperview];
- }];
- }
- - (void)setCaptchaImage:(UIImage *)image {
- self.captchaImageView.image = image;
- }
- - (void)refreshCaptcha {
- NSLog(@"Refresh captcha tapped");
- [self loadCaptchaImage];
- }
- - (void)getCaptchaImageCompletion:(void(^)(UIImage *image))completion {
- NSString * urlstr=[NSString stringWithFormat:@"%@%@",[LCSaveData getBaseURL]?[LCSaveData getBaseURL]:BaseURL,GetCaptcha];
- NSURL *url = [NSURL URLWithString:urlstr];
- if (!url) {
- NSLog(@"Captcha URL is nil");
- return;
- }
-
- NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
- if (error) {
- NSLog(@"Error fetching captcha image: %@", error.localizedDescription);
- } else if (data) {
- UIImage *image = [UIImage imageWithData:data];
- if (image) {
- dispatch_async(dispatch_get_main_queue(), ^{
- completion(image);
- //self.captchaImageView.image = image;
- });
- } else {
- NSLog(@"Failed to convert data to image");
- }
- } else {
- NSLog(@"No data received for captcha image");
- }
- }];
- [task resume];
- }
- @end
|