【发布时间】:2012-05-11 22:46:39
【问题描述】:
viewWillAppear 在视图即将显示在屏幕上时在 UIViewController 上调用。是否有可能在 UIView 上获得类似的回调?
【问题讨论】:
标签: ios objective-c uiview uikit viewwillappear
viewWillAppear 在视图即将显示在屏幕上时在 UIViewController 上调用。是否有可能在 UIView 上获得类似的回调?
【问题讨论】:
标签: ios objective-c uiview uikit viewwillappear
否,但您可以将该通知从您的视图控制器转发到所需的视图。
【讨论】:
viewWillAppear 中引用该视图并调用 view.MyOnViewWillAppearFunc()。
UIView 参考中的以下内容怎么样
willMoveToSuperview:, didMoveToSuperview - 根据需要实现这些方法以跟踪当前视图在视图层次结构中的移动。
这至少会告诉您何时将其添加到视图层次结构中,但不能保证视图层次结构已呈现/可见。
【讨论】:
willMove(toWindow:)/didMoveToWindow() 是稍微接近的类似物,因为在那些你可以测试窗口是否为nil 以查看视图是否是附加到一个层次结构的一部分屏幕。如果您要设置计时器来控制动画或类似的东西,这可能就是您想要的。
我为此制作了一个非常优雅且易于使用的宏解决方案。
将以下内容添加到您的 .m
-(void)viewDidLoad {
//normal stuff
}
__METHOD_MACRO_wasRemovedFromSuperview() {
//Code here will run whenever this view is removed from its superview
}
__METHOD_MACRO_wasAddedAsSubview() {
//Code here will run whenever this view is added as the subview of another view
}
是的!真的就是这么简单!
(由于下面如何设置宏的 ifdef 切换,您可以使用其中一个或两个或两者!)
将以下内容添加到@end 下的.h 中(或者,如果你想保持干净,你可以简单地添加到一个名为macros.h 的文件中并#import 它) p>
注意:如果你将这个(或导入这个)添加到多个相互导入或 @class 的文件中,你最终可能会弄乱#ifdef 逻辑并且这个宏可能会失败,我建议导入它从您需要的每个类的单独 .h 文件中,创建此宏更多的是作为概念证明而不是在生产代码中使用的东西
//Logic for __METHOD_MACRO_wasAddedAsSubview() and __METHOD_MACRO_wasRemovedFromSuperview()
#define startSuppressingWarnings() \
_Pragma("clang clang diagnostic push")\
_Pragma("clang diagnostic ignored \"-Weverything\"")
#define stopSuppressingWarnings() \
_Pragma("clang clang diagnostic pop")
#define __INTERNAL_METHOD_MACRO__didChangeSuperviewsSetup() \
-(void)didMoveToWindow {\
[super didMoveToWindow];\
if (self.window && self.superview) {\
startSuppressingWarnings()/*Hide potential undeclared selector warnings*/\
if ([self respondsToSelector:@selector(__wasAddedAsSubview)]) {\
[self performSelector:@selector(__wasAddedAsSubview)];\
}\
stopSuppressingWarnings()\
} else {\
startSuppressingWarnings()/*Hide potential undeclared selector warnings*/\
if ([self respondsToSelector:@selector(__wasRemovedFromSuperview)]) {\
[self performSelector:@selector(__wasRemovedFromSuperview)];\
}\
stopSuppressingWarnings()\
}\
}
#ifdef __INTERNAL_METHOD_MACRO__didChangeSuperviewsSetup_wasSetup
///Called when UIView was added as subview OR moved to another superview OR if another VC was presented
#define __METHOD_MACRO_wasAddedAsSubview() \
-(void)__wasAddedAsSubview/*{ //perform extra processes here }*/
#else
#define __INTERNAL_METHOD_MACRO__didChangeSuperviewsSetup_wasSetup 1
///Called when UIView was added as subview OR moved to another superview
#define __METHOD_MACRO_wasAddedAsSubview() \
__INTERNAL_METHOD_MACRO__didChangeSuperviewsSetup() \
-(void)__wasAddedAsSubview/*{ //perform extra processes here }*/
#endif
#ifdef __INTERNAL_METHOD_MACRO__didChangeSuperviewsSetup_wasSetup
///Called when UIView is removed as subview from superview or when its parent window is removed
#define __METHOD_MACRO_wasRemovedFromSuperview() \
-(void)__wasRemovedFromSuperview/*{ //perform extra processes here }*/
#else
#define __INTERNAL_METHOD_MACRO__didChangeSuperviewsSetup_wasSetup 1
///Called when UIView is removed as subview from superview
#define __METHOD_MACRO_wasRemovedFromSuperview() \
__INTERNAL_METHOD_MACRO__didChangeSuperviewsSetup() \
-(void)__wasRemovedFromSuperview/*{ //perform extra processes here }*/
#endif
【讨论】:
Macros are bad 听起来很主观。我这样做是为了好玩;这是一种清晰的 viewWillDisppear 等效方法,可以清楚地知道发生了什么,而不是 willMoveToWindow{if(!window){if(!superview){/*stuff*/}}},后者不那么清楚