简体   繁体   English

UIView如何在添加到超级视图时获得回调?

[英]How can a UIView get a callback when it is added to its superview?

Problem 问题

I have subclassed a UIView . 我已经将UIView子类化了。 After an object of this subclass is added to its superview, it needs to autonomously run some code. 将此子类的对象添加到其superview后,它需要自动运行一些代码。 How can I hook on to this event to run my code? 如何挂钩此事件以运行我的代码?

Why I Need It 为什么我需要它

The background of the selected segmented of a UISegmentedControl has been notoriously hard to style. UISegmentedControl的所选分段的背景众所周知难以设计。 The best solution I could find is doing this hack: 我能找到的最好的解决方案是做这个黑客:

#import "SegmentedControlStyled.h"

@implementation SegmentedControlStyled

- (void) updateStyle
{
    for (NSUInteger i = 0; i < [self.subviews count]; i++) {
        if ([[self.subviews objectAtIndex:i] respondsToSelector:@selector(isSelected)] && [[self.subviews objectAtIndex:i] isSelected]) {
            [[self.subviews objectAtIndex:i] setTintColor:[UIColor colorWithWhite:0.7 alpha:1.0]];
        }
        if ([[self.subviews objectAtIndex:i] respondsToSelector:@selector(isSelected)] && ![[self.subviews objectAtIndex:i] isSelected]) {
            [[self.subviews objectAtIndex:i] setTintColor:[UIColor colorWithWhite:0.9 alpha:1.0]];
        }
    }
}

@end

This updateStyle function needs to be called in two places. 需要在两个地方调用此updateStyle函数。 Obviously, the first is whenever the a user taps a different segment. 显然,第一个是用户点击不同的段时。 I can do this autonomously by overriding my SegmentedControlStyled 's addTarget function and hooking on to the UIControlEventValueChanged event. 我可以通过覆盖我的SegmentedControlStyledaddTarget函数并挂钩到UIControlEventValueChanged事件来自动执行此操作。 The second place updateStyle needs to be called is after a SegmentedControlStyled is added to its superview. SegmentedControlStyled添加到其superview 之后 ,需要调用第二个地方updateStyle You may ask, "why do you call it after and not somewhere like init ?". 您可能会问,“为什么要在之后调用它而不是像init那样的地方?”。 Well, from my observations, calling it before it is attached to the view hiearchy has no effect. 好吧,从我的观察来看,在它被附加到视图之前调用它是没有效果的。 Therefore, one needs to write their code like this: 因此,需要像这样编写代码:

SegmentedControlStyled* seg = [[SegmentedControlStyled alloc] initWithItems:[NSArray arrayWithObjects:@"One", @"Two", nil]];
[self.view addSubview:seg];
[seg updateStyle];

The last line is ugly, because the co-worker who uses my subclass has to understand why the view is broken and has to know when to call updateStyle . 最后一行是丑陋的,因为使用我的子类的同事必须理解为什么视图被破坏并且必须知道何时调用updateStyle To uphold the Object Oriented principle of encapsulation , this detail should be moved into the class itself. 为了坚持面向对象的封装原则,这个细节应该移到类本身。 If I had the ability to detect when a view has been added to its superview, I would be able to encapsulate the style hack within my subclass. 如果我能够检测何时将视图添加到其superview中,我将能够将样式hack封装在我的子类中。

override either of 覆盖任何一个

- (void)didAddSubview:(UIView *)subview
- (void)willMoveToSuperview:(UIView *)newSuperview
- (void)willMoveToWindow:(UIWindow *)newWindow

as appropriate? 作为适当的?

UISegmentedControl's selected state isn't hard to style. UISegmentedControl的选定状态并不难。

You use the method setBackgroundImage:forState:barMetrics: and use UIControlStateSelected as the argument for named parameter forState: . 您使用方法setBackgroundImage:forState:barMetrics:并使用UIControlStateSelected作为命名参数forState:参数forState:

Anything where you are accessing subviews of UIKit controls is a bad thing™. 您访问UIKit控件子视图的任何内容都是件坏事。 You shouldn't rely on internal implementation details. 您不应该依赖内部实现细节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM