UIButton在单元重新加载时被创建两次

时间:2014-03-24 06:50:37

标签: ios objective-c uitableview uibutton

UIButton内有UITableViewCell。当应用程序首次启动时,它按预期工作,我创建了它的框架。

当我滚动传递按住按钮的单元格时,它会在按钮下方创建第二个按钮实例 这是一个视频来说明我的问题:http://pixori.al/DJ1k

这里是UITableViewCell的代码以及我如何填充单元格。 不知道为什么它会像这样。

#pragma mark - UITableViewDataSource

// 3 sections, (1 = mistarOverview) (2 = hourlyForecast) (3 = dailyForecast)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 3;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section == 0) {
        return MAX(6,6) + 1; //TODO add getNumberOfClasses for people with 7 or 8 classes
    } else if (section == 1) {
        return MIN([[MAManager sharedManager].hourlyForecast count], 6) + 1;
    } else {
        return MIN([[MAManager sharedManager].dailyForecast count], 6) + 1;
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"CellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Redefine layout variables in method from `viewDidLoad`
    CGFloat inset = 20; // For padding


    if (! cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
    }

    // Sets up attributes of each cell
    cell.selectionStyle = UITableViewCellSelectionStyleNone; //TODO none
    cell.backgroundColor = [UIColor colorWithWhite:0 alpha:0.2];
    cell.textLabel.textColor = [UIColor whiteColor];
    cell.detailTextLabel.textColor = [UIColor whiteColor];
    QBFlatButton* loginButton = nil;

    if (indexPath.section == 0) {
        if (indexPath.row == 0) {
            [self configureHeaderCell:cell title:@"Grades"];

            if ([cell.textLabel.text isEqual: @"Grades"] && (!loginButton) && (indexPath.row == 0) && (indexPath.section == 0)) {

                UIView *cellView = cell.contentView;
                CGRect loginButtonFrame = CGRectMake((cellView.frame.size.width - (80 + inset)), 18, 80, (cellView.frame.size.height));
                loginButton = [[QBFlatButton alloc] initWithFrame:loginButtonFrame];
                [loginButton addTarget:self action:@selector(loginButtonWasPressed)forControlEvents:UIControlEventTouchUpInside];
                loginButton.faceColor = [UIColor grayColor];
                loginButton.sideColor = [UIColor clearColor];

                loginButton.radius = 6.0;
                loginButton.margin = 4.0;
                loginButton.depth = 3.0;
                loginButton.alpha = 0.3;

                loginButton.titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:20];
                [loginButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
                [loginButton setTitle:@"Login" forState:UIControlStateNormal];
                [cellView addSubview:loginButton];
            }
        } else {
            cell.selectionStyle = UITableViewCellSelectionStyleBlue;
            cell.textLabel.text = [NSString stringWithFormat:@"Period %ld               A+", (long)indexPath.row];
            cell.detailTextLabel.text = @"Class name";
            //TODO get grades and config using method (TB Created)
        }
    } else if (indexPath.section == 1) {
        if (indexPath.row == 0) {
            [self configureHeaderCell:cell title:@"Hourly Forecast"];
        }
        else {
            // Get hourly weather and configure using method
            MACondition *weather = [MAManager sharedManager].hourlyForecast[indexPath.row - 1];
            [self configureHourlyCell:cell weather:weather];
        }
    }
    else if (indexPath.section == 2) {
        if (indexPath.row == 0) {
            [self configureHeaderCell:cell title:@"Daily Forecast"];
        }
        else if (indexPath.section == 2) {
            // Get daily weather and configure using method
            MACondition *weather = [MAManager sharedManager].dailyForecast[indexPath.row - 1];
            [self configureDailyCell:cell weather:weather];
        }
    }

    return cell;
}

4 个答案:

答案 0 :(得分:2)

实现以下UITableView委托方法

-(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
//In here, check the index path. When you have the cell that contains the button, pop it out from there by using [button removeFromSuperView];
}

出列单元格时出现问题。由于单元格正在重复使用,它已经有了按钮,您只需重新添加它即可。这将解决您的问题。但是,我建议你为UITableViewCell创建一个子类,在它的prepareForReuse方法中,弹出按钮。由你决定。两者都有效。

答案 1 :(得分:1)

表视图单元格不仅被释放,而是移出可见区域。存储它们以便重复使用,然后在tableView dequeueReusableCellWithIdentifier:CellIdentifier];

中返回

因此您需要在使用后或重复使用前清洁细胞。有几种方法:

1.在创建标签时将标签添加到按钮

loginButton.tag = SOME_TAG;

之后

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

使用此标记搜索视图

loginButton = [cell viewWithTag:SOME_TAG];

如果loginButton != nil您可以重复使用它或从单元格中删除,然后创建一个新的。

2.实现UITableViewDelegate方法

-(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

并删除其中的登录按钮。

3.创建自定义UITableViewCell类并实施prepareForReuse方法。

答案 2 :(得分:0)

每次在此方法中返回单元格时,都会添加按钮。如果将单元格从屏幕滚动并重新打开,则会再次为同一索引路径调用此方法,然后再次添加该按钮。

你声明变量,不做任何事情,然后检查它是否为零。它总是零,所以你总是添加按钮。

快速而肮脏的解决方案是为按钮添加标签,然后使用viewWithTag:检查其存在。

更好的解决方案是创建自定义单元子类,并在init方法中设置这样的一次性属性。您的单元格内容对于每个部分看起来也非常不同,因此对每个部分使用不同的重用标识符,并且可能使用不同的单元子类。清除子视图很昂贵,可能会损害您的滚动性能。

答案 3 :(得分:0)

第一次运行项目时,会调用cellForRowAtIndexPath ..... 然后,无论何时滚动tableView,它都会再次调用cellForRowAtIndexPath并自动重新加载数据。 因此,您必须将CellIdentifier作为每个单元格的唯一标识。

您必须从

中删除静态关键字
static NSString *CellIdentifier = @"CellIdentifier";

现在你有了

NSString *CellIdentifier = @"CellIdentifier";

只有这件事

现在你必须写下面的

NSString *CellIdentifier = [NSString stringWithFormat:@"%@",indexPath];

现在享受.....

相关问题