【问题标题】:UITableView multiple sections with GUI Elements UIButton, UISwitch, etcUITableView 多个部分,带有 GUI 元素 UIButton、UISwitch 等
【发布时间】:2011-10-25 20:52:43
【问题描述】:

我已经在这个问题上绞尽脑汁了一天左右...我已经搜索了这个论坛以及谷歌和其他博客等。都无济于事。

我正在做的是创建一个包含多个部分的UITableView,并且在每个部分中,每一行都有不同的 GUI 元素(即设置屏幕)

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 3;
}

我想要实现的只是每个部分在不同的单元格中都有不同的 GUI 元素。但是正如您在此屏幕截图中看到的那样:

最初一切都按原样显示,但在向上和向下滚动一次后,问题就开始了。元素开始四处移动,向上和向下滚动的次数越多/时间越长,元素移动的次数就越多。

!["UITableView 在部分和行中带有 GUI 元素。错误?故障?无知?"][2]

这是一个错误吗?毛刺?还是无知? (可能是后者)-我已经删除了除 GUI 代码之外的所有其他代码,如果它意味着任何我正在使用 NIB 创建UITableView

另外,这是我的cellForRowAtIndexPath 方法的代码。如果有人能指出我正确的方向或告诉我我做错了什么,我将永远感激不尽。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }


    // Set up the cell
    // desired section
    if(indexPath.section == 0) {
        //
        //  Load Settings
        //

        // button
        UIButton * loadButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        loadButton.frame = CGRectMake(0.0, 0.0, 300.0, 44.0);
        [loadButton setTitle:@"Load Image" forState:UIControlStateNormal];
        [loadButton setTitle:@"Load Image" forState:UIControlStateSelected];
        [loadButton addTarget:self action:@selector(loadImage:) forControlEvents:UIControlEventTouchUpInside];
        [cell.contentView addSubview:loadButton]; 


    } else if(indexPath.section == 1) {
        //
        //  Mode Settings
        //
        if(indexPath.row == 0) {
            cell.text = [mode objectAtIndex:indexPath.row];    
        } else if(indexPath.row == 1) {
            cell.text = [mode objectAtIndex:indexPath.row];    
        }


    } else if(indexPath.section == 2) {
        //
        //  Marker Settings
        //

        if(indexPath.row == 0) {
            // description text
            cell.text = [marker objectAtIndex:indexPath.row];    

            // switch
            UISwitch *markerSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
            cell.accessoryView = markerSwitch;
            [markerSwitch setOn:YES animated:NO];
            [markerSwitch addTarget:self action:@selector(markerToggle:) forControlEvents:UIControlEventValueChanged];
            [markerSwitch release];       

        } else if(indexPath.row == 1) {
            UISlider *markerGridSlider = [[UISlider alloc] initWithFrame:CGRectMake(0.0, 10.0, 284, 10.0)];
            cell.accessoryView = markerGridSlider;
            markerGridSlider.minimumValueImage = [UIImage imageNamed:@"size_icon_1x1.png"];
            markerGridSlider.maximumValueImage = [UIImage imageNamed:@"size_icon_8x8.png"];

            [markerGridSlider setMinimumValue:1.0];
            [markerGridSlider setMaximumValue:8.0];
            markerGridSlider.value = 8.0;
            [markerGridSlider addTarget:self action:@selector(markerGrid:) forControlEvents:UIControlEventValueChanged];
            [markerGridSlider release];       

        } else if(indexPath.row == 2) {
            UISlider *markerSpacingSlider = [[UISlider alloc] initWithFrame:CGRectMake(0.0, 10.0, 284, 10.0)];
            cell.accessoryView = markerSpacingSlider;
            markerSpacingSlider.minimumValueImage = [UIImage imageNamed:@"spacing_icon_min.png"];
            markerSpacingSlider.maximumValueImage = [UIImage imageNamed:@"spacing_icon_max.png"];

            [markerSpacingSlider setMinimumValue:1.0];
            [markerSpacingSlider setMaximumValue:(320.0/8.0)];
            markerSpacingSlider.value = 1.0;
            [markerSpacingSlider addTarget:self action:@selector(markerSpacing:) forControlEvents:UIControlEventValueChanged];
            [markerSpacingSlider release];       
        }
    }

    return cell;
}

谢谢。


非常感谢您的帮助。

也许我不明白你的意思,但我认为我已经正确地实施了你的建议。但是我仍然得到元素交换位置的故障,尽管现在经过大约 5 次以上的向上和向下滑动并且我的 UISwitch 现在被放置在左上角。

这是我更新的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];



        if([indexPath section] == 0) {
            //
            // Load Settings
            //

            // button
            UIButton *loadButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect] autorelease];
            loadButton.frame = CGRectMake(0.0, 0.0, 300.0, 44.0);
            [loadButton addTarget:self action:@selector(loadImage:) forControlEvents:UIControlEventTouchUpInside];
            [loadButton setTag:1000];

            [cell.contentView addSubview:loadButton]; 

        } 



        if([indexPath section] == 1) {
            //
            // Mode Settings
            //
            if([indexPath row] == 0) {
                cell.text = [mode objectAtIndex:[indexPath row]];    
            }
            if([indexPath row] == 1) {
                cell.text = [mode objectAtIndex:[indexPath row]];    
            }
        } 



        if([indexPath section] == 2) {
            //
            // Marker Settings
            //
            if([indexPath row] == 0) {
                // switch
                UISwitch *markerSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
                [markerSwitch setOn:YES animated:NO];
                [markerSwitch addTarget:self action:@selector(markerToggle:) forControlEvents:UIControlEventValueChanged];
                [markerSwitch setTag:3000];

                [cell.contentView addSubview:markerSwitch]; 
                [markerSwitch release];

            }
            if([indexPath row] == 1) {
                // slider
                UISlider *markerGridSlider = [[UISlider alloc] initWithFrame:CGRectMake(0.0, 10.0, 284, 10.0)];
                markerGridSlider.minimumValueImage = [UIImage imageNamed:@"size_icon_1x1.png"];
                markerGridSlider.maximumValueImage = [UIImage imageNamed:@"size_icon_8x8.png"];

                [markerGridSlider setMinimumValue:1.0];
                [markerGridSlider setMaximumValue:8.0];
                [markerGridSlider setValue:8.0];
                [markerGridSlider addTarget:self action:@selector(markerGrid:) forControlEvents:UIControlEventValueChanged];
                [markerGridSlider setTag:3100];

                [cell.contentView addSubview:markerGridSlider]; 
                [markerGridSlider release];

            }
            if([indexPath row] == 2) {
                // slider
                UISlider *markerSpacingSlider = [[UISlider alloc] initWithFrame:CGRectMake(0.0, 10.0, 284, 10.0)];
                markerSpacingSlider.minimumValueImage = [UIImage imageNamed:@"spacing_icon_min.png"];
                markerSpacingSlider.maximumValueImage = [UIImage imageNamed:@"spacing_icon_max.png"];

                [markerSpacingSlider setMinimumValue:1.0];
                [markerSpacingSlider setMaximumValue:(320.0/8.0)];
                [markerSpacingSlider setValue:1.0];
                [markerSpacingSlider addTarget:self action:@selector(markerSpacing:) forControlEvents:UIControlEventValueChanged];
                [markerSpacingSlider setTag:3200];

                [cell.contentView addSubview:markerSpacingSlider]; 
                [markerSpacingSlider release];

            }
        }


    } // end cell == nil


    // Load
    UIButton *loadButton = (UIButton*)[cell.contentView viewWithTag:1000];
    [loadButton setTitle:@"Load Image" forState:UIControlStateNormal];
    [loadButton setTitle:@"Load Image" forState:UIControlStateSelected];

    // Mode

    // Marker
    UISwitch *markerSwitch = (UISwitch*)[cell.contentView viewWithTag:3000];
    UISlider *markerGridSlider = (UISlider*)[cell.contentView viewWithTag:3100];
    UISlider *markerSpacingSlider = (UISlider*)[cell.contentView viewWithTag:3200];


    return cell;
}

【问题讨论】:

    标签: objective-c user-interface uitableview


    【解决方案1】:

    iOS 中绑定到 UITable 的所有单元格都是可重用。 这就是为什么您首先使用函数调用“dequeueReusableCellWithIdentifier”获取单元格的原因,该单元格可能不是零,指向之前加载的单元格。在您的情况下,即使单元格不为零,您也可以向其中添加子视图。当您上下滚动时,这将无限次发生。

    这是一个小例子:

    -(int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return 2;
    }
    
    -(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        static NSString* CellIdentifier = @"Cell";
    
        const NSInteger lblTag = 101;
        const NSInteger btnTag = 102;
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
        //First init the cells
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    
            //Initialize subviews of cells only in this block.
    
            if (indexPath.row == 0) {
                //Only the first cell on the top has a UILabel
                UILabel *lbl = [[[UILabel alloc] initWithFrame:CGRectMake(5, 5, 100, 20)] autorelease];
                lbl.tag = lblTag;    
                [cell.contentView addSubview:lbl];
            } else if (indexPath.row == 1) {
                //Only the 2nd cell has a UIButton
                UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
                btn.frame = CGRectMake(5, 5, 60, 20);
                btn.tag = btnTag;    
                [cell.contentView addSubview:btn];
            }
        }
    
        //Modify your cells here
        if (indexPath.row == 0) {
            //Only the first cell on the top has a UILabel
            UILabel *lbl = (UILabel*)[cell.contentView viewWithTag:lblTag];
            //Do stuff with our label
    
            lbl.text = [NSString stringWithFormat:@"%d",indexPath.row];
    
        } else if (indexPath.row == 1) {
            //Only the 2nd cell has a UIButton
            UIButton *btn = (UIButton*)[cell.contentView viewWithTag:btnTag];
            //Do stuff with our button
            [btn setTitle:[NSString stringWithFormat:@"%d",indexPath.row] forState:UIControlStateNormal];
    
        }
    
        return cell;
    
    }
    

    在您的非常特定情况下,您会这样写-

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    {
        if (section == 0) {
            return 1;
        } else if (section == 1) {
            return 2;
        } else if (section == 2) {
            return 3;
        } else {
            return 0;
        }
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        static NSString *CellIdentifier = @"Cell";
    
    
    
        const NSInteger
        sec0BtnTag = 101,
        markerSwitchTag = 102,
        markerGridSliderTag = 103,
        markerSpacingSliderTag = 104;
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    
    
    
            if([indexPath section] == 0) {
                //
                // Load Settings
                //
    
                // button
                UIButton *loadButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect] autorelease];
                loadButton.frame = CGRectMake(0.0, 0.0, 300.0, 44.0);
                [loadButton addTarget:self action:@selector(loadImage:) forControlEvents:UIControlEventTouchUpInside];
                [loadButton setTag:sec0BtnTag];
    
                [cell.contentView addSubview:loadButton]; 
    
            } 
    
    
    
            else if([indexPath section] == 2) {
                //
                // Marker Settings
                //
                if([indexPath row] == 0) {
                    // switch
                    UISwitch *markerSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
                    [markerSwitch setOn:YES animated:NO];
                    [markerSwitch addTarget:self action:@selector(markerToggle:) forControlEvents:UIControlEventValueChanged];
                    [markerSwitch setTag:markerSwitchTag];
    
                    [cell.contentView addSubview:markerSwitch]; 
                    [markerSwitch release];
    
                }
                else if([indexPath row] == 1) {
                    // slider
                    UISlider *markerGridSlider = [[UISlider alloc] initWithFrame:CGRectMake(0.0, 10.0, 284, 10.0)];
                    markerGridSlider.minimumValueImage = [UIImage imageNamed:@"size_icon_1x1.png"];
                    markerGridSlider.maximumValueImage = [UIImage imageNamed:@"size_icon_8x8.png"];
    
                    [markerGridSlider setMinimumValue:1.0];
                    [markerGridSlider setMaximumValue:8.0];
                    [markerGridSlider setValue:8.0];
                    [markerGridSlider addTarget:self action:@selector(markerGrid:) forControlEvents:UIControlEventValueChanged];
                    [markerGridSlider setTag:markerGridSliderTag];
    
                    [cell.contentView addSubview:markerGridSlider]; 
                    [markerGridSlider release];
    
                }
                else if([indexPath row] == 2) {
                    // slider
                    UISlider *markerSpacingSlider = [[UISlider alloc] initWithFrame:CGRectMake(0.0, 10.0, 284, 10.0)];
                    markerSpacingSlider.minimumValueImage = [UIImage imageNamed:@"spacing_icon_min.png"];
                    markerSpacingSlider.maximumValueImage = [UIImage imageNamed:@"spacing_icon_max.png"];
    
                    [markerSpacingSlider setMinimumValue:1.0];
                    [markerSpacingSlider setMaximumValue:(320.0/8.0)];
                    [markerSpacingSlider setValue:1.0];
                    [markerSpacingSlider addTarget:self action:@selector(markerSpacing:) forControlEvents:UIControlEventValueChanged];
                    [markerSpacingSlider setTag:markerSpacingSliderTag];
    
                    [cell.contentView addSubview:markerSpacingSlider]; 
                    [markerSpacingSlider release];
    
                }
            }
    
    
        } // end cell == nil
    
        //Load specific cell row values
    
        if([indexPath section] == 0) {
            //
            // Load Settings
            //
    
            // button
            UIButton *loadButton = (UIButton*)[cell.contentView viewWithTag:sec0BtnTag];
            [loadButton setTitle:@"Load Image" forState:UIControlStateNormal];
            [loadButton setTitle:@"Load Image" forState:UIControlStateSelected];
            //do other stuff with the button here according to the specific row & section
    
        } 
    
    
    
        if([indexPath section] == 1) {
            //
            // Mode Settings
            //
            if([indexPath row] == 0) {
                cell.text = [mode objectAtIndex:[indexPath row]];    
            }
            if([indexPath row] == 1) {
                cell.text = [mode objectAtIndex:[indexPath row]];    
            }
        } 
    
    
    
        if([indexPath section] == 2) {
            //
            // Marker Settings
            //
            if([indexPath row] == 0) {
                // switch
                UISwitch *markerSwitch = (UISwitch*)[cell.contentView viewWithTag:markerSwitchTag];
                //do stuff with the switch here according to the specific row & section
            }
            if([indexPath row] == 1) {
                // slider
                UISlider *markerGridSlider = (UISlider*)[cell.contentView viewWithTag:markerGridSliderTag];
                //do stuff with the slider here according to the specific row & section
            }
            if([indexPath row] == 2) {
                // slider
                UISlider *markerSpacingSlider = (UISlider*)[cell.contentView viewWithTag:markerSpacingSliderTag];
                //do stuff with the slider here according to the specific row & section
    
    
    
            }
        }
    
    
        return cell;
    }
    

    【讨论】:

    • 好的。我可能不完全理解你的意思。虽然我认为我已经实施了你的建议。大约需要 5 次以上的 UP 和 DOWN 才能恢复故障,但它仍然存在。
    • 修改了我的答案。请参阅包含的示例。
    【解决方案2】:

    为每个部分更改 static NSString *CellIdentifier = @"Cell";,例如:

    NSString *CellIdentifier; if(indexPath.section==0){ CellIdentifier= @"Cell"; }elseif(indexPath.section==2){ CellIdentifier=@"Cell2"; }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-15
      • 1970-01-01
      • 1970-01-01
      • 2016-10-09
      • 1970-01-01
      • 2011-04-15
      相关资源
      最近更新 更多