代替案があります。UIAlertControl
のビュー階層にサブビューを追加するのではなく、代わりに適切な位置にUIWindow
を追加します。 UIAlertControl
のビューフレームを追跡するために、ビューコントローラは、UIViewController
スーパークラス実装を呼び出すobj-cランタイム/スウィフト拡張を使用して、カスタム.viewゲッターで拡張されます。これにより、本物のビューのプライベートクラス依存を避けることができ、UIAlertControl
をサブクラス化することも、ビューの階層を変更することもできません。
Example screenshot
のObjective-C
#import <objc/runtime.h>
#import <objc/message.h>
@implementation AppDelegate
+ (UIView*)alertHelperView
{
static UIView *alertHelperView = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
alertHelperView = [UIView new];
alertHelperView.backgroundColor = [UIColor redColor];
alertHelperView.frame = CGRectZero;
});
return alertHelperView;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self.window addSubview:[AppDelegate alertHelperView]];
return YES;
}
@end
@implementation ViewController
- (void)viewDidAppear:(BOOL)animated {
Class class = [UIAlertController class];
class_addMethod(class, @selector(view), imp_implementationWithBlock(^(__unsafe_unretained UIAlertController* self) {
struct objc_super super = {
.receiver = self,
.super_class = class_getSuperclass(class)
};
id (*objc_msgSendSuper_typed)(struct objc_super *, SEL) = (void *)&objc_msgSendSuper;
UIView* myView = objc_msgSendSuper_typed(&super, @selector(view));
CGRect newFrame = myView.frame;
if (!self.isBeingPresented) {
[AppDelegate alertHelperView].frame = CGRectZero;
} else {
[[AppDelegate alertHelperView].superview bringSubviewToFront:[AppDelegate alertHelperView]];
[AppDelegate alertHelperView].frame = CGRectMake(newFrame.origin.x,
newFrame.origin.y,
newFrame.size.width/2,
newFrame.size.height/2);
}
return myView;
}), "@@:");
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:@"Info"
message:@"You are using UIAlertController"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction
actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
}];
UIAlertAction* cancel = [UIAlertAction
actionWithTitle:@"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
}];
[alert addAction:ok];
[alert addAction:cancel];
[self presentViewController:alert animated:YES completion:nil];
}
@end
スウィフト3.1
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
static var alertHelperView : UIView!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
AppDelegate.alertHelperView = UIView()
AppDelegate.alertHelperView.backgroundColor = .red
self.window?.addSubview(AppDelegate.alertHelperView!)
return true
}
}
extension UIAlertController {
open override var view: UIView! {
get {
let newFrame : CGRect = super.view.frame
if !self.isBeingPresented {
AppDelegate.alertHelperView.frame = CGRect.zero
} else {
AppDelegate.alertHelperView.superview?.bringSubview(toFront: AppDelegate.alertHelperView)
AppDelegate.alertHelperView.frame = CGRect(x:newFrame.origin.x,y:newFrame.origin.y,width:newFrame.size.width/2,height:newFrame.size.height/2)
}
return super.view
}
set(newValue) {
super.view = newValue
}
}
}
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
let alertController = UIAlertController(title: "Default Style", message: "A standard alert.", preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { action in
// ...
}
alertController.addAction(cancelAction)
let OKAction = UIAlertAction(title: "OK", style: .default) { action in
// ...
}
alertController.addAction(OKAction)
self.present(alertController, animated: false) {
}
}
}
}
私は '使用すると、あなたは簡単に' UIAlertController'の挙動を再現することができますUIPresentationController'ことを追加しますどんなビュー/コントローラを提供してもかまいません。 – jjatie
@jjatie、 'UIAresentController'を使って' UIAlertController'の振る舞いを複製/拡張するサンプルプロジェクト/ツットがありますか?私は 'UIPresentationController'でまだ働いていません。 –
ここが出発点です。 CoolPresentationControllerが閉じます。 https://developer.apple.com/library/content/samplecode/LookInside/Introduction/Intro.html#//apple_ref/doc/uid/TP40014643関連するWWDCビデオもあります – jjatie