iOS 6 MFMailComposeViewController: 仅支持RGBA或白色色彩空间,此方法是一种hack。

27

出现了一个非常奇怪的错误

我的应用程序在iOS 5/.1中运行良好,但是在iOS 6中出现了一些过渡问题,但这个问题很令人困惑。

我有一些启动邮件编写器的代码,自从iOS 6以来,它会导致崩溃并显示以下错误:

* 在-[UICGColor encodeWithCoder:]中进行断言失败,/SourceCache/UIKit/UIKit-2372/UIColor.m:1191 2012-09-26 02:14:38.044 MyCQs Medical[2126:1b03] * Terminating app due to uncaught exception 'NSInternalInconsistencyException',reason: 'Only support RGBA or the White color space, this method is a hack.'

有什么建议吗?通过注释掉各种行进行试错,似乎是alloc/init行引起了错误,尽管当所有行都取消注释时,所有NSLog都被执行,包括“present”,这表明已经调用了应该调用的所有内容。应用程序在邮件合成器呈现在屏幕上之前崩溃,我真的很感激任何建议。

            if (indexPath.row == 3) {
               if([MFMailComposeViewController canSendMail]){
                   mailComposer = [[MFMailComposeViewController alloc]init];
                   NSLog(@"Alloc, init");
                   mailComposer.mailComposeDelegate = self;
                   NSLog(@"Set delegate");
                   NSArray *toArray = [[NSArray alloc]initWithObjects:@"john@doe.com", nil];
                   NSLog(@"To array");
                   [mailComposer setToRecipients:toArray];
                   NSLog(@"To recipients");
                   [mailComposer setSubject:@"Message from a MyCQs user!"];
                   NSLog(@"Subject");
                   NSLog(@"About to present mail composer");
                   [[mailComposer navigationBar] setTintColor:[UIColor blackColor]];
                   [self presentModalViewController:mailComposer animated:YES];
                   NSLog(@"Present");
             }
    }

1
你尝试过像这样设置mailComposer的navigationBar的色调吗? mailComposer.navigationBar.tintColor = [UIColor colorWithRed:1.0 Green:1.0 Blue:1.0 Alpha:1.0]; - geraldWilliam
哦,这里有个想法。尝试对MFMailComposeViewController进行子类化,呈现它并在其viewDidLoad中设置navigationBar.tintColor。 - geraldWilliam
我认为这一定与归档颜色有关...当我谷歌这个错误时,唯一出现的情况就是当人们试图这样做时。但是,它似乎很奇怪,因为它应该出现在MFMailComposeViewController alloc / init上吗?特别是在iOS 5.1中没有任何警告的情况下,并且我看不到该类的任何记录更改。我刚刚尝试禁用了所有自定义图形后运行它,以防它与此有关,但仍然出现相同的问题! - James Gupta
2
为什么苹果公司没有意识到这个问题?这是一个明显的漏洞,他们需要尽快修复。 - ryan
我可以在iOS 8中重现这个错误。我简直不敢相信这个错误已经存在了两年,而苹果还没有解决它... - Brian
显示剩余5条评论
10个回答

8

好的,这只是一个部分解决方案,但在不进行一些相当破坏性的代码更改的情况下,这是我能想到的最好的解决方法。

对于将来遇到此问题的任何其他人,我认为这是iOS 6中的一个错误,当您将UITableView separatorStyle设置为colorWithPatternImage时,MFMailComposeViewController会崩溃,但是当您使用单色时它可以正常工作,因此:

        if ([[[UIDevice currentDevice] systemVersion] floatValue] > 5.2) {
           NSLog(@"Using iOS 5x");
           [[UITableView appearance]setSeparatorColor:[UIColor colorWithRed:142.0/255.0          green:130.0/255.0 blue:76.0/255.0 alpha:1.0]];
        }
        else {
           NSLog(@"Using iOS 6x, Table view use pattern color");
           [[UITableView appearance]setSeparatorColor:[UIColor colorWithPatternImage: [UIImage imageNamed:@"dotted-line2.png"]]];
        }

5

我的问题也是由于使用了colorWithPatternImage,但我发现它似乎只会在显示在MFMailCompserViewController上的元素上引起问题,例如:

[[UINavigationBar appearance] setTintColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"navbar"]]];

5

实际上,我认为这是一个重要的错误。有人提交了雷达吗?

在我的看法中,只要您在呈现视图控制器的外观代理中使用“colorWithPatternImage”,断言就会抛出。

我认为发生的情况是iOS在切换到单独的服务之前尝试存储应用程序的外观(MFMailComposeViewController执行此操作,它现在是由您的应用程序呈现但由另一个应用程序/进程管理的“远程视图控制器”),因为邮件应用程序想要自己确定外观,所以会更改诸如色调颜色等内容。 有关远程视图控制器的更多信息,请参见此处: http://oleb.net/blog/2012/10/remote-view-controllers-in-ios-6/

这似乎失败了。这一定是一个错误,可以对图像进行编码。

解决方法可能很难。我尝试在呈现视图控制器之前将图案颜色替换为纯色,但发现您至少必须确保它真正重新绘制在屏幕上,并且放弃了(我不需要图案)。


4

我发现当colorWithPatternImage[[UITableView appearance]语句中使用时,MFMailComposeViewController会崩溃。但是,在表格的viewDidLoad中设置背景和separatorColor时没有问题。唯一的问题是你需要为每个表格都这样做。

[self.tableView setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"image.png"]]];
[self.tableView setSeparatorColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"image.png"]]];

2

@coolio是正确的,当使用任何控制器类与图案颜色时似乎会发生这种情况。(至少在UITabBarController和UITableViewController中显然如此。)

我通过子类化我的标签栏控制器并使用appearanceWhenContainedIn:来解决这个问题。这样你仍然可以使用你的花哨纹理,而无需子类化MFMailComposeViewController或嗅探iOS版本等。

UIColor *tabBarBgPattern = [UIColor colorWithPatternImage:...];
[[UITabBar appearanceWhenContainedIn:[MyTabBarController class],
                                     nil]
                  setBackgroundColor:tabBarBgPattern];

1

这个帖子给了我很好的线索,让我知道如何修复使用ShareKit并尝试通过电子邮件发送视图图像的类似问题。现在,我只会为低于6.0版本的UISwitch外观进行更改。

当我的应用程序启动时,将调用此代码:

// Protect against IOS 6.0 BUG: 'NSInternalInconsistencyException', reason: 'Only support RGBA or the White color space, this method is a hack.'
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0) {
    UIImage *patternImage = [UIImage imageNamed:@"solid-colors_blue.png"];
    UIColor* switchColor = [UIColor colorWithPatternImage:patternImage];
    [[UISwitch appearance] setOnTintColor: switchColor];
}  

1

我在使用'colorWithPatterImage'为我的tableViewController的navBar内的UIBarButtonItem设置颜色时,遇到了同样的问题。该tableViewController用于显示模态视图(我不是在使用MFMailComposeViewController)。

[[UIBarButtonItem appearance] setTintColor:[UIColor colorWithPatternImage:bgImage]];

我需要用RGBa颜色替换它;


1
我的应用在使用colorWithPatternImage并尝试展示MFMailComposeViewController时,在iOS 7上崩溃。我必须从UIImage中确定颜色,因为UIImage可以由用户选择,我想根据用户选择的图片来“主题化”我的应用程序。
对我而言,解决方案(尽管有点hacky)是获取UIImage原点(0,0)的RGBA值,然后将其应用作背景颜色,而不是使用colorWithPatternImage
+ (UIColor*)getUIColorFromImageAtOrigin:(UIImage*)image
{        
    // First get the image into your data buffer
    CGImageRef imageRef = [image CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                                 bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);

    // Now your rawData contains the image data in the RGBA8888 pixel format.
    int byteIndex = (bytesPerRow * 0) + 0 * bytesPerPixel;

    CGFloat red   = (rawData[byteIndex]     * 1.0) / 255.0;
    CGFloat green = (rawData[byteIndex + 1] * 1.0) / 255.0;
    CGFloat blue  = (rawData[byteIndex + 2] * 1.0) / 255.0;
    CGFloat alpha = (rawData[byteIndex + 3] * 1.0) / 255.0;

    UIColor *acolor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];

    free(rawData);

    return acolor;
}

现在,如果我使用这个UIColor作为背景,而不是colorWithPatternImage,我可以尽情分享,而不会遇到这个奇怪的异常。
上述方法是从我在这里找到的解决方案中改编的:https://dev59.com/qHRB5IYBdhLWcg3w-8A9#1262893

0

使用图案时,您可以使用resizableImageWithCapInsets。 在Monotouch中,它看起来像这样:

var sba = UISearchBar.Appearance;

var img = UIImage.FromBundle("myResource.png");

if (UIDevice.CurrentDevice.CheckSystemVersion(6, 0)) {
    img = img.CreateResizableImage(UIEdgeInsets.Zero, UIImageResizingMode.Tile);
    sba.BackgroundColor = UIColor.LightGray;
    sba.BackgroundImage = img;
} else {
    sba.BackgroundImage = new UIImage();
    sba.BackgroundColor = UIColor.FromPatternImage(img);
}

0

这是iOS 6的一个漏洞,我已经报告过了,而且它被标记为重复。所以,有人早先就报告了那个漏洞。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接