如何将 UILabel 和 UIButton 项都放入 UITableView 标题部分的 UIView

Posted

技术标签:

【中文标题】如何将 UILabel 和 UIButton 项都放入 UITableView 标题部分的 UIView【英文标题】:How to have both UILabel and UIButton items into a UIView for UITableView header section 【发布时间】:2019-12-17 12:17:07 【问题描述】:

这是我在这里的第一篇文章,所以我希望一切都正确。 我正在尝试在 Objective-C 中编写代码,允许我在表头视图中为特定部分添加 UIButton。

它应该是这样的:

我正确地看到了标题,但不幸的是 UIButton 没有出现,我不知道为什么.. 几个月前我使用了类似的代码并且它有效,但是由于另一个错误而改变了一些东西表格视图,它停止工作,不幸的是我没有原始代码了.. 你知道我错在哪里或者你知道任何替代方案吗?

这是 Objective-C 中的代码(应该自动对齐标题和按钮,即使用户更改设备方向并且它应该适用于任何屏幕尺寸):

-(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
    if (section == 2) 
        UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0,0, 0,0)];
        [view setClipsToBounds:NO];
        [view setPreservesSuperviewLayoutMargins:TRUE];
        UILabel *textLabel = [[UILabel alloc] init];
        textLabel.text = @"MY TITLE";
        textLabel.textColor = [UIColor colorWithRed:0.427f green:0.427f blue:0.427f alpha:1.0f];
        //[textLabel setFont:_tableViewFooterFont];
        [textLabel setTextAlignment:4]; // Natural
        [textLabel setTranslatesAutoresizingMaskIntoConstraints:FALSE];
        [textLabel setAccessibilityTraits:UIAccessibilityTraitHeader];
        [view addSubview:textLabel];
        UIButton *button = [UIButton buttonWithType:1];
        //[button setHidden:FALSE];
        //[button.titleLabel setFont:_tableViewFooterFont];
        [button.titleLabel setTextColor:[UIColor redColor]];
        [button setTranslatesAutoresizingMaskIntoConstraints:FALSE];
        [button setTitle:@"RESET" forState:0];
        [button setContentCompressionResistancePriority:0 forAxis:UILayoutConstraintAxisHorizontal];
        [button addTarget:self action:@selector(resetAction:) forControlEvents:UIControlEventTouchUpInside];
        [view addSubview:button];
        NSDictionary *dictionary = NSDictionaryOfVariableBindings(textLabel, button);
        NSLayoutConstraint *buttonConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"|-[textLabel]->=0-[button]-|" options:0 metrics:NULL views:dictionary];
        [view addConstraints:buttonConstraint];
        NSLayoutConstraint *labelConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-12-[textLabel]-6-|" options:0 metrics:NULL views:dictionary];
        [view addConstraints:labelConstraint];
        NSLayoutConstraint *viewConstraint = [NSLayoutConstraint constraintWithItem:button attribute:10 relatedBy:0 toItem:textLabel attribute:10 multiplier:1.0 constant:0];
        [view addConstraint:viewConstraint];
        return view;
    
    return NULL;

【问题讨论】:

【参考方案1】:

试试这个:

-(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

    // create view for header
    UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 40)]; // set header view height as you want
    headerView.backgroundColor = [UIColor clearColor] ;

    // create label for header title
    UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, tableView.frame.size.width-130, 30)];
    title.font = [UIFont fontWithName:@"FONT_NAME" size:16.0];  //optional
    [title.heightAnchor constraintEqualToConstant:30].active = true;
    [title.widthAnchor constraintEqualToConstant:tableView.frame.size.width-130].active = true;

    // create button for header action
    UIButton *resetButton = [[UIButton alloc] initWithFrame:CGRectMake(self.yourTableView.frame.size.width-120, 0, 120, 30)];
    [resetButton setTitle:@"RESET" forState:UIControlStateNormal];
    //resetButton.backgroundColor = [UIColor redColor];
    [resetButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    [resetButton setFont:[UIFont fontWithName:@"FONT_NAME" size:16.0]] ;
    [resetButton.heightAnchor constraintEqualToConstant:30].active = true;
    [resetButton.widthAnchor constraintEqualToConstant:120].active = true;

    //Stack View
    UIStackView *stackView = [[UIStackView alloc] initWithFrame:headerView.frame];

    stackView.axis = UILayoutConstraintAxisHorizontal;
    stackView.distribution = UIStackViewDistributionFillProportionally;
    stackView.alignment = UIStackViewAlignmentCenter;
    stackView.spacing = 10;


    [stackView addArrangedSubview:title];
    [stackView addArrangedSubview:resetButton];

    stackView.translatesAutoresizingMaskIntoConstraints = false;
    [headerView addSubview:stackView];

    if(section == 2)
        title.text = @"MY TITLE";
        [resetButton addTarget:self action:@selector(resetBtnActn:) forControlEvents:UIControlEventTouchUpInside] ;

    else

        headerView.hidden = YES ;
        title.hidden = YES ;
        resetButton.hidden = YES ;
    

    //Trailing
    NSLayoutConstraint *trailing =[NSLayoutConstraint
                                    constraintWithItem:stackView
                                    attribute:NSLayoutAttributeTrailing
                                    relatedBy:NSLayoutRelationEqual
                                    toItem:headerView
                                    attribute:NSLayoutAttributeTrailing
                                    multiplier:1.0f
                                    constant:0.f];

    //Leading

    NSLayoutConstraint *leading = [NSLayoutConstraint
                                       constraintWithItem:stackView
                                       attribute:NSLayoutAttributeLeading
                                       relatedBy:NSLayoutRelationEqual
                                       toItem:headerView
                                       attribute:NSLayoutAttributeLeadingMargin
                                       multiplier:1.0f
                                       constant:0.f];

    //Bottom
    NSLayoutConstraint *bottom =[NSLayoutConstraint
                                     constraintWithItem:stackView
                                     attribute:NSLayoutAttributeBottom
                                     relatedBy:NSLayoutRelationEqual
                                     toItem:headerView
                                     attribute:NSLayoutAttributeBottom
                                     multiplier:1.0f
                                     constant:0.f];

    //Add constraints
    [headerView addConstraint:trailing];
    [headerView addConstraint:bottom];
    [headerView addConstraint:leading];

    // 5. Finally return
    return headerView;            



// table section button action
-(IBAction)resetBtnActn:(id)sender

    NSLog(@"button tapped");


如果您有任何问题,请发表评论。

【讨论】:

只发布代码不是回答的好方法,您应该在可以说明问题所在以及您的代码如何帮助解决此问题的地方添加一些描述:),您的答案也是对寻求相同解决方案的其他人有所帮助 感谢您的帮助!您的代码显示了 UIButton,但不幸的是,在更改设备方向后,它不再对齐。这就是我添加这些约束的原因之一。 @Ram2048 你能分享一下 ss 改变设备方向后到底出了什么问题 @Nick 当我打开该控制器时,它适用于纵向和横向模式,但如果我旋转显示器(在这种情况下从纵向到横向),结果是:imgur.com/a/WP86JOG 我想要避免每次设备改变方向时重新加载该标题,看到这是一种不好的做法.. @Nick 谢谢,但不幸的是它是一样的。我认为是因为视图是用tableView.frame.size.width创建的,当我旋转设备时宽度会发生变化,但视图是旧的宽度。

以上是关于如何将 UILabel 和 UIButton 项都放入 UITableView 标题部分的 UIView的主要内容,如果未能解决你的问题,请参考以下文章

如何将 UIButton 与右侧的 UILabel 对齐。喜欢 instagram 的评论

动态大小的 UILabel 直接跟在 UIButton 后面

使用自动布局将 UIButton 和 UILabel 居中

如何在 iPhone 应用程序中实现 UIButton / UILabel 'padding'

如何通过点击其他 UIButton 来移动 UILabel?

在 cellForRowAtIndexPath 中将 UIButton 视为 UILabel