UIButton 未显示在自定义 UIView 中

Posted

技术标签:

【中文标题】UIButton 未显示在自定义 UIView 中【英文标题】:UIButton does not show up in custom UIView 【发布时间】:2015-02-20 15:08:30 【问题描述】:

我正在努力解决这个问题,但无法弄清楚问题所在。

我有一个自定义 UIView:FKPoiMiniDetail,这是实现 (FKPoiMiniDetail.m)

const static CGFloat kDialogLateralMargin   = 15.0;
const static CGFloat kDialogHeight          = 100.0;
const static CGFloat kDialogBottomMargin    = 10.0;
const static CGFloat kBottomButtonHeight    = 50.0;

@interface FKPoiMiniDetail ()
@property (nonatomic) float tabBarHeight;
@property (nonatomic) NSUInteger numberOfButtons;
@property (nonatomic) NSMutableArray *buttonBlocks;
@property (strong, nonatomic) PoI* myPoi;

@end
@implementation FKPoiMiniDetail

- (id) initWithTabBarHeight:(float)aTabBarHeight numberOfButtons:(NSUInteger)numButtons andPoi:(PoI*)aPoi
    if (self = [super init]) 
        self.tabBarHeight = aTabBarHeight;
        self.numberOfButtons = numButtons;
        self.myPoi = aPoi;
        self.buttonBlocks = [[NSMutableArray alloc] init];
        [self configure];
    
    return self;

在这里我以编程方式添加按钮:

- (void) assignButton:(NSUInteger)index anImage:(UIImage*)image aText:(NSString*)text andCallback:(void(^)())cb
    if (index > self.numberOfButtons) 
        ALog("ERROR: Index is greater than number of buttons");
        return;
    
    [self.buttonBlocks addObject:cb];

    int imWidth = 20;
    int imHeight = 20;
    int imLabelSpacing = 8;
    CGSize labelSize = [text sizeWithAttributes:@NSFontAttributeName: [UIFont systemFontOfSize:17.0f]];
    CGFloat overallWidth = labelSize.width + imWidth + imLabelSpacing;

    CGFloat test = self.bounds.size.width;
    CGFloat buttonWidth = test / ((CGFloat) self.numberOfButtons);

    int x = index * buttonWidth;

    int y = self.frame.size.height - kBottomButtonHeight;

    UIButton *buttonContainer = [[UIButton alloc] initWithFrame:CGRectMake(x,y,buttonWidth,kBottomButtonHeight)];
    [buttonContainer addTarget:self action:@selector(buttonTouched:) forControlEvents:UIControlEventTouchUpInside];
    buttonContainer.tag = index;


    int firstImOrigin = x + (buttonWidth - overallWidth) / 2;
    UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(firstImOrigin, (kBottomButtonHeight - imHeight)/2, imWidth, imHeight)];
    [iv setImage:image];
    [buttonContainer addSubview:iv];


    CGRect lR = CGRectMake(firstImOrigin + imWidth + imLabelSpacing, (kBottomButtonHeight - labelSize.height)/2, labelSize.width, labelSize.height);

    UILabel *label = [[UILabel alloc] initWithFrame:lR];
    label.text = text;

    [buttonContainer addSubview:label];
    [self addSubview:buttonContainer];

这是作为 UIButton 目标的选择器:

- (void)buttonTouched:(UIButton*)b
    void (^ myblock)() = [self.buttonBlocks objectAtIndex:b.tag];
    myblock();

我在其他地方创建此对象并分配如下按钮:

FKPoiMiniDetail *md = [[FKPoiMiniDetail alloc] initWithTabBarHeight:self.tabBarController.tabBar.frame.size.height
                                                            numberOfButtons:2
                                                                     andPoi:annotation.aPoI];
UIImage *im = [UIImage imageNamed:@"detail.png"];
[md assignButton:0 anImage:im aText:@"Dettagli" andCallback:^
     ALog("Button 0 pressed");
];

[md assignButton:1 anImage:im aText:@"Naviga" andCallback:^
     ALog("Button 1 pressed");
];
[self.mapView addSubview:md];

第二个按钮是空的,但奇怪的是:在按钮内部点击回调确实会执行......

调试似乎没用: 第一个按钮的变量:

以及第二个按钮的变量:

任何帮助表示赞赏,在此先感谢!

【问题讨论】:

更新了调试截图 您正在使用x 在buttonContainer 内设置子视图的框架,而它似乎是真实使用的(如定义的那样)与您的FKPoiMiniDetail 的整个宽度。换句话说,如果我理解正确,buttonContainer 的第二个按钮应该是 origin.x 145,但里面的内容应该与第一个按钮的相同(firtImOrigin = 29),等等。 是的,也许我被融合了 谢谢!!!我花了 20 分钟写这个问题,花了 2 个小时来解决这个问题。今天应该辞职 【参考方案1】:

“分解”你的FKPoiMiniDetail

FKPoiMiniDetail

查看 buttonContainer1 - buttonContainer2 — buttonContainer3 等

所以 buttonContainer 中的内容应该始终具有相同的“框架”,而 buttonContainer frame 根据按钮的数量而变化,因为 buttonContainer 将是它们的超级视图。

所以你声明:

int x = index * buttonWidth;
int y = self.frame.size.height - kBottomButtonHeight;

这将有助于设置buttonContainer frame

但是labeliv 不应该依赖于它们,只依赖于[buttonContainer frame] 的高度和宽度,因为它们似乎是居中的。

我猜从你的代码,如果你在最后[self addSubview:iv][self addSubview:label]; 你可能会看到它们。

【讨论】:

简洁的答案,这就是问题所在:)【参考方案2】:

我过去在UIImageView 上设置图像时遇到问题,我的解决方案是将顺序更改为:

[buttonContainer addSubview:iv]; [iv setImage:image];

首先添加他的子视图,然后设置图像。

【讨论】:

谢谢,但问题是框架边界存在错误,请参阅我的问题中 Larme 的评论。

以上是关于UIButton 未显示在自定义 UIView 中的主要内容,如果未能解决你的问题,请参考以下文章

在自定义 UIView 上为 UIButton 设置动画

自定义视图中未调用 UIButton 操作

按钮未在自定义 UIButton 中注册触摸

UIButton 在自定义 UITableviewCell 中没有响应

Swift:在自定义视图中未调用 UIButton 触摸事件

UIButton 未使用 Swift 在 UIView 中显示