Вопрос по uiview, iphone, objective-c, viewwillappear – Какой похожий функциональный метод (viewWillAppear) существует в UIView?

26

viewWillAppear вызывается в UIViewController, когда представление будет отображаться на экране. Можно ли получить подобный обратный вызов на UIView?

Ваш Ответ

3   ответа
46

UIView ссылка

willMoveToSuperview:, didMoveToSuperview - Implement these methods as needed to track the movement of the current view in your view hierarchy.

это, по крайней мере, сообщит вам, когда оно будет добавлено в иерархию представлений, но нет никакой гарантии, что иерархия представлений будет представлена / доступна для просмотра.

Я думаюwillMove(toWindow:)/didMoveToWindow() немного более близкие аналоги, потому что в тех, которые вы можете проверить, если окноnil чтобы увидеть, является ли представление частью иерархии, которая прикреплена к экрану. Это, вероятно, то, что вам нужно, если вы устанавливаете таймеры для управления анимацией или что-то в этом роде.
Джон прав. И это также позволяет вам проверить, когда представление появляется между переходами View Controller, даже если оно не перемещается в иерархии представления.
-1
Note, I was originally going to post this answer here but seeing as this was asked years prior I marked that one as a duplicate and will now answer here instead. Macro Solution

которое очень элегантно и легко в использовании.

.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
}

Ага! Это действительно так просто!

(Due to how the ifdef toggling of the macro is set-up below, you can use one or the other or both!)

.h

Добавьте следующее к вашему .h ниже@end (or, if you want to keep things clean, you can simply add to a file called macros.h and #import it)

Note: If you add this (or import this) to multiple files that also import each other or @class each other you can end up messing up the #ifdef logic and this macro could fail, I suggest importing it from a separate .h file for each class you need it in, this macro was created more as a proof of concept than something to be used in production code

//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? Макросыbad.
Macros are bad звучит субъективно. Я сделал это для удовольствия; это аккуратный способ иметь эквивалент viewWillDisppear, который ясно показывает, что произошло, в отличие отwillMoveToWindow{if(!window){if(!superview){/*stuff*/}}} что не так ясно
7

но вы можете переслать это уведомление желаемому представлению с вашего контроллера представления.

Это предполагает, что у вас есть контроллер для представления.

Похожие вопросы