由于 iOS6 上的全局外观属性,MFMailComposeViewController 崩溃

Posted

技术标签:

【中文标题】由于 iOS6 上的全局外观属性,MFMailComposeViewController 崩溃【英文标题】:MFMailComposeViewController Crashes because of Global Appearance Properties on iOS6 【发布时间】:2013-11-08 16:28:45 【问题描述】:

当我提交 MFMailComposeViewController 时出现以下崩溃:

2013-11-08 11:04:05.963 <redacted>[7108:1603] *** Assertion failure in NSDictionary *_UIRecordArgumentOfInvocationAtIndex(NSInvocation *, NSUInteger, BOOL)(), /SourceCache/UIKit/UIKit-2380.17/UIAppearance.m:1118
2013-11-08 11:04:06.032 <redacted>[7108:1603] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unknown key, "NSColor" in title text attributes dictionary'

我已经在我的 AppDelegate 的 application:didFinishLaunchingWithOptions: 方法中追踪到以下外观设置:

        [[UINavigationBar appearance] setTitleTextAttributes:
            @NSForegroundColorAttributeName : [UIColor whiteColor]];

注释掉该行可以解决问题,但会破坏应用程序的其余部分,因此我尝试专门将 titleTextAttributes 设置为 MFMailComposeViewController 的空字典:

尝试 #1

        [[UINavigationBar appearanceWhenContainedIn:
            NSClassFromString(@"MFMailComposeViewController"), nil]
            setTitleTextAttributes:@ ];

这会导致同样的崩溃。和

        [[UINavigationBar appearanceWhenContainedIn:
            NSClassFromString(@"MFMailComposeViewController"), nil]
            setTitleTextAttributes:nil];

也会导致同样的崩溃。

尝试 #2

我注意到MFMailComposeViewControllerUINavigationController,所以可能全局外观设置被本地化到 UIViewControllers inside UINavigationController。我整理了一些代码来确定 MFMailComposeViewController 中的视图控制器:

        for (UIViewController *viewController in mailViewController.viewControllers) 
            NSLog(@"%@", NSStringFromClass([viewController class]));
        

输出结果:

2013-11-08 11:04:05.936 <redacted>[7108:907] MFMailComposeInternalViewController

所以我尝试了(尽管依赖 Apple 的私有视图控制器是不好的做法)

        [[UINavigationBar appearanceWhenContainedIn:
            NSClassFromString(@"MFMailComposeViewController"), nil]
            setTitleTextAttributes:@ ];

        [[UINavigationBar appearanceWhenContainedIn:
            NSClassFromString(@"MFMailComposeViewController"), nil]
            setTitleTextAttributes:nil];

但这仍然会导致同样的崩溃!

尝试 #3

        // right before instantiating the MFMailComposeViewController
        [[UINavigationBar appearance] setTitleTextAttributes:@ ];

        [[UINavigationBar appearance] setTitleTextAttributes:nil];

然后在dismissViewController:animated:completion:的完成块中恢复全局外观属性

但是,这种方法也不起作用。有谁知道如何在全局 UINavigationBar 外观上设置 titleTextAttributes 而不会导致 MFMailComposeViewController 崩溃?

【问题讨论】:

【参考方案1】:

尝试使用UITextAttributeTextColor 而不是NSForegroundColorAttributeName

【讨论】:

伙计,我不敢相信这是这么愚蠢的事情。这是在 ios 版本中不断来回切换的枚举之一;我无法直截了当。 天哪,谢谢乔纳森!! 20 工时的调试由此解决。 我想补充一点,QLPreviewController 也会出现同样的问题。使用 UIAppearance 和 NSForegroundColorAttributeName 时会崩溃。使用现在已弃用的 UITextAttributeTextColor 工作正常。 我的问题似乎是这个和将NSFontAttributeName 更改为UITextAttributeFont 的结合 这似乎是iOS 8的错误,但即使使用上述解决方案也没有运气。【参考方案2】:

只是扩展 UINavigationController 类

@interface MyNavigationController : UINavigationController
@end

用新的子类替换你所有的 UINavigationController 类 和您的应用委托中的 [appearanceWhenContainedIn:]

[UINavigationBar appearanceWhenContainedIn:[MyNavigationController class], nil].titleTextAttributes = @ NSForegroundColorAttributeName : [UIColor whiteColor] ;

之后你的应用就不会崩溃了。

【讨论】:

我更喜欢这个解决方案,因为它在架构上更正确。【参考方案3】:

我能够解决此问题的唯一方法是为我的每个UIViewControllers 创建[[UINavigationBar appearanceWhenContainedIn:] setTitleTextAttributes:]。幸运的是,这相当简单,因为我所有的自定义视图控制器都来自 4 个视图控制器子类。

编辑:见this answer,因为我很笨。

【讨论】:

您是否向苹果提交了错误?

以上是关于由于 iOS6 上的全局外观属性,MFMailComposeViewController 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

iOS 6 vs 7 外观构建设置

iOS 6 上的allowAirPlayVideo 属性

UITabBar 外观适用于 iOS6 但不适用于 iOS 5

保持我的 ios 应用程序在 ios6 中而不是 ios7 中的外观

UILabel 外观字体和属性字符串字体

iOS 6 iPhone 5 App 在Phonegap Build 中没有全屏显示?