【问题标题】:Custom UITableViewCell with drop-down in SwiftSwift 中带有下拉菜单的自定义 UITableViewCell
【发布时间】:2016-04-05 22:19:56
【问题描述】:

我想用 XIB 实现自定义 UITableViewCellHere 是图纸。 主视图右侧的按钮显示/隐藏附加视图。我有两个问题:

  1. 如何隐藏附加视图?我认为一种可能性是将附加 UIView 框架中的高度设置为零。有没有更好的选择?

  2. 附加视图(在本例中为 1-5)中的按钮应动态显示。有两组数据:一组用于左侧(按钮 1-3),另一组用于右侧(按钮 4-5)。左侧按钮的高度是固定的,比如说每个 70px。应调整右侧按钮的高度,使右侧按钮的总高度与左侧的总高度相同。考虑到这些规则,如何动态添加按钮?

按钮将在运行时添加。例如有两个数组:

var leftButtons:[String] = ["button1label", “button2label“, "button3label"]

var rightButtons:[String] = ["button4label", "button5label"]

假设我稍后在运行时"button6label" 添加到leftButtons。应该调整leftView/rightView 的大小以及这些视图内按钮的大小。同样,左侧尺寸上每个按钮的高度是固定的。

【问题讨论】:

    标签: ios swift uitableview cocoa xib


    【解决方案1】:

    首先你应该在你的自定义 UITableViewCell 上添加ContainerView 视图,现在在ContainerView - leading , trailing, top & bottom to superView 上添加约束,priority 999 用于所有约束`。

    现在您应该在ContainerView 上添加两个视图,一个是mainView,另一个是additionView

    并在mainView 上添加约束 - 导致 superView、top 到 superView、尾随到 superView 和高度约束(比如说 70)。

    现在在 mainView 中添加 textfieldshow/hide button 并对 textFieldshow/hide button 应用约束。

    文本字段约束 - leading to superViewtop to superViewbottom to superViewHorizontal spacing between textField & show/hide button

    显示/隐藏按钮约束 - top to superViewbottom to superViewtrailing to superView 和宽度约束。

    这里mainView 配置正确。所以现在让我们配置additionView

    您应该在additionView 中添加两个新视图,一个是leftView,另一个是rightViewadd constraintsleftView & rightView 上。

    leftView 约束 - leading to superViewtop to superViewbottom to superViewHorizontal spacing between leftView & rightViewequal width and width constraints of leftView to rightView.

    rightView 约束 - trailing to superView, top to superView&bottom to superView 这里是你的Interface Builder Designing completed,所以现在我们需要在运行时管理左右视图上的按钮。为此,您必须创建一个名为 VerticalContainerView 的自定义类,它将管理按钮的垂直分布。

    我使用 KVConstraintExtensionsMaster 库创建了 VerticalContainerView 以应用我已实现的约束。

    将下面的代码放在VerticalContainerView.h头文件中

    #import <UIKit/UIKit.h>
    
    @interface VerticalContainerView : UIView
    -(void)configureButtonsbyNames:(NSArray<__kindof NSString *>*)names isDistribuated:(BOOL)isDistributed;
    @end
    

    将以下代码放入VerticalContainerView.m文件中

    #import "VerticalContainerView.h"
    #import "KVConstraintExtensionsMaster.h"
    
    @implementation VerticalContainerView
    
    -(void)configureButtonsbyNames:(NSArray<__kindof NSString *>*)names isDistribuated:(BOOL)isDistributed
    {
        /* Just Two steps to Apply\Add constraints by programatically */
        /* Step 1 create & configure the view hierarchy for constraint first. */
        /* Step 2 Apply the constraints */
    
        CGFloat space  = 0.0;
        CGFloat height = 70.0;
    
        UIButton *previousContentButton = nil;
        NSInteger count  = names.count;
    
        for (NSInteger i = 0; i < count; i++)
        {
            UIButton *contentButton = [UIButton prepareNewViewForAutoLayout];
            if (i&1) {
                [contentButton setBackgroundColor:[UIColor greenColor]];
            }else{
                [contentButton setBackgroundColor:[UIColor purpleColor]];
            }
    
            [contentButton setTag:i];
            [contentButton setTitle:names[i] forState:UIControlStateNormal];
            [self addSubview:contentButton];
    
            [contentButton applyLeadingAndTrailingPinConstraintToSuperviewWithPadding:space];
    
            if (!isDistributed) {
                [contentButton applyHeightConstraint:height];
            }
    
            if (i == 0) // for first
            {
                [contentButton applyTopPinConstraintToSuperviewWithPadding:space];
            }
            else if (i == count-1) // for last
            {
                if (isDistributed) {
                    [previousContentButton applyConstraintFromSiblingViewAttribute:NSLayoutAttributeHeight toAttribute:NSLayoutAttributeHeight ofView:contentButton spacing:space];
                }
    
                [previousContentButton applyConstraintFromSiblingViewAttribute:NSLayoutAttributeBottom toAttribute:NSLayoutAttributeTop ofView:contentButton spacing:space];
                [contentButton applyBottomPinConstraintToSuperviewWithPadding:space];
            }
            else
            {
                if (isDistributed) {
                    [previousContentButton applyConstraintFromSiblingViewAttribute:NSLayoutAttributeHeight toAttribute:NSLayoutAttributeHeight ofView:contentButton spacing:space];
                }
    
                [previousContentButton applyConstraintFromSiblingViewAttribute:NSLayoutAttributeBottom toAttribute:NSLayoutAttributeTop ofView:contentButton spacing:space];
            }
    
            previousContentButton = contentButton;
        }
    
    }
    
    @end
    

    现在创建一个名为 CustomCell 的自定义 Cell 并将下面的代码放入 CustomCell.h 头文件中

    #import "VerticalContainerView.h"
    
    @interface CustomCell : UITableViewCell
    @property (weak, nonatomic) IBOutlet VerticalContainerView *leftVerticalContainerView;
    @property (weak, nonatomic) IBOutlet VerticalContainerView *rightVerticalContainerView;
    @end
    

    将以下代码放入CustomCell.m 文件中。

    #import "CustomCell.h"
    
    @implementation CustomCell
    
    -(void)prepareForReuse
    {
        // here you have to remove the all the buttons from left and right veiw becuase
        // Every cell can have distinct number buttons on left and right view.
    
        for (UIView *subView in self.leftVerticalContainerView.subviews) {
            [subView removeFromSuperview];
        }
        for (UIView *subView in self.leftVerticalContainerView.subviews) {
            [subView removeFromSuperview];
        }
    
        [super prepareForReuse];
    
    }
    
    @end
    

    现在在 Identity inspector editorInterface Builder 的帮助下,由我们的 CustomCell 更改 UITableViewCell Class

    Identity inspector editorInterface Builder 的帮助下,我们的VerticalContainerView 还可以更改left and right View Class

    现在为leftVerticalContainerView &amp; rightVerticalContainerView连接我们CusromCell的IBOutlet

    把下面的代码放在你的ViewController的viewDidLoad方法中是:

    tableView.rowHeight = UITableViewAutomaticDimension;
    /* any estimated height but must be more than 2, but it should be more estimated */
    tableView.estimatedRowHeight = 210.0;
    tableView.delegate = self;
    tableView.dataSource = self;
    
    // if you created cell from `.xib` is called CustomCell.xib,then you have to register that cell with table.
    //    UINib *nib = [UINib nibWithNibName:@"CustomCell" bundle:nil];
    //    [tableView registerNib:nib forCellReuseIdentifier:@"YouCellIdentifier"];
    

    现在在你的 ViewController 中实现 UITableView DataSource

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section{
        return 10;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath{
    
        static NSString *cellIdentifier = @"CustomCell";
        CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
    
        if (indexPath.row%2 == 0) {
            // this is fixed height constraints
            [cell.leftVerticalContainerView configureButtonsbyNames:@[@"button1",@"button2",@"button3"] isDistributed:NO];
            // this is distributed height constraints according to left view
            [cell.rightVerticalContainerView configureButtonsbyNames:@[@"button4",@"button5"] isDistributed:YES];
        }
        else{
            // this is fixed height constraints
            [cell.leftVerticalContainerView configureButtonsbyNames:@[@"button1",@"button2",@"button3",@"button4",@"button5"] isDistributed:NO];
    
            // this is isDistribuated height constraints according to left view
            [cell.rightVerticalContainerView configureButtonsbyNames:@[@"button6",@"button7",@"button8"] isDistributed:YES];
        }
    
        return cell;
    }
    

    【讨论】:

    • 我编辑了这个问题。也许不清楚,但按钮也可以在运行时添加。所以在这种情况下,您描述的方法将不起作用。
    • 我已经提供了添加约束的一般方法,但是这取决于你,你如何处理约束?
    • 我也根据你的要求更新了答案。
    【解决方案2】:

    您可以使用带有自动高度的UITableViewCells 来执行此操作。 这允许您使用约束来确定单元格的高度。

    要让它工作:

    • 添加以下行以打开自动高度:

      tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = 160.0 // 一个近似的单元格高度。

    • 使用约束使单元格的内容向外推,以便内容决定单元格的高度。
    • 在代码中使用IBOutlet 向附加视图添加高度约束。将此约束的constant 属性设置为0,并将附加视图的.hidden 属性设置为true 以隐藏附加视图。
    • 为了更好地打开/关闭,请更改 UIView 动画块内的约束 constant 属性。

    【讨论】:

    • 正如我在下面的答案评论中所写,我编辑了这个问题。 在运行时也应该添加按钮。遇到这种情况该怎么办?
    • 您可以通过编程方式添加其他视图、按钮及其约束。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多