Swift 中带有下拉菜单的自定义 UITableViewCell
Custom UITableViewCell with drop-down in Swift
我想用 XIB 实现自定义 UITableViewCell
。 Here是图纸。 主视图 shows/hides 附加视图右侧的按钮。我有两个问题:
如何隐藏附加视图?我认为一种可能性是将附加 UIView 框架中的高度设置为零。有没有更好的选择?
附加视图中的按钮(在本例中为 1-5)应该动态显示。有两组数据:一组用于左侧(按钮 1-3),另一组用于右侧(按钮 4-5)。左边按钮的高度是固定的,比方说每个 70px。应调整右侧按钮的高度,使右侧按钮的总高度与左侧总高度相同。考虑到这些规则,如何动态添加按钮?
按钮将在运行时添加。例如有两个数组:
var leftButtons:[String] = ["button1label", “button2label“, "button3label"]
var rightButtons:[String] = ["button4label", "button5label"]
。
假设我稍后在运行期间将"button6label"
添加到leftButtons
。 leftView
/rightView
的大小以及这些视图中按钮的大小应该进行调整。同样,左侧尺寸上每个按钮的高度是固定的。
您可以使用具有自动高度的 UITableViewCell
s 来执行此操作。
这允许您使用约束来确定单元格的高度。
要使其正常工作:
添加以下行以打开自动高度:
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 160.0
// 近似的单元格高度。
- 使用约束使单元格的内容向外推以便内容决定单元格的高度。
- 在代码中使用
IBOutlet
向附加视图添加高度限制。将此约束的constant
属性设置为0
,并将附加视图的.hidden
属性设置为true
以隐藏附加视图。
- 为了更好 opening/closing,更改
UIView
动画块中的约束 constant
属性。
首先,您应该在自定义 UITableViewCell 上添加 ContainerView
视图,现在在 ContainerView
- leading , trailing, top & bottom to superView
上添加约束,所有约束都为 priority 999
。
现在您应该在 ContainerView
上添加两个视图,一个是 mainView
,另一个是 additionView
。
并在 mainView
上添加约束 - 导致 superView,顶部到 superView,尾随 superView 和高度约束(比如 70)。
现在在 mainView 中添加 textfield
和 show/hide button
并在 textField
和 show/hide button
上应用约束。
textField 约束 - leading to superView
、top to superView
、bottom to superView
和 Horizontal spacing between textField & show/hide button
.
show/hide 按钮约束 - top to superView
、bottom to superView
、trailing to superView
和宽度约束。
此处mainView
配置正确。所以现在让我们配置 additionView
您应该在 additionView
中添加两个新视图,一个是 leftView
,另一个是 leftView & rightView
上的 rightView
& add constraints
。
leftView 约束 - leading to superView
, top to superView
, bottom to superView
, Horizontal spacing between leftView & rightView
,
equal 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
的自定义单元格并将下面的代码放入 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
现在我们的 CustomCell 在 Interface Builder
的 Identity inspector editor
的帮助下更改 UITableViewCell Class
也在Interface Builder
的Identity inspector editor
的帮助下,我们的VerticalContainerView
改变了left and right View Class
现在为 leftVerticalContainerView & 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;
}
我想用 XIB 实现自定义 UITableViewCell
。 Here是图纸。 主视图 shows/hides 附加视图右侧的按钮。我有两个问题:
如何隐藏附加视图?我认为一种可能性是将附加 UIView 框架中的高度设置为零。有没有更好的选择?
附加视图中的按钮(在本例中为 1-5)应该动态显示。有两组数据:一组用于左侧(按钮 1-3),另一组用于右侧(按钮 4-5)。左边按钮的高度是固定的,比方说每个 70px。应调整右侧按钮的高度,使右侧按钮的总高度与左侧总高度相同。考虑到这些规则,如何动态添加按钮?
按钮将在运行时添加。例如有两个数组:
var leftButtons:[String] = ["button1label", “button2label“, "button3label"]
var rightButtons:[String] = ["button4label", "button5label"]
。
假设我稍后在运行期间将"button6label"
添加到leftButtons
。 leftView
/rightView
的大小以及这些视图中按钮的大小应该进行调整。同样,左侧尺寸上每个按钮的高度是固定的。
您可以使用具有自动高度的 UITableViewCell
s 来执行此操作。
这允许您使用约束来确定单元格的高度。
要使其正常工作:
添加以下行以打开自动高度:
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 160.0
// 近似的单元格高度。- 使用约束使单元格的内容向外推以便内容决定单元格的高度。
- 在代码中使用
IBOutlet
向附加视图添加高度限制。将此约束的constant
属性设置为0
,并将附加视图的.hidden
属性设置为true
以隐藏附加视图。 - 为了更好 opening/closing,更改
UIView
动画块中的约束constant
属性。
首先,您应该在自定义 UITableViewCell 上添加 ContainerView
视图,现在在 ContainerView
- leading , trailing, top & bottom to superView
上添加约束,所有约束都为 priority 999
。
现在您应该在 ContainerView
上添加两个视图,一个是 mainView
,另一个是 additionView
。
并在 mainView
上添加约束 - 导致 superView,顶部到 superView,尾随 superView 和高度约束(比如 70)。
现在在 mainView 中添加 textfield
和 show/hide button
并在 textField
和 show/hide button
上应用约束。
textField 约束 - leading to superView
、top to superView
、bottom to superView
和 Horizontal spacing between textField & show/hide button
.
show/hide 按钮约束 - top to superView
、bottom to superView
、trailing to superView
和宽度约束。
此处mainView
配置正确。所以现在让我们配置 additionView
您应该在 additionView
中添加两个新视图,一个是 leftView
,另一个是 leftView & rightView
上的 rightView
& add constraints
。
leftView 约束 - leading to superView
, top to superView
, bottom to superView
, Horizontal spacing between leftView & rightView
,
equal 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
的自定义单元格并将下面的代码放入 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
现在我们的 CustomCell 在 Interface Builder
Identity inspector editor
的帮助下更改 UITableViewCell Class
也在Interface Builder
Identity inspector editor
的帮助下,我们的VerticalContainerView
改变了left and right View Class
现在为 leftVerticalContainerView & rightVerticalContainerView
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;
}