当视图即将显示在屏幕上时,UIViewController 上的 viewWillAppear 会被调用。是否有可能在 UIView 上获得类似的回调?
当视图即将显示在屏幕上时,UIViewController 上的 viewWillAppear 会被调用。是否有可能在 UIView 上获得类似的回调?
willMoveToSuperview:, didMoveToSuperview - 如有需要,请实现这些方法以跟踪当前视图在您的视图层次结构中的移动情况。
这将至少告诉您它何时被添加到视图层次结构中,但不能保证该视图层次结构已呈现/可见。
不行,但您可以从您的视图控制器将该通知转发到所需的视图。
我已经为此制作了一个宏解决方案,非常优雅和易于使用。
将以下内容添加到您的.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 切换设置方式,您可以使用其中一个或两个或全部!)
在您的.h文件中,在@end
下方添加以下内容(或者,如果要保持代码整洁,您可以将其添加到名为macros.h的文件中并导入它)
注意:如果您将此内容(或导入此内容)添加到多个互相导入或@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
willMove(toWindow:)
/didMoveToWindow()
更接近对应的方法,因为在这两个方法中你可以测试窗口是否为nil
来确定视图是否属于与屏幕连接的层次结构。如果你需要设置计时器来控制动画或类似的操作,那么这可能是你想要的。 - Jon Colverson