【问题标题】:Adding UIButton to UITableView section header将 UIButton 添加到 UITableView 部分标题
【发布时间】:2014-01-14 12:10:51
【问题描述】:

我有一个带有 1 个部分的 UITableView,对于部分标题,我想保持标题的所有内容相同,但只需在右侧添加一个按钮。我无法将按钮放在导航控制器中,因为放置此类按钮的两个可用位置已被其他按钮占用。

在这里你可以看到我尝试做的结果。现在我要做的就是在标题的右侧放置一个添加按钮,但我尝试过的没有奏效。我还在 StackOverflow 上尝试了其他一些解决方案,但它们并没有完全完成我想做的事情。此外,如果有更好的方法来创建添加按钮,请告诉我。我尝试使用UIBarButtonItem,但我不知道如何将其视图添加到实际视图中。谢谢!

这是我目前在我的代表中所拥有的:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UIButton *addButton = [[UIButton alloc] init]; //I also tried setting a frame for the
    button, but that did not seem to work, so I figured I would just leave it blank for posting       
    the question.
    addButton.titleLabel.text = @"+";
    addButton.backgroundColor = [UIColor redColor];
    [self.tableView.tableHeaderView insertSubview:addButton atIndex:0]; 
    //I feel like this is a bad idea

    return self.tableView.tableHeaderView;
}

- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 50;
}

【问题讨论】:

    标签: ios objective-c uitableview uiview uibutton


    【解决方案1】:

    斯威夫特 4:

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    
        let frame = tableView.frame
        let button = UIButton(frame: CGRect(x: 5, y: 10, width: 15, height: 15))
        button.tag = section
        button.setImage(UIImage(named: "remove_button"), for: UIControl.State.normal)
        button.addTarget(self,action:#selector(buttonClicked),for:.touchUpInside)
    
        let headerView = UIView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height))
        headerView.addSubview(button)
    
        return headerView
    }
    

    这个函数处理按钮点击:

    @objc func buttonClicked(sender:UIButton)
    {
        if(sender.tag == 1){
    
           //Do something for tag 1
        }
        print("buttonClicked")
    }
    

    【讨论】:

    • 仅供参考,我需要使用:let headerView = UITableViewHeaderFooterView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: 60))
    【解决方案2】:

    如果您想使用 Interface Builder 来构建您的部分标题,您可以使用 UITableViewCell 作为标题。在 UITableView 中为您的标题创建一个原型单元格,像对任何其他单元格一样进行自定义,包括添加标签、按钮和约束。

    你可以懒惰地在你的 UITableViewController 中实例化:

    lazy var headerCell: MyHeaderTableViewCell = {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Header") as! MyHeaderTableViewCell
        return cell
    }()
    

    使其成为标题:

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return headerCell
    }
    

    【讨论】:

      【解决方案3】:

      如果您对 Swift 解决方案感兴趣:

      override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
      
          let frame = tableView.frame
      
          let button = UIButton(frame: CGRectMake(5, 10, 15, 15))  // create button
          button.tag = section 
          // the button is image - set image
          button.setImage(UIImage(named: "remove_button"), forState: UIControlState.Normal)  // assumes there is an image named "remove_button"
          button.addTarget(self, action: #selector(TestController.remove(_:)), forControlEvents: .TouchUpInside)  // add selector called by clicking on the button
      
          let headerView = UIView(frame: CGRectMake(0, 0, frame.size.width, frame.size.height))  // create custom view
          headerView.addSubview(button)   // add the button to the view
      
          return headerView   
      }
      

      您可能想要指定节中标题的高度。这必须与自定义视图的高度同步:

      override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
          return CGFloat(30)
      }
      

      【讨论】:

        【解决方案4】:

        问题是你的self.tableView.tableHeaderView此时是nil,所以你不能使用它。所以你需要做的是,创建一个 UIView,为其添加标题和按钮,设置它们的样式,然后返回它。

        这应该为您的部分标题添加一个标题和按钮,您仍然需要使用正确的字体和大小设置标题的样式,但会给您一个想法。

        - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
            CGRect frame = tableView.frame;
        
            UIButton *addButton = [[UIButton alloc] initWithFrame:CGRectMake(frame.size.width-60, 10, 50, 30)];
            [addButton setTitle:@"+" forState:UIControlStateNormal];
            addButton.backgroundColor = [UIColor redColor];
        
            UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 100, 30)];
            title.text = @"Reminders";
        
            UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
            [headerView addSubview:title];
            [headerView addSubview:addButton];
        
            return headerView;
        }
        

        【讨论】:

        • 由于某种原因,此代码产生了正确的视图(图片),但按钮对触摸没有反应:(
        • @AlexSorokoletov - 请确保您的按钮不在其父框架之外。
        • 不是,触发了TouchUpInside/TouchDownInside事件,但是按钮上没有视觉动画
        • @AlexSorokoletov - 在这种情况下,您需要更改highlighted 和/或selected 状态的按钮样式。
        • 您能详细说明一下吗?我不确定我知道该怎么做,如果有任何帮助,我将不胜感激
        【解决方案5】:

        您有两个选择,都通过您的tableView.delegate。第一个涉及实现委托方法

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

        这使您基本上可以在自定义视图中返回您想要的任何内容,该视图将用作您所需部分的标题。这可能很简单

        - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
        {
            UIButton *addButton = [UIButton buttonWithType:UIButtonTypeContactAdd];
            [addButton addTarget:self action:@selector(SomeMethod:) forControlEvents:UIControlEventTouchUpInside];
            return addButton;
        }
        

        这会将圆形信息按钮(居中)作为您的标题。但您更有可能想要创建一个实际的 UIView 对象并使用您的按钮(和一个部分标题标签?)填充它,并按照您的喜好布置所有内容[请参阅其他人的答案以了解如何执行此操作]。

        但是,对于简单地向(其中一个)部分标题添加按钮的一般情况,第二种方法可能更好在多节表中类似]。这涉及到实现委托方法

        - (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
        

        并且基本上在事后将您的按钮添加到标题中;具体

        - (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
        {
            // Remove old button from re-used header
            if ([view.subviews.lastObject isKindOfClass:UIButton.class])
                [view.subviews.lastObject removeFromSuperview];
        
            if (section == MySectionNumberWithButton) {
                UIButton *addButton = [UIButton buttonWithType:UIButtonTypeContactAdd];
                [addButton addTarget:self action:@selector(SomeMethod:) forControlEvents:UIControlEventTouchUpInside];
                [view addSubview:addButton];
        
                // Place button on far right margin of header
                addButton.translatesAutoresizingMaskIntoConstraints = NO; // use autolayout constraints instead
                [addButton.trailingAnchor constraintEqualToAnchor:view.layoutMarginsGuide.trailingAnchor].active = YES;
                [addButton.bottomAnchor constraintEqualToAnchor:view.layoutMarginsGuide.bottomAnchor].active = YES;
            }
        }
        

        注意,因为 tableView 重复使用标题,所以在多节表中,您必须确保删除您之前可能添加的任何按钮,否则您最终会在不需要的部分中使用按钮。然后,如果这是正确的部分,则将按钮添加到现有标题中。注意,为了简洁起见,我使用NSLayoutAnchor(iOS 9+)来布局按钮;你可以对NSLayoutConstraint(iOS 6+)做同样的事情

        这种方法具有明显的优势 - 只需添加一个按钮 - 您不必重新创建常规布局以匹配所有其他(非按钮)标题,或者担心旋转设备时边距发生变化等。特别是,标题标题保持不变,并且将保留您可能为表格标题定义的任何全局外观设置(例如字体、颜色等),如果您采用了所有这些设置,您将不得不重新创建所有这些设置tableView:viewForHeaderInSection: 方法。

        【讨论】:

        • 很好的答案!以及对NSLayoutAnchor 的简洁而轻松的介绍,直到现在我一直避免这样做。建议添加addButton.centerYAnchor.constraint(equalTo: view.layoutMarginsGuide.centerYAnchor).isActive = true 作为替代!
        • 我喜欢这个答案。这正是我想要的。
        【解决方案6】:

        从iOS 6开始,也可以实现

        - (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
        

        在您的UITableViewDelegate 中。例如:

        - (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
            if (section == 0) {
                if ([view.subviews.lastObject isKindOfClass:[UIButton class]]) {
                    return;
                }
                UIButton *button = [UIButtonbuttonWithType:UIButtonTypeSystem];
                button.frame = CGRectMake(view.frame.size.width - 160.0, 0, 160.0, view.frame.size.height); // x,y,width,height
                [button setTitle:@"My Button" forState:UIControlStateNormal];
                [button addTarget:self action:@selector(sectionHeaderButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
                [view addSubview:button];
            }
        }
        

        【讨论】:

        • 你通过检查 lastObject 救了我的命
        【解决方案7】:

        您可以使用下面的代码来做到这一点,您可以将任何类型的视图放在标题视图中,但您必须为其指定框架。

        - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
        {
            UIView *view=[[UIView alloc]init];
            UIButton *addButton=[UIButton buttonWithType:UIButtonTypeContactAdd];
            addButton.frame=CGRectMake(250, 0, 100, 50);
            [view addSubview:addButton];
            [tblView.tableHeaderView insertSubview:view atIndex:0];
            //I feel like this is a bad idea
        
            return view;
        }
        

        【讨论】:

          猜你喜欢
          • 2015-02-18
          • 2023-03-06
          • 2012-03-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-01-31
          • 1970-01-01
          • 2015-11-26
          相关资源
          最近更新 更多