6

问题

我已经继承了UIView。在这个子类的一个对象被添加到它的父视图之后,它需要自主运行一些代码。我怎样才能连接到这个事件来运行我的代码?

为什么我需要它

众所周知, UISegmentedControl的选定分段的背景很难设置样式。我能找到的最好的解决方案是做这个黑客:

#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需要调用的地方是aSegmentedControlStyled被添加到它的superview之后。你可能会问,“为什么你在之后而不是在某个地方调用它init?”。好吧,根据我的观察,在它附加到视图层次结构之前调用它没有任何效果。因此,需要像这样编写他们的代码:

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

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

4

2 回答 2

13

覆盖任何一个

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

作为适当的?

于 2013-07-22T19:31:50.883 回答
0

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

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

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

于 2013-07-22T19:39:14.437 回答