UIView中存在哪些类似的功能方法(如viewWillAppear)?

35

当视图即将显示在屏幕上时,UIViewController 上的 viewWillAppear 会被调用。是否有可能在 UIView 上获得类似的回调?

3个回答

52
以下是来自UIView参考文档的内容:

willMoveToSuperview:, didMoveToSuperview - 如有需要,请实现这些方法以跟踪当前视图在您的视图层次结构中的移动情况。

这将至少告诉您它何时被添加到视图层次结构中,但不能保证该视图层次结构已呈现/可见。


10
我认为 willMove(toWindow:)/didMoveToWindow() 更接近对应的方法,因为在这两个方法中你可以测试窗口是否为 nil 来确定视图是否属于与屏幕连接的层次结构。如果你需要设置计时器来控制动画或类似的操作,那么这可能是你想要的。 - Jon Colverson
Jon是正确的。这也允许您在视图控制器转换之间检查视图何时出现,即使它没有在视图层次结构内移动。 - Lee Probert

10

不行,但您可以从您的视图控制器将该通知转发到所需的视图。


8
假设您拥有视图控制器。 - devios1
最终,每个视图都在一个viewController中,因此除非该视图具有私有访问权限,否则您可以在“viewWillAppear”中引用该视图并调用“view.MyOnViewWillAppearFunc()”。 - mfaani

-1
  • 注意,我最初打算在这里发布答案,但由于该问题是几年前提出的,我将那个标记为重复,并现在在这里回答。

宏解决方案

我已经为此制作了一个宏解决方案,非常优雅和易于使用。


.m

将以下内容添加到您的.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

在您的.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

为什么要使用基本上是if条件的宏?宏是不好的 - Sulthan
“宏不好”听起来很主观。我只是为了好玩而这样做;这是一种清晰表达发生情况的viewWillDisppear等效方法的整洁方式,而不是像“willMoveToWindow{if(!window){if(!superview){/stuff/}}}"那样不够清晰。 - Albert Renshaw

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