更改 UIActionSheet 中项目的文本颜色 - iOS 8

Posted

技术标签:

【中文标题】更改 UIActionSheet 中项目的文本颜色 - iOS 8【英文标题】:Change Text Color of Items in UIActionSheet - iOS 8 【发布时间】:2014-06-11 04:52:13 【问题描述】:

我一直在使用以下代码来更改我在UIActionSheet 中添加的项目的文本颜色。:

- (void)willPresentActionSheet:(UIActionSheet *)actionSheet 
    for (UIView *subview in actionSheet.subviews) 
        if ([subview isKindOfClass:[UIButton class]]) 
            UIButton *button = (UIButton *)subview;
            [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        
    

ios7 中可以正常工作,但在iOS8 中,上面的代码不会改变项目的文本颜色。

现在我的问题是如何使用iOS8 更改我在UIActionSheet 添加的项目的文本颜色?? 其他信息: 我添加了断点以查看上述代码中的以下几行是否被执行:

UIButton *button = (UIButton *)subview;
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

这些行不会被执行。因此,if([subview isKindOfClass:[UIButton class]]) 对于actionSheet.subviews 的所有项目始终为false。所以我认为 UIActionSheet 已更改。

【问题讨论】:

视图层次结构确实已经改变,你不应该在 iOS 8 中再使用UIActionSheet。改用UIAlertController 如果我使用'UIAlertController',有没有办法改变'UIAlertAction'的文本颜色?? @borrrden:今年没有保密协议。 @ScottBerrevoets 一个保密协议,它只是更轻松。它仍然适用于 WWDC 上未讨论的事情 meta.stackexchange.com/questions/94465 【参考方案1】:

如果您仍想使用UIActionSheet 而不是UIAlertController 来支持旧的iOS 版本,有一个简单的方法。

UIActionSheet实际上在iOS 8中使用UIAlertController,它有一个私有属性_alertController

SEL selector = NSSelectorFromString(@"_alertController");
if ([actionSheet respondsToSelector:selector])

    UIAlertController *alertController = [actionSheet valueForKey:@"_alertController"];
    if ([alertController isKindOfClass:[UIAlertController class]])
    
        alertController.view.tintColor = [UIColor blueColor];
    

else

    // use other methods for iOS 7 or older.

对于 Swift,下面的代码应该可以工作

let alertAction = UIAlertAction(title: "XXX", style: .default)  (action) in

     

    alertAction.setValue(UIColor.red, forKey: "titleTextColor")

【讨论】:

使用私有属性可能会导致应用被拒绝 要正确执行此操作,您应该在 iOS7 及更低版本上使用 UIActionSheet 和 UIAlertView,在 iOS8 及更高版本上使用 UIAlertController。对于我的项目,我编写了一个“自定义”AlertController,它会根据操作系统版本自动选择正确的方法。糟糕的是我不能分享,但我肯定会推荐这样做,因为使用 UIActionSheet 时可能会在 iOS8 上出现一些错误 这个会被苹果拒绝吗?如果我用这个? 很好,但是你怎么知道那个专业的?【参考方案2】:

要更改按钮标题颜色,您需要使用UIAlertController 并设置主viewtintColor

将按钮标题颜色设置为黑色的示例:

UIAlertController *actionSheetController = [UIAlertController alertControllerWithTitle:@"How would you like to proceed?" message:@"" preferredStyle:UIAlertControllerStyleActionSheet];

UIAlertAction *finish = [UIAlertAction actionWithTitle:@"Finish" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
                               
                                   [self performSelector:@selector(finish:) withObject:nil];
                               ];

UIAlertAction *playAgain = [UIAlertAction actionWithTitle:@"Play Again" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
                            
                                [self performSelector:@selector(playAgain:) withObject:nil];
                            ];

UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action)
                         
                             [actionSheetController dismissViewControllerAnimated:YES completion:nil];
                         ];

[actionSheetController addAction:finish];
[actionSheetController addAction:playAgain];
[actionSheetController addAction:cancel];

//******** THIS IS THE IMPORTANT PART!!!  ***********
actionSheetController.view.tintColor = [UIColor blackColor];

[self presentViewController:actionSheetController animated:YES completion:nil];

【讨论】:

这是一个很好的答案。虽然,我仍在寻找一种方法来设置每个按钮的色调以及UIAlertController 的背景颜色。有什么想法吗? @Jorge 我记得在某处读到 Apple 不希望您自定义操作表/警报颜色。我相信,如果你想做比我提到的更多的自定义,你需要创建自己的警报类,或者从 github 借用许多现成的开源选项之一。 这不适用于样式.Alert。 Apple 很可能不会预见到警报的修改。 我们至少可以改变字体和标题颜色吗? Apple 至少应该允许我们进行简单的自定义,而不是使用功能类似于 alertview 或 actionsheet 的 uiview。 是的,GUI(图形)的部分目的是有时通过颜色使其清晰和明显,例如当一个人要删除某些东西时,红色用于表示,你是即将做一些有潜在后果的事情。史蒂夫乔布去世后的一些苹果选择似乎并不明智。【参考方案3】:

好的,我遇到了同样的问题,但我想我找到了解决方案:

适当的方式应该是这样的,我猜它适用于iOS7:

[[UIButton appearanceWhenContainedIn:[UIActionSheet class], nil] setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];

但由于 ActionSheets“按钮”现在基于 UICollectionView,它在 iOS8 中不起作用。 所以经过一番挖掘后,我得到了这个工作:

[[UICollectionView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor blueColor]];

【讨论】:

只有我看到这会改变除取消按钮之外的所有按钮的颜色吗? 这肯定会产生意想不到的副作用,不建议这样做。更改 UIAlertController 中所有 UICollectionViews 的色调颜色是脆弱的,并且依赖于 Apple 为当前版本的 iOS 选择的视图层次结构。正如您从这个答案中看到的那样,他们从 iOS 7-> iOS 8 更改了视图层次结构,是什么阻止他们在 iOS 9 中再次这样做?这肯定需要在未来进行更新,因此不建议这样做。 @friedegg-bacon-sandwich 除了取消按钮之外,我将所有内容都设置为浅色。看起来非常愚蠢。你知道如何将取消按钮也设置为着色吗? @friedegg-bacon-sandwich 有人解决过顽固的取消按钮问题吗?【参考方案4】:

我正在使用它。

[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor blueColor]];

添加一行(AppDelegate)并适用于所有 UIAlertController。

【讨论】:

最佳解决方案 imo。我添加了a few tweaks 以实现向后兼容性并获得默认的色调,而不是UIColor.blueColor【参考方案5】:

我有同样的任务,我今天做了这个 hack,很脏,但它有效

class CustomAlertViewController: UIAlertController 

    internal var cancelText: String?


    private var font: UIFont? = UIFont(name: "MuseoSansCyrl-500", size: 12)

    override func viewDidLoad() 
        super.viewDidLoad()

        self.view.tintColor = UIColor.blackColor()
    

    override func viewWillLayoutSubviews() 
        super.viewWillLayoutSubviews()

        self.findLabel(self.view) //if you need ios 9 only, this can be made in viewWillAppear
    

    func findLabel(scanView: UIView!) 
        if (scanView.subviews.count > 0) 
            for subview in scanView.subviews 
                if let label: UILabel = subview as? UILabel 

                    if (self.cancelText != nil && label.text == self.cancelText!) 
                        dispatch_async(dispatch_get_main_queue(),
                            label.textColor = UIColor.redColor() //for ios 8.x
                            label.tintColor = UIColor.redColor() //for ios 9.x
                        )
                    

                    if (self.font != nil) 
                        label.font = self.font
                    
                

                self.findLabel(subview)
            
        
    


【讨论】:

这个答案是最好的。【参考方案6】:

更改windowtintColor 对我有用。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method

写这个:

[self.window setTintColor:[UIColor redColor]];

这改变了所有UIActionSheet 对象的字体颜色。

【讨论】:

虽然这不能回答 OP 的问题,但它只是解决了我的具体问题。谢谢!【参考方案7】:

为了向后兼容 iOS 7,并收集正确的默认色调(Apple 可能会在未来的版本中更改),我使用了这个。感谢上面关于default tint 和Lucas's answer 的回答。

    const Class alertControllerClass = NSClassFromString(@"UIAlertController");
    if(alertControllerClass)
    
        UIColor *defaultTintColour = UIView.new.tintColor;
        [[UIView appearanceWhenContainedIn: alertControllerClass, nil] setTintColor: defaultTintColour];
    

但请注意——您需要确保在开始设置全局色调之前使用此选项,否则UIView.new.tintColor 只会为您提供您设置的当前色调。

【讨论】:

由于某种原因,这不适用于 iOS 9 上的 iPad。便便。 :-( [self.window setTintColor:[UIColor whateverColor]] 是我发现的唯一适用于 iOS 8 和 9 的东西 @whyoz 我会看看——我已经出于某种原因将其设置为其他内容,但也许我可以在其他地方实现...【参考方案8】:

斯威夫特 4

    let alert =  UIAlertController(title: "title", message: "message", preferredStyle: .alert)
    alert.view.tintColor = UIColor.black
    self.present(alert, animated: true, completion: nil)

【讨论】:

【参考方案9】:

对于 Swift 你可以这样做

    let alertAction = UIAlertAction(title: "XXX", style: .default)  (action) in

     

    alertAction.setValue(UIColor.red, forKey: "titleTextColor")

【讨论】:

以上是关于更改 UIActionSheet 中项目的文本颜色 - iOS 8的主要内容,如果未能解决你的问题,请参考以下文章

更改 UIAlertview 和 UIActionsheet 按钮的色调颜色

具有许多项目的 UIActionSheet 覆盖文本

如何在 Cordova iOS 项目中更改文本字段光标颜色

使用android中的颜色选择器更改textview的文本颜色和背景颜色

如何在Cordova iOS项目中更改文本字段光标颜色

更改 ItemDelegate 的背景和文本颜色