提问人:Simon McNeil 提问时间:11/3/2023 最后编辑:TimmySimon McNeil 更新时间:11/5/2023 访问量:52
UIAlertController 作为子视图控制器,不响应点击
UIAlertController as child view controller not responding to tap
问:
所以我有一个需要呈现在另一个视图控制器之上的,所以是一个子视图控制器。我可以让子视图控制器显示在父视图的顶部没有问题,但是当我将这个子视图控制器放在前面时,我无法让警报按钮响应。UIAlertController
UIAlertController* alert = [AlertHelper createAlertWithTitle:title
message:message
cancelButton:nil
continueButtonText:Ok
continueAction:nil
cancelAction:nil];
alert.view.translatesAutoresizingMaskIntoConstraints = false;
[self addChildViewController:alert];
alert.view.frame = self.view.bounds;
[self.view addSubview:alert.view];
[alert didMoveToParentViewController:self];
[alert.view.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = YES;
[alert.view.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = YES;
答:
0赞
DonMag
11/5/2023
#1
UIAlertController
是利用 .UIAlertAction
值得一提的是,苹果的文档:
重要
UIAlertController 类应按原样使用,不支持子类化。此类的视图层次结构是私有的,不得修改。
虽然你可能没有对它进行子类化(你没有提供你的代码),但你显然没有“按原样”使用它。AlertHelper
相反,您可能希望设计自己的“模拟”警报控制器。
这里有一个简单的例子......
AlertHelper.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface AlertHelper : NSObject
+ (UIAlertController *)createAlertWithTitle:(NSString *)title
message:(NSString *)message
cancelButton:(NSString *)cancel
continueButtonText:(NSString *)ok
continueAction:(UIAction *)continueAction
cancelAction:(UIAction *)cancelAction;
@end
NS_ASSUME_NONNULL_END
AlertHelper.m(警报助手.m)
#import "AlertHelper.h"
@implementation AlertHelper
+ (UIViewController *)createAlertWithTitle:(NSString *)title
message:(NSString *)message
cancelButton:(NSString *)cancel
continueButtonText:(NSString *)ok
continueAction:(UIAction *)continueAction
cancelAction:(UIAction *)cancelAction;
{
UIViewController *vc = [UIViewController new];
vc.view.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.25];
UIView *bkg = [UIView new];
bkg.clipsToBounds = YES;
bkg.backgroundColor = [UIColor systemBackgroundColor];
bkg.layer.cornerRadius = 12.0;
UILabel *titleLabel = [UILabel new];
titleLabel.font = [UIFont systemFontOfSize:17.0 weight:UIFontWeightSemibold];
titleLabel.numberOfLines = 0;
titleLabel.textAlignment = NSTextAlignmentCenter;
titleLabel.text = title;
UILabel *msgLabel = [UILabel new];
msgLabel.font = [UIFont systemFontOfSize:13.0 weight:UIFontWeightRegular];
msgLabel.numberOfLines = 0;
msgLabel.textAlignment = NSTextAlignmentCenter;
msgLabel.text = message;
UIButton *cancelButton = [UIButton systemButtonWithPrimaryAction:cancelAction];
UIButton *okButton = [UIButton systemButtonWithPrimaryAction:continueAction];
cancelButton.layer.borderColor = [UIColor systemBlueColor].CGColor;
okButton.layer.borderColor = [UIColor systemBlueColor].CGColor;
cancelButton.layer.borderWidth = 1.0;
okButton.layer.borderWidth = 1.0;
for (UIView *v in @[bkg, titleLabel, msgLabel, okButton, cancelButton]) {
v.translatesAutoresizingMaskIntoConstraints = NO;
}
for (UIView *v in @[titleLabel, msgLabel, okButton, cancelButton]) {
[bkg addSubview:v];
}
[vc.view addSubview:bkg];
[NSLayoutConstraint activateConstraints:@[
[titleLabel.topAnchor constraintEqualToAnchor:bkg.topAnchor constant:20.0],
[titleLabel.leadingAnchor constraintEqualToAnchor:bkg.leadingAnchor constant:8.0],
[titleLabel.trailingAnchor constraintEqualToAnchor:bkg.trailingAnchor constant:-8.0],
[msgLabel.topAnchor constraintEqualToAnchor:titleLabel.bottomAnchor constant:4.0],
[msgLabel.leadingAnchor constraintEqualToAnchor:bkg.leadingAnchor constant:8.0],
[msgLabel.trailingAnchor constraintEqualToAnchor:bkg.trailingAnchor constant:-8.0],
[cancelButton.topAnchor constraintEqualToAnchor:msgLabel.bottomAnchor constant:20.0],
[cancelButton.leadingAnchor constraintEqualToAnchor:bkg.leadingAnchor constant:-1.0],
[okButton.topAnchor constraintEqualToAnchor:cancelButton.topAnchor constant:0.0],
[okButton.trailingAnchor constraintEqualToAnchor:bkg.trailingAnchor constant:1.0],
[cancelButton.bottomAnchor constraintEqualToAnchor:bkg.bottomAnchor constant:1.0],
[cancelButton.trailingAnchor constraintEqualToAnchor:okButton.leadingAnchor constant:1.0],
[cancelButton.widthAnchor constraintEqualToAnchor:okButton.widthAnchor],
[cancelButton.heightAnchor constraintEqualToConstant:40.0],
[okButton.heightAnchor constraintEqualToAnchor:cancelButton.heightAnchor],
[bkg.widthAnchor constraintEqualToConstant:274.0],
[bkg.centerXAnchor constraintEqualToAnchor:vc.view.centerXAnchor],
[bkg.centerYAnchor constraintEqualToAnchor:vc.view.centerYAnchor],
]];
return vc;
}
@end
以及一个示例视图控制器:
** ViewController.h**
#import < UIKit/UIKit.h>
@interface ViewController:UIViewController @end
** ViewController.m**
#import "ViewController.h"
#import "AlertHelper.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor systemYellowColor];
UIAction *act = [UIAction actionWithTitle:@"Show Fake Alert VC" image:nil identifier:nil handler:^(UIAction * _Nonnull action) {
[self showFakeAlertVC];
}];
UIButton *btn = [UIButton systemButtonWithPrimaryAction:act];
btn.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0];
btn.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:btn];
UILayoutGuide *g = self.view.safeAreaLayoutGuide;
[NSLayoutConstraint activateConstraints:@[
[btn.topAnchor constraintEqualToAnchor:g.topAnchor constant:60.0],
[btn.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:80.0],
[btn.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:-80.0],
]];
}
- (void)removeFakeAlertVC {
UIViewController *vc;
for (int i = 0; i < [self.childViewControllers count]; i++) {
if ([self.childViewControllers[i].title isEqualToString:@"MyFakeAlertVC"]) {
vc = self.childViewControllers[i];
break;
}
}
if (nil != vc) {
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
}
}
- (void)showFakeAlertVC {
UIAction *okAction = [UIAction actionWithTitle:@"Continue" image:nil identifier:nil handler:^(UIAction * _Nonnull action) {
// do something because OK / Continue was tapped
NSLog(@"OK tapped!");
[self removeFakeAlertVC];
}];
UIAction *cancelAction = [UIAction actionWithTitle:@"Cancel" image:nil identifier:nil handler:^(UIAction * _Nonnull action) {
// do something because Cancel was tapped
NSLog(@"Cancel tapped!");
[self removeFakeAlertVC];
}];
UIViewController *alert = [AlertHelper createAlertWithTitle:@"Some really long Title that we expect to wrap."
message:@"Some really long Message that we also expect to wrap."
cancelButton:@"Cancel Btn"
continueButtonText:@"Continue Btn"
continueAction:okAction
cancelAction:cancelAction
];
[self addChildViewController:alert];
// we'll use this when we want to remove the
// view and child controller
// in case we have more than one child
alert.title = @"MyFakeAlertVC";
UIView *sv = self.view;
UIView *v = alert.view;
v.translatesAutoresizingMaskIntoConstraints = false;
[sv addSubview:v];
[alert didMoveToParentViewController:self];
[NSLayoutConstraint activateConstraints:@[
[v.topAnchor constraintEqualToAnchor:sv.topAnchor constant:0.0],
[v.leadingAnchor constraintEqualToAnchor:sv.leadingAnchor constant:0.0],
[v.trailingAnchor constraintEqualToAnchor:sv.trailingAnchor constant:0.0],
[v.bottomAnchor constraintEqualToAnchor:sv.bottomAnchor constant:0.0],
]];
}
@end
输出:
评论
UIAlertController