iOS UI 外观错误
Posted
技术标签:
【中文标题】iOS UI 外观错误【英文标题】:iOS UIAppearance Error 【发布时间】:2012-06-21 03:28:40 【问题描述】:我正在构建一个文件管理应用程序,在调用UIImagePickerController
或MPMediaPickerController
时偶尔会收到以下错误:
*** -[_UIImageViewPretiledImageCacheKey hash]: message sent to deallocated instance 0x140dc0
我最近使用 ios 5 的 UIAppearance API 为我的应用程序提供了一个自定义主题,这就是我开始收到此错误的时候。通过猜测和检查,我发现了导致此错误的代码有问题的行:
UIImage *backButtonImage = [[UIImage imageNamed:@"backButton.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(12, 16, 12, 8)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
UIImage *barButtonImage = [[UIImage imageNamed:@"barButton.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(14, 12, 14, 12)];
[[UIBarButtonItem appearance] setBackgroundImage:barButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
我不知道这段代码是如何触发上述错误的。能否请您向我解释此错误的来源并提供解决方案。
提前感谢您的帮助, 古维
【问题讨论】:
对于那些不幸看到这个崩溃的人,这里是另一个非常有用的资源:@987654321@ 我们知道为什么会发生这种情况吗?我在 iOS 6 中得到了同样的结果。我正在自定义绘制自己的 20x20 图像,并且在所有方面都有 9 的上限插图... @bogardon 您是否在非视网膜设备上遇到此崩溃? 【参考方案1】:经过一些更彻底的测试,我得出的结论是这个问题仅限于视网膜设备。问题出在@2x 图像中。它们的分辨率为奇数(例如 59 像素 x 60 像素)。我所做的只是重新创建图像并将分辨率更改为 60 x 60 像素,我再也没有遇到过这个问题。
我对这个解决方案有点惊讶,因为我发现错误消息和代码行之间没有关联,但最终,是图像导致了这个问题。
【讨论】:
我的@2x 图像没有奇数分辨率,但偶尔仍会发生这种崩溃...【参考方案2】:我有一个similar problem,但我的崩溃是由UIImageView
中可调整大小的图像引起的。
我的可调整大小的图像具有顶部 = 30 像素、左侧 = 20 像素、底部 = 1 像素、右侧 = 10 像素的边缘插图。图像为 43x45,因此其可调整大小的区域为 13x14。我使用的是 iOS6,因此我能够通过将 UIImageResizingModeStretch
指定为 resizingMode
来解决此问题,以用于 -[UIImage resizableImageWithCapInsets:resizingMode:]
。
作品:
UIImage *image = [UIImage imageNamed:name];
UIImage *resizableImage = [image resizableImageWithCapInsets:edgeInsets resizingMode:UIImageResizingModeStretch];
EXC_BAD_ACCESS
或 [_UIImageViewPretiledImageCacheKey hash]: message sent to deallocated instance 0xb14deb0
和 NSZombieEnabled
崩溃:
UIImage *image = [UIImage imageNamed:name];
UIImage *resizableImage = [image resizableImageWithCapInsets:edgeInsets];
【讨论】:
【参考方案3】:下面的代码我得到了同样的结果
UIImage* image = [UIImage stretchableImageNamed:@"imageName"];
self.backgroundView = [[UIImageView alloc] initWithImage:image];
self.selectedBackgroundView = [[UIImageView alloc] initWithImage:image];
其中self
是UITableViewCell
而stretchableImageNamed:
很简单
+(UIImage*)stretchableImageNamed:(NSString*)name
UIImage *img = [UIImage imageNamed:name];
CGSize sz = img.size;
int left = (sz.width - 1.) / 2.;
int top = (sz.height - 1.) / 2.;
return [img resizableImageWithCapInsets:UIEdgeInsetsMake(top, left, top, left)];
这有帮助:
self.backgroundView = [[UIImageView alloc] initWithImage:[UIImage stretchableImageNamed:@"imageName"]];
self.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage stretchableImageNamed:@"imageName"]];
【讨论】:
以上是关于iOS UI 外观错误的主要内容,如果未能解决你的问题,请参考以下文章
iOS 使用UI控件的外观协议UIAppearance进行设置默认UI控件样式
调整窗口大小时,SwiftUI TextField 文本边界无法使用 GeometryReader 更新,导致外观错误
UIAppearance setTranslucent 错误:非法属性类型,c 为外观设置器,_installAppearanceSwizzleForSetter