【问题标题】:How can a UIView get a callback when it is added to its superview?UIView 添加到其父视图时如何获得回调?
【发布时间】:2013-07-21 16:11:55
【问题描述】:

问题

我对@9​​87654321@ 进行了子类化。在这个子类的一个对象被添加到它的父视图之后,它需要自主运行一些代码。如何连接到这个事件来运行我的代码?

我为什么需要它

UISegmentedControl 的选定分段的背景是出了名的难以设置样式。我能找到的最佳解决方案是做这个 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

这个updateStyle 函数需要在两个地方调用。显然,第一个是每当用户点击不同的段时。我可以通过覆盖我的SegmentedControlStyledaddTarget 函数并连接到UIControlEventValueChanged 事件来自主执行此操作。第二个需要调用updateStyle 的地方是一个SegmentedControlStyled 被添加到它的superview 之后。你可能会问,“为什么你在之后调用它而不是像 init 这样的地方?”。好吧,根据我的观察,在它附加到视图层次结构之前调用它没有任何效果。因此,需要像这样编写他们的代码:

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

最后一行是丑陋的,因为使用我的子类的同事必须理解为什么视图被破坏并且必须知道何时调用updateStyle。为了坚持encapsulation 的面向对象原则,这个细节应该移到类本身中。如果我能够检测何时将视图添加到其父视图中,我将能够将样式 hack 封装在我的子类中。

【问题讨论】:

    标签: iphone ios cocoa-touch uiview uisegmentedcontrol


    【解决方案1】:

    UISegmentedControl 的选中状态不难设置样式。

    您使用方法setBackgroundImage:forState:barMetrics: 并使用UIControlStateSelected 作为命名参数forState: 的参数。

    任何访问 UIKit 控件子视图的地方都是坏事™。您不应依赖内部实现细节。

    【讨论】:

    • 如何将其设置为 UIColor 而不是 UIImage?
    【解决方案2】:

    覆盖其中一个

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

    合适吗?

    【讨论】:

    • 我最终使用了willMoveToSuperview。在那个函数里面,我做了[self performSelector:@selector(updateStyle) withObject:nil afterDelay:0];。立即调用它无法重新设置分段控件的样式。
    • 即使改用- (void)didMoveToSuperview? (即育儿完成后,请注意)
    猜你喜欢
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 1970-01-01
    相关资源
    最近更新 更多