为啥从自定义 UIView 向 UIButton 添加子视图不显示添加的子视图?

Posted

技术标签:

【中文标题】为啥从自定义 UIView 向 UIButton 添加子视图不显示添加的子视图?【英文标题】:Why adding a subView to UIButton, from a custom UIView doesn't show the added subViews?为什么从自定义 UIView 向 UIButton 添加子视图不显示添加的子视图? 【发布时间】:2013-07-23 12:09:40 【问题描述】:

我有一个 UIView 的子类,我是从一个 NIB 文件加载的。我的 NIB 文件,包含一个 UIButton 和一个 IBOutlet,称为 clock

@property (strong, nonatomic) IBOutlet UIButton *clock;

显示在我的界面构建器上的时钟按钮中设置的文本!但是我从 initWithCoder 添加的其他子视图没有。这是为什么呢?

.h 文件

@interface TWTimerView : UIView

@property (strong, nonatomic) IBOutlet UIButton *clock;

@property (strong, nonatomic) UIImageView *circle;
@property (strong, nonatomic) UIImageView *pointer;
@property (strong, nonatomic) UIImageView *tick;

@property (strong, nonatomic) UIImageView *circleGlow;
@property (strong, nonatomic) UIImageView *pointerGlow;
@property (strong, nonatomic) UIImageView *tickGlow;

@end

.m 文件

@implementation TWTimerView

-(id)initWithCoder:(NSCoder *)aDecoder 

    self = [super initWithCoder:aDecoder];
    if(self) 

        self.backgroundColor = [UIColor clearColor];

        _circle  = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"circle"]];
        _pointer = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"pointer"]];
        _tick    = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tick"]];

        [_clock addSubview:_circle];
        [_clock addSubview:_pointer];
        [_clock addSubview:_tick];

    
    return self;


- (id)initWithFrame:(CGRect)frame


    self = [super initWithFrame:frame];
    if (self) 
        // Initialization code
        TWTimerView *view= [[[NSBundle mainBundle] loadNibNamed:@"TimerView" owner:self options:nil] objectAtIndex:0];
        [self addSubview:view];

    
    return self;


@end

谢谢!

【问题讨论】:

你是在向 uibutton 添加图像视图吗??? 是的,我的 UIButton 是我的 _clock。我像这样添加它们:[_clock addSubview:_image]; 在调用initWithFrame 时,您实际上是在添加TWTimerView 作为TWTimerView 的子视图吗?还是 TimerView 只是一个带有某种内容子视图的常规 .xib 文件? 我不明白您为什么要分配两次视图...您确定调用了 initWithCoder 方法吗? 根据我的测试它不是,你真的需要使用initWithFrame方法还是我可以定义另一个方法来为你加载视图? 【参考方案1】:

这是我要做的: 如果您不需要使用框架,请删除initWithFrame 方法并使用其他方法来帮助您加载视图,就像这样。

+ (id)loadViewFromNIBFile 
    NSArray * array = [[NSBundle mainBundle] loadNibNamed:@"TimerView" owner:self options:nil];
    //You may want to assert array only contains one element here
    TWTimerView * view = (TWTimerView *)[array objectAtIndex:0];
    NSAssert([view isKindOfClass:TWTimerView.class], @"Unexpected class");
    [view _setDefaultComponents];
    return view;


- (void)_setDefaultComponents 
    self.backgroundColor = [UIColor clearColor];
    _circle  = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"circle"]];
    _pointer = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"pointer"]];
    _tick    = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tick"]];
    [_clock addSubview:_circle];
    [_clock addSubview:_pointer];
    [_clock addSubview:_tick];

致电[TWTimerView loadViewFromNIBFile] 获取您的视图实例。

【讨论】:

【参考方案2】:

您的 TWTimerView 有一个笔尖,其中您有一个 UIButton?而且你有一个 UIView-Subclass,就是给你的 UIButton 添加三个 UIImageViews,你为什么要这样做?!

为什么不继承 UIButton 并在那里设置 UIImageViews?

我会把它改成这样:

@implementation TWTimerView

    - (id)initWithFrame:(CGRect)frame
    

        self = [super initWithFrame:frame];
        if (self) 
            // Initialization code
            [[[NSBundle mainBundle] loadNibNamed:@"TimerView" owner:self options:nil] objectAtIndex:0];
            self.backgroundColor = [UIColor clearColor];

            _circle  = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"circle"]];
            _pointer = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"pointer"]];
            _tick    = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tick"]];

            [_clock addSubview:_circle];
            [_clock addSubview:_pointer];
            [_clock addSubview:_tick];

        
        return self;
    

@end

【讨论】:

TWTimerView 是 UIView 的子类。这个子类从一个 NIB 文件初始化。这个 nib 文件有一个 UIButton。我可以继承 UIButton 是的,但是,这应该可以工作。正如您所建议的,刚刚尝试在我的 UIButton 中从 initWithFrame 设置我的 UIImageViews。到目前为止没有运气。

以上是关于为啥从自定义 UIView 向 UIButton 添加子视图不显示添加的子视图?的主要内容,如果未能解决你的问题,请参考以下文章

如何从自定义 UIView 类调用函数?

UIView:从自定义 XIB 加载导致崩溃

无法从自定义 UIView 调用按钮的方法

将捏合手势从自定义 UIView 传递到父 UIScrollView

为啥 UIView 的这些自动布局约束会阻止 UIButton 子视图接收触摸事件?

从自定义 UIView 类设置视图宽度约束不更新帧