- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
使用 UIAppearance 代理设置 UIBarButtonItem 子类的自定义属性会导致“无法识别的选择器”异常,因为 setter 可能由 UIAppearance 转发到 UINavigationButton,而不是栏按钮本身。
我正在使用 iOS 7 Beta 5 SDK 和 Xcode 5 DP5。但是,请不要告诉我它处于 NDA 之下,因为我不会在这个问题中讨论任何新功能或新类。我通知你我的 SDK,因为可以查出它只是 beta 软件中的一个错误。
我子类化了一个 UIBarButtonItem
并在头文件中创建了一个自定义属性:
@property (nonatomic, strong) NSString *mySubclassedProperty UI_APPEARANCE_SELECTOR;
我的 setter 和 getter 看起来像这样:
- (void)setMySubclassedProperty:(NSString *)mySubclassedProperty {
_mySubclassedProperty = mySubclassedProperty;
NSLog(@"%p %s %@", self, __PRETTY_FUNCTION__, mySubclassedProperty);
}
没什么特别的吧?但它根本不适用于 UIAppearance
。当我尝试在我的应用程序的委托(delegate)中设置默认外观时,它没有给我任何错误,也没有任何警告。
[[AKBarButtonItem appearance] setMySubclassedProperty:@"GLOBALLY ASSIGNED"];
它看起来像一个魅力,除了当我尝试将 AKBarButtonItem
的实例设置为 self.navigationItem.rightBarButtonItem
时它崩溃的事实:
self.navigationItem.rightBarButtonItem = [[AKBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:nil action:nil];
回溯看起来像这样:
2013-08-13 14:30:08.551 UIBarButtonItem Subclass Demo[1512:a0b] -[UINavigationButton setMySubclassedProperty:]: unrecognized selector sent to instance 0x8c42710
2013-08-13 14:30:08.556 UIBarButtonItem Subclass Demo[1512:a0b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationButton setMySubclassedProperty:]: unrecognized selector sent to instance 0x8c42710'
*** First throw call stack:
(
0 CoreFoundation 0x0173b6f4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x014bb8b6 objc_exception_throw + 44
2 CoreFoundation 0x017d8983 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x0172ba1b ___forwarding___ + 1019
4 CoreFoundation 0x0172b5fe _CF_forwarding_prep_0 + 14
5 CoreFoundation 0x0172fe2d __invoking___ + 29
6 CoreFoundation 0x0172fd3a -[NSInvocation invoke] + 362
7 CoreFoundation 0x0172feba -[NSInvocation invokeWithTarget:] + 74
8 UIKit 0x00763255 workaround10030904InvokeWithTarget + 824
9 UIKit 0x0075dea8 +[_UIAppearance _applyInvocationsTo:window:matchingSelector:] + 4497
10 UIKit 0x0075e299 +[_UIAppearance _applyInvocationsTo:window:] + 55
11 UIKit 0x0029ddcb -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 183
12 libobjc.A.dylib 0x014cd81f -[NSObject performSelector:withObject:] + 70
13 QuartzCore 0x03ac172a -[CALayer layoutSublayers] + 148
14 QuartzCore 0x03ab5514 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
15 QuartzCore 0x03ac3b55 -[CALayer(CALayerPrivate) layoutBelowIfNeeded] + 43
16 UIKit 0x00290886 -[UIView(Hierarchy) layoutBelowIfNeeded] + 595
17 UIKit 0x0029062d -[UIView(Hierarchy) layoutIfNeeded] + 74
18 UIKit 0x0050841e -[UIBarButtonItem(UIStatic) _leftRightImagePaddingForEdgeMarginInNavBarIsMini:] + 574
19 UIKit 0x002ea325 -[UINavigationBar _getTitleViewFrame:leftViewFrames:rightViewFrames:forItemAtIndex:returnedIdealWidthOfTextContent:availableLayoutWidthForTextContent:idealBackButtonWidth:] + 3522
20 UIKit 0x002ef2da -[UINavigationBar _getTitleViewFrame:leftViewFrames:rightViewFrames:forItemAtIndex:] + 591
21 UIKit 0x002ef59a -[UINavigationBar _getTitleViewFrame:leftViewFrames:rightViewFrames:] + 151
22 UIKit 0x002dc515 -[UINavigationBar _setLeftViews:rightViews:] + 1894
23 UIKit 0x002ca6c5 -[UINavigationItem updateNavigationBarButtonsAnimated:] + 188
24 UIKit 0x002cab63 -[UINavigationItem setObject:forLeftRightKeyPath:animated:] + 547
25 UIKit 0x002cb1ae -[UINavigationItem setRightBarButtonItem:animated:] + 171
26 UIKit 0x002cb0fe -[UINavigationItem setRightBarButtonItem:] + 48
27 UIBarButtonItem Subclass Demo 0x0000665e -[AKViewController viewDidLoad] + 222
28 UIKit 0x00345c18 -[UIViewController loadViewIfRequired] + 696
29 UIKit 0x00345eb4 -[UIViewController view] + 35
30 UIKit 0x00370369 -[UINavigationController rotatingSnapshotViewForWindow:] + 52
31 UIKit 0x00698e10 -[UIClientRotationContext initWithClient:toOrientation:duration:andWindow:] + 420
32 UIKit 0x00276ff2 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 1495
33 UIKit 0x00276a16 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 82
34 UIKit 0x002768e8 -[UIWindow _setRotatableViewOrientation:updateStatusBar:duration:force:] + 117
35 UIKit 0x00276970 -[UIWindow _setRotatableViewOrientation:duration:force:] + 67
36 UIKit 0x00275a0a __57-[UIWindow _updateToInterfaceOrientation:duration:force:]_block_invoke + 120
37 UIKit 0x0027596c -[UIWindow _updateToInterfaceOrientation:duration:force:] + 400
38 UIKit 0x002766c3 -[UIWindow setAutorotates:forceUpdateInterfaceOrientation:] + 870
39 UIKit 0x00279c7e -[UIWindow setDelegate:] + 449
40 UIKit 0x0034a037 -[UIViewController _tryBecomeRootViewControllerInWindow:] + 180
41 UIKit 0x0026f91c -[UIWindow addRootViewControllerViewIfPossible] + 609
42 UIKit 0x00270146 -[UIWindow setRootViewController:] + 960
43 UIBarButtonItem Subclass Demo 0x00006a07 -[AKAppDelegate application:didFinishLaunchingWithOptions:] + 823
44 UIKit 0x0022d525 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 309
45 UIKit 0x0022dd65 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1536
46 UIKit 0x00232578 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
47 UIKit 0x0024657c -[UIApplication handleEvent:withNewEvent:] + 3447
48 UIKit 0x00246ae9 -[UIApplication sendEvent:] + 85
49 UIKit 0x002341f5 _UIApplicationHandleEvent + 736
50 GraphicsServices 0x0365a33b _PurpleEventCallback + 776
51 GraphicsServices 0x03659e46 PurpleEventCallback + 46
52 CoreFoundation 0x016b6e95 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
53 CoreFoundation 0x016b6bcb __CFRunLoopDoSource1 + 523
54 CoreFoundation 0x016e18ac __CFRunLoopRun + 2156
55 CoreFoundation 0x016e0bf3 CFRunLoopRunSpecific + 467
56 CoreFoundation 0x016e0a0b CFRunLoopRunInMode + 123
57 UIKit 0x00231cad -[UIApplication _run] + 840
58 UIKit 0x00233f0b UIApplicationMain + 1225
59 UIBarButtonItem Subclass Demo 0x00006e9d main + 141
60 libdyld.dylib 0x01d77725 start + 0
)
libc++abi.dylib: terminating with uncaught exception of type NSException
经过一些检查,我奇怪地意识到 setMySubclassedProperty:
消息被发送到 UINavigationButton
(它是导航中使用的 UIButton
的私有(private)子类栏、工具栏和搜索栏)。我在 26
帧中设置按钮,UIAppearance
魔法在 10
帧中执行。
在 iOS 6 中,问题存在,但向 UINavigationButton
发送了一条不同的消息:
2013-08-13 14:35:58.316 UIBarButtonItem Subclass Demo[1591:c07] -[UINavigationButton _UIAppearance_setMySubclassedProperty:]: unrecognized selector sent to instance 0x810d600
2013-08-13 14:35:58.359 UIBarButtonItem Subclass Demo[1591:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationButton _UIAppearance_setMySubclassedProperty:]: unrecognized selector sent to instance 0x810d600'
*** First throw call stack:
(0x12b2012 0x10d7e7e 0x133d4bd 0x12a1bbc 0x12a194e 0x12a61bd 0x12a60d6 0x12a624a 0x68b9e8 0x68769c 0x687a95 0x291884 0x3088ca 0x28cf96 0x2934a4 0x28b89d 0x2cc646 0x2bc076 0x2bc517 0x2bcb66 0x2bcab6 0x665e 0x3261c7 0x326232 0x3264da 0x33d8e5 0x33d9cb 0x33dc76 0x33dd71 0x33e89b 0x33e9b9 0x33ea45 0x44420b 0x2952dd 0x10eb6b0 0x289dfc0 0x289233c 0x289deaf 0x3342bd 0x27cb56 0x27b66f 0x27b589 0x27a7e4 0x27a61e 0x27b3d9 0x27e2d2 0x32899c 0x275574 0x275cc1 0x6a07 0x242157 0x242747 0x24394b 0x254cb5 0x255beb 0x247698 0x24b8df9 0x24b8ad0 0x1227bf5 0x1227962 0x1258bb6 0x1257f44 0x1257e1b 0x24317a 0x244ffc 0x6e9d 0x1ab0725)
libc++abi.dylib: terminate called throwing an exception
我的第一个想法是:“UIAppearance 将 setter 转发给 AKBarButtonItem,然后它崩溃了”。但是是吗?在 an article by Peter Steinberger我发现 Apple 正在使用 _UIAppearance
的一个特殊子类用于栏目,称为 _UIBarItemAppearance
。我想确认这一点并在 -[_UIBarItemAppearance forwardInvocation:]
上设置一个符号断点,并且 lldb 在异常发生之前成功停止。
现在在我看来,Apple 在 -[_UIBarItemAppearance forwardInvocation:]
中做了一些肮脏的逻辑,以实现应该将哪个选择器发送到哪个实例,例如:
setBackgroundImage:forState:
应该发送到 UINavigationButton
setBackButtonBackgroundImage:forState:barMetrics:
到 UIBarButtonItem
他们的代码是这样的:
if (selector == @selector(setBackButtonBackgroundImage:forState:barMetrics:)) {
// forward to UIBarButtonItem
} else if (selector == @selector(setBackButtonBackgroundVerticalPositionAdjustment:forBarMetrics:)) {
// forward to UIBarButtonItem
} else if (...) {
// more forwarding to UIBarButtonItem
} else {
// forward to UINavigationButton
}
然后,根据我的推论,最后的 else
语句导致 setNiceBarButtonItemAttributes:
选择器被发送到 UINavigationButton
,而不是 UIBarButtonItem
。如果这是真的,我们就完蛋了。
您可以在此处下载示例项目:http://cl.ly/241I2A3U0a0y .
我只是做错了什么,还是一个错误?或者苹果是故意的?任何帮助将不胜感激。
最佳答案
问题是 UIBarButtonItem
不是 UIView
的子类,它是创建私有(private) UIView 子类的“ Controller ”类。对于条形按钮项目,使用了一个私有(private)外观代理,而不是通常的代理(一些信息 here )。
我可以建议走另一条路吗?您真的需要为您的定制子类化条形按钮项目吗?您不能创建 UINavigationBar
的子类并将其用作您对 appearanceWhenContainedIn:
进行更改的触发器吗?
关于iphone - 将 UIAppearance 与 UIBarButtonItem 的子类一起使用会导致无法识别的选择器被发送到 UINavigationButton,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18204389/
我想要的是能够在输入获得焦点或失去焦点时执行某些操作(两个事件)。 我尝试了以下方法,但这按事件单独工作(单独编码时):仅在焦点上,或仅在失去焦点时。 另外,我希望它尽可能跨平台(包括触摸设备),这是
我分别研究了TableView的Filtering和Pagination。 过滤: this帖子帮助我满足了我的需要 分页: this , this帖子也帮助了我 我想像这样将它们组合在一起: 详情-
我是 TDD 方法的新手,所以我想知道是否有人经历过这种机智可以启发我一点。我想获得一些关于如何一起使用 UML 和 TDD 方法的线索。 我已经习惯了:用 UML 设计 --> 生成骨架类(然后保持
我尝试使用入口点和 cmd 设置 Docker。 FROM debian:stretch RUN apt-get update && \ apt install gnupg ca-certificat
我想要一个 Class 对象,但我想强制它所代表的任何类扩展类 A 并实现接口(interface) B。 我能做到: Class 或者: Class 但我不能两者兼得。有办法做到这一点吗? 最佳答案
我是 Rubymine 的长期用户。 Rubymine 非常适合基于 html 的 Rails 应用程序,但我现在正在做更多的 SPA 客户端工作(例如 javascript/react)。我发现我真
我注意到我使用的某个脚本依赖于原型(prototype)。 (Lightbox 2) 它会与 jQuery 在同一页面上一起工作吗?有没有办法确保它们不冲突? 最佳答案 可以,但你需要采取 speci
我需要对表中显示的数据进行分页并通过 ajax 调用获取它 - 这是我通过使用具有以下配置的 dataTables 插件来完成的 - bServerSide : true; sAjaxSource :
我是 gtk 新手,所以想知道在 C 语言中归档和 gtk 是否可以一起使用?例如,我可以从 .txt 文件中读取,然后在相同的代码中使用 gtk 在标签或其他内容中显示它吗?如果是,怎么办? 谢谢!
有没有人设法得到Bck2Brwsr最近与 Java 8/JavaFX 8 一起工作?有没有兼容的机会?我找不到太多关于它的信息,也没有一个好的起点。使用给定的 Maven archetype我遇到了几
在我的应用程序中,用户通过 openid(与 stackoverflow 相同)登录/注销。 我想通过 oauth 向第三方应用程序开放我的应用程序。 如何创建我的 openid-consumer 应
我在启动和运行 Hibernate 和 Spring 时遇到一些问题。我有一个网络服务器项目,它使用了其他几个具有持久实体的项目。我遇到的问题是,对于存储在 WEB-INF/libs 内的另一个 ja
我有 @ControllerAdvice 类,它处理一组异常。我们还有一些其他异常,这些异常用 @ResponseStatus 注释进行注释。为了结合这两种方法,我们使用博客文章中描述的技术:http
我想在屏幕上使用进度条而不是 progressDialog。 我在我的 XML View 文件中插入了一个进度条,我想让它在加载时显示并在不加载时禁用它。 所以我使用的是可见的,但它发生了,所以其余的
CREATE TABLE `users` ( `id` int(11) AUTO_INCREMENT, `academicdegree` varchar(255),
IN() 中使用的查询返回:1, 2。然而,整个查询返回 0 行,这是不可能的,因为它们存在。我在这里做错了什么? SELECT DISTINCT li.auto_id FROM links
亲们, 我如何在使用 Jade 生成的表单上实现 jQuery 样式?我想做的是美化 表单并使它们可点击。我在 UI 方面很糟糕。期间。 我如何在表单上实现这个可选择的方法? http://jquer
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我可以: auto o1 = new Content; 但不能: std::shared_ptr o1(new Content); std::unique_ptr o1(new Content); 我
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 4 年前。 Improve this qu
我是一名优秀的程序员,十分优秀!