質問は iOS 8 UIActivityViewControllerおよびUIAlertControllerボタンのテキストの色はウィンドウのtintColorを使用 に似ていますが、iOS 9にあります。
UIAlertControllerがあり、設定しようとしても閉じるボタンが白い色を保持します
[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor blackColor]];
UIAlertController *strongController = [UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:preferredStyle];
strongController.view.tintColor = [UIColor black];
過去に同様の問題に遭遇しましたが、問題はアラートコントローラーのビューがtintColor
の変更を表示する前に受け入れる準備ができていないという事実に起因するようです。または、色合いを設定してみてください[〜#〜] after [〜#〜]アラートコントローラーを提示します:
[self presentViewController:strongController animated:YES completion:nil];
strongController.view.tintColor = [UIColor black];
In Swift 3.x:
以下が効果的に機能することがわかりました。これをアプリの起動時に呼び出します。
UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = UIColor.black
したがって、これにより、アプリ内のすべてのUIAlertViewControllerボタンラベルの色合いがグローバルに変更されます。変更されない唯一のボタンラベルの色は、破壊的なUIAlertActionStyleを持つものです。
Objective-C
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title text" message:@"Message text" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
//code here…
}];
UIAlertAction* cancel = [UIAlertAction actionWithTitle:@"Later" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
//code here….
}];
[ok setValue:[UIColor greenColor] forKey:@"titleTextColor"];
[cancel setValue:[UIColor redColor] forKey:@"titleTextColor"];
[alertController addAction:ok];
[alertController addAction:cancel];
[alertController.view setTintColor:[UIColor yellowColor]];
[self presentViewController:alertController animated:YES completion:nil];
Swift 3
let alertController = UIAlertController(title: "Title text", message: "Message text", preferredStyle: .alert)
let ok = UIAlertAction(title: "Yes" , style: .default) { (_ action) in
//code here…
}
let cancel = UIAlertAction(title: "Later" , style: .default) { (_ action) in
//code here…
}
ok.setValue(UIColor.green, forKey: "titleTextColor")
cancel.setValue(UIColor.red, forKey: "titleTextColor")
alertController.addAction(ok)
alertController.addAction(cancel)
alertController.view.tintColor = .yellow
self.present(alertController, animated: true, completion: nil)
UIAlertController
をサブクラス化することでこれを解決できました。
class MyUIAlertController: UIAlertController {
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
//set this to whatever color you like...
self.view.tintColor = UIColor.blackColor()
}
}
これは、アラートが表示されている間、デバイスの回転に耐えます。
また、このサブクラスを使用するときにアラートを表示した後、tintColorを設定する必要はありません。
IOS 8.4では必要ありませんが、このコードはiOS 8.4でも機能します。
Objective-Cの実装は次のようになります。
@interface MyUIAlertController : UIAlertController
@end
@implementation MyUIAlertController
-(void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
//set this to whatever color you like...
self.view.tintColor = [UIColor blackColor];
}
@end
Swift
UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = MyColor
を使用しようとしましたが、これによりUIAlertController
に関係のない他のアイテムがtintColor設定から除外されます。ナビゲーションバーのボタン項目の色を変更しようとしたときに見ました。
拡張機能(上記のMike Taverneの回答に基づく)に切り替えたところ、うまく機能しました。
extension UIAlertController {
override open func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
//set this to whatever color you like...
self.view.tintColor = MyColor
}
}
表示後のビューの色合いの設定に問題があります。 presentViewController:animated:completion:の完了ブロックで実行しても、ボタンタイトルの色にちらつき効果が発生します。これはずさんで、専門的ではなく、まったく受け入れられません。
この問題を解決し、どこでもそれを行う確実な方法の1つは、UIAlertControllerにカテゴリを追加し、viewWillAppearをスウィズルすることです。
ヘッダー:
//
// UIAlertController+iOS9TintFix.h
//
// Created by Flor, Daniel J on 11/2/15.
//
#import <UIKit/UIKit.h>
@interface UIAlertController (iOS9TintFix)
+ (void)tintFix;
- (void)swizzledViewWillAppear:(BOOL)animated;
@end
実装:
//
// UIAlertController+iOS9TintFix.m
//
// Created by Flor, Daniel J on 11/2/15.
//
#import "UIAlertController+iOS9TintFix.h"
#import <objc/runtime.h>
@implementation UIAlertController (iOS9TintFix)
+ (void)tintFix {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method method = class_getInstanceMethod(self, @selector(viewWillAppear:));
Method swizzle = class_getInstanceMethod(self, @selector(swizzledViewWillAppear:));
method_exchangeImplementations(method, swizzle);});
}
- (void)swizzledViewWillAppear:(BOOL)animated {
[self swizzledViewWillAppear:animated];
for (UIView *view in self.view.subviews) {
if (view.tintColor == self.view.tintColor) {
//only do those that match the main view, so we don't strip the red-tint from destructive buttons.
self.view.tintColor = [UIColor colorWithRed:0.0 green:122.0/255.0 blue:1.0 alpha:1.0];
[view setNeedsDisplay];
}
}
}
@end
プロジェクトに.pch(プリコンパイル済みヘッダー)を追加し、カテゴリを含めます。
#import "UIAlertController+iOS9TintFix.h"
プロジェクトにpchを適切に登録してください。UIAlertControllerを使用するすべてのクラスにカテゴリメソッドが含まれます。
次に、アプリデリゲートdidFinishLaunchingWithOptionsメソッドで、カテゴリをインポートして呼び出します
[UIAlertController tintFix];
コードまたは他の誰かによって起動されたかどうかにかかわらず、アプリ内のUIAlertControllerのすべてのインスタンスに自動的に伝播します。
このソリューションは、iOS 8.XとiOS 9.Xの両方で機能し、色調変更後のプレゼンテーションアプローチのちらつきがありません。
この旅を始めるために上記のブランドンに気違いの小道具、残念ながら私の評判は彼の投稿にコメントするのに十分ではなかった、さもなければ私はそれをそこに残したでしょう!
[[UIView appearance] setTintColor:[UIColor black]];
これにより、すべてのUIView tintColor
およびUIAlertController
のビュー
以下を使用して変更できます:Swift 3.x
strongController.view.tintColor = UIColor.green
これに対する解決策を見つけました。エレガントなソリューションではなく、ソリューション。
UIAlertControllerでviewWillAppear:をスウィズルし、ビューをループして色合いの色を変更しました。私の場合、ウィンドウ全体にtintColorが設定されており、外観でtintColorを設定したにもかかわらず、UIAlertControllerはウィンドウの色を維持していました。色がウィンドウの色と等しいかどうかを確認し、等しい場合は新しい色を適用します。 tintColorをすべてのビューにブラインドで適用すると、破壊的なアクションの赤い色合いがリセットされます。
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method swizzleMethod = class_getInstanceMethod(self, @selector(viewWillAppear:));
Method method = class_getInstanceMethod(self, @selector(alertSwizzle_viewWillAppear:));
method_exchangeImplementations(method, swizzleMethod);
});
}
- (void)alertSwizzle_viewWillAppear:(BOOL)animated
{
[self alertSwizzle_viewWillAppear:animated];
[self applyTintToView:self.view];
}
- (void)applyTintToView:(UIView *)view
{
UIWindow *mainWindow = [UIApplication sharedApplication].keyWindow;
for (UIView *v in view.subviews) {
if ([v.tintColor isEqual:mainWindow.tintColor]) {
v.tintColor = [UIColor greenColor];
}
[self applyTintToView:v];
}
}
ただし、これはiOS 8では機能しないため、外観の色合いを設定する必要があります。
[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor greenColor]];
Swift 2.2では、次のコードを使用できます
// LogOut or Cancel
let logOutActionSheet: UIAlertController = UIAlertController(title: "Hello Mohsin!", message: "Are you sure you want to logout?", preferredStyle: .Alert)
self.presentViewController(logOutActionSheet, animated: true, completion: nil)
let cancelActionButton: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
print("Cancel Tapped")
}
logOutActionSheet.addAction(cancelActionButton)
let logOutActionButton: UIAlertAction = UIAlertAction(title: "Clear All", style: .Default)
{ action -> Void in
//Clear All Method
print("Logout Tapped")
}
logOutActionButton.setValue(UIColor.redColor(), forKey: "titleTextColor")
logOutActionSheet.addAction(logOutActionButton)
最も合理的な方法は、メインウィンドウのtintColorを設定することです。均一な外観が通常必要です。
// in app delegate
window.tintColor = ...
他のソリューションには欠陥があります
外観を使用する
UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = ...
IOS 9、iOS 11 SDKでのテストでは機能しません。
[[UIView appearance] setTintColor:[UIColor black]];
真剣ですか?
UIAlertControllerビューのtintColorが不安定であることを設定します。ユーザーがボタンを押すか、レイアウトを表示すると、色が変わる場合があります。
サブクラスUIAlertControllerと上書きレイアウトメソッドは、受け入れられないハック方法です。
アクションボタンには3つのスタイルがあります。
let style : UIAlertActionStyle = .default
// default, cancel (bold) or destructive (red)
let alertCtrl = UIAlertController(....)
alertCtrl.addAction( UIAlertAction(title: "click me", style: style, handler: {
_ in doWhatever()
}))
削除ボタンを赤く表示したかったので、.destructiveスタイルを使用しました。
alert.addAction(UIAlertAction(title: "Delete", style: .destructive, handler:{(UIAlertAction) in