我正在尝试动态填充包含多行按钮的表。当表启动时,我传递一个包含正确按钮的数组。按钮的数量以及行的数量会有所不同。这是有效的,直到我需要创建一个新行(即,太多的按钮适合第一行)。我们假设我将其限制为每行4个按钮。然后我的按钮从第2行开始,而不是第1行。它们也被限制在右边界。
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows = 0; // No rows if section is unknown!
switch (section)
{
case TableViewSectionFormatButtons:
{
if ([[self fileTypeButtonsArray] count] % kButtonsPerRow)
return ([[self fileTypeButtonsArray] count] / kButtonsPerRow) + 1;
else
return [[self fileTypeButtonsArray] count] / kButtonsPerRow;
}
break;
case TableViewSectionExportSwitches:
rows = 4;
break;
case TableViewSectionExportButton:
rows = 1;
break;
default:
break;
}
return rows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *defaultCellIdentifier = @"defaultCellIdentifier";
static NSString *detailCellIdentifier = @"detailCellIdentifier";
UITableViewCell *cellToReturn = nil;
// Usage note: Both kinds of cells get created every time, which is arguably wasteful. Since there aren't many rows involved
// it's simpler just to ignore the one that we don't need. Assign the one we want to cellToReturn.
UITableViewCell *defaultCell = [tableView dequeueReusableCellWithIdentifier:defaultCellIdentifier]; // Image on left
if (defaultCell == nil) {
defaultCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:defaultCellIdentifier];
}
UITableViewCell *detailCell = [tableView dequeueReusableCellWithIdentifier:detailCellIdentifier]; // Text on right
if (detailCell == nil) {
detailCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:detailCellIdentifier];
}
// Clear old values
defaultCell.textLabel.textAlignment = NSTextAlignmentLeft;
defaultCell.accessoryType = UITableViewCellAccessoryNone;
defaultCell.accessoryView = nil;
defaultCell.imageView.image = nil;
detailCell.accessoryType = UITableViewCellAccessoryNone;
detailCell.imageView.image = nil;
switch (indexPath.section) {
case TableViewSectionFormatButtons: {
for (int i = 0; i < [self.fileTypeButtonsArray count]; i++)
{
UIButton *currentButton = (UIButton *)[self.fileTypeButtonsArray objectAtIndex:i];
[currentButton setTag:i];
[currentButton setFrame:CGRectMake((kButtonPadding + (i * (kButtonWidth + kButtonPadding))), kButtonPadding, kButtonWidth, kButtonHeight)];
[defaultCell.contentView addSubview:currentButton];
}
defaultCell.selectionStyle = UITableViewCellSelectionStyleNone;
cellToReturn = defaultCell;
}
break;
case TableViewSectionExportSwitches: {
defaultCell.selectionStyle = UITableViewCellSelectionStyleNone;
if (indexPath.row == 0) {
defaultCell.textLabel.text = NSLocalizedString(@"synopsisSwitchLabel", @"Synopsis - Export switch label to indicate if Synopsis text should be included in export.");
self.synopsisSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
defaultCell.accessoryView = self.synopsisSwitch;
// self.synopsisSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:kUserDefaultsShowNotesIndicatorKey];
[self.synopsisSwitch addTarget:self action:@selector(synopsisSwitchValueChanged:) forControlEvents: UIControlEventValueChanged];
}
else if (indexPath.row == 1)
{
defaultCell.textLabel.text = NSLocalizedString(@"bodySwitchLabel", @"Body - Export switch label to indicate if Body text should be included in export.");
self.bodySwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
defaultCell.accessoryView = self.bodySwitch;
// self.bodySwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:kUserDefaultsShowNotesIndicatorKey];
[self.bodySwitch addTarget:self action:@selector(bodySwitchValueChanged:) forControlEvents: UIControlEventValueChanged];
}
else if (indexPath.row == 2)
{
defaultCell.textLabel.text = NSLocalizedString(@"notesSwitchLabel", @"Notes - Export switch label to indicate if Notes should be included in export.");
self.notesSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
defaultCell.accessoryView = self.notesSwitch;
// self.notesSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:kUserDefaultsShowExpandedOutlineKey];
[self.notesSwitch addTarget:self action:@selector(notesSwitchValueChanged:) forControlEvents: UIControlEventValueChanged];
}
else if (indexPath.row == 3)
{
defaultCell.textLabel.text = NSLocalizedString(@"imagesSwitchLabel", @"Images - Export switch label to indicate if Images should be included in export.");
self.imagesSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
defaultCell.accessoryView = self.imagesSwitch;
// self.imagesSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:kUserDefaultsStoryboardModeKey];
[self.imagesSwitch addTarget:self action:@selector(imagesSwitchValueChanged:) forControlEvents: UIControlEventValueChanged];
}
cellToReturn = defaultCell;
}
break;
case TableViewSectionExportButton:
{
defaultCell.textLabel.textAlignment = NSTextAlignmentCenter;
if (indexPath.row == 0)
{
defaultCell.textLabel.text = NSLocalizedString(@"nextButtonTitle", @"Next - Button title indicating user is ready to proceed with Export.");
defaultCell.textLabel.textColor = [UIColor blueColor];
}
cellToReturn = defaultCell;
}
break;
}
return cellToReturn;
}
示例按钮超过1行 - 不好
示例按钮适合1行 - 很好
我意识到我只是告诉它继续向对方添加按钮。我很难说我会告诉它将哪些行放入其中。同样难以理解为什么它们从第二行(索引1)开始,而不是顶行(索引0)。感谢您的帮助。
答案 0 :(得分:1)
在numberOfRowsInSection:
方法中,如果按钮整齐地放入行中,TableViewSectionFormatButtons:
会在另一行上添加,即if ([[self fileTypeButtonsArray] count] % kButtonsPerRow)
;但这听起来与你想做的完全相反。听起来好像你只想要额外的一排,如果你的按钮不能整齐地放在它上面的行中,在这种情况下,我建议用一行代替它:
case TableViewSectionFormatButtons: {
return ([[self fileTypeButtonsArray] count] + kButtonsPerRow - 1) / kButtonsPerRow;
}
简化整数除法。
至于你的cellForRowAtIndexPath:
方法,(1)你需要考虑每行按钮的数量,即你的算法中有kButtonsPerRow
,(2)你需要知道你在哪一行&# 39;重新添加,以及(3)使用该信息你只想将属于当前行的按钮放在当前行中,所以你不希望该循环从0开始并一直走到你的按钮数组的末尾。例如:
case TableViewSectionFormatButtons: {
// Calculate the index of the first button in the current row
int firstButtonIndex = indexPath.row * kButtonsPerRow;
// Then starting from that index place kButtonsPerRow within that row
for (int i = firstButtonIndex ; i < firstButtonIndex + kButtonsPerRow ; i++) {
if (self.fileTypeButtonsArray.count > i) {
UIButton *currentButton = (UIButton *)[self.fileTypeButtonsArray objectAtIndex:i];
[currentButton setTag:i];
[currentButton setFrame:CGRectMake((kButtonPadding + ((i-firstButtonIndex) * (kButtonWidth + kButtonPadding))), kButtonPadding, kButtonWidth, kButtonHeight)];
[defaultCell.contentView addSubview:currentButton];
}
}
defaultCell.selectionStyle = UITableViewCellSelectionStyleNone;
cellToReturn = defaultCell;
}
这样的事情应该有用。
P.S。您在每个cellForRowAtIndexPath:
期间重复使用单元格并添加按钮作为子视图这一事实可能会导致一些问题。如果您要按照自己在代码中已经完成的方式清除旧值,也许您也应该删除相同位置的旧按钮,例如:
// Clear old values
defaultCell.textLabel.textAlignment = NSTextAlignmentLeft;
defaultCell.accessoryType = UITableViewCellAccessoryNone;
defaultCell.accessoryView = nil;
defaultCell.imageView.image = nil;
for (UIView *view in [defaultCell subviews]) {
if ([view isKindOfClass:[UIButton class]]) {
[view removeFromSuperview];
}
}