在 Xcode 中的 UITableView Cell 中动态调整 UIImage 宽度

发布于 2024-09-03 02:57:40 字数 2595 浏览 2 评论 0原文

我正在使用下面的代码来组合我的 UITableView。单元格高度允许前三行显示在表格中而无需滚动。前三行一切都很好。但是,一旦我向下滚动超过原始的前三行,myImage 中的图像就会继承前三行中单元格的宽度,并且不会根据从基于 indexPath.row 的数组中提取的值调整大小。

显然,该单元格是从最初绘制的单元格的 else 语句中重用的,但我需要找出一种方法来允许 myImage 宽度针对每行而变化。

非常感谢任何帮助! lq

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

const NSInteger LABEL_TAG = 1001;
const NSInteger IMAGE_TAG = 1002;

UILabel *myLabel;
UIImageView *myImage;

static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [myTableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {

    // Create the cell

    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
                        reuseIdentifier:CellIdentifier]
                        autorelease];

    // Constant values

    const CGFloat LABEL_HEIGHT = 20;
    const CGFloat LABEL_WIDTH = 140;
    const CGFloat LABEL_INDENT = 1;
    const CGFloat LABEL_TOP = 0.065 * myTableView.rowHeight;

    // Create the label;

    myLabel = [[[UILabel alloc] initWithFrame:
            CGRectMake(
                LABEL_INDENT,
                LABEL_TOP  + LABEL_HEIGHT,
                LABEL_WIDTH,
                LABEL_HEIGHT)]
            autorelease];

    [cell.contentView addSubview:myLabel];

    // Configure the label

    myLabel.tag = LABEL_TAG;
    myLabel.backgroundColor = [UIColor clearColor];
    myLabel.textColor = [UIColor blueColor];
    myLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize] - 3];
    myLabel.textAlignment = UITextAlignmentRight;

    // Create the image (NOTE: THIS IS THE PROBLEMATIC PART)

    // Extract the width for the image based on an array value for each row:

    int xValue = [[myArray objectAtIndex:(indexPath.row)]intValue]; 
    float xLength = (float)xValue / 100;

    myImage = [[[UIImageView  alloc] initWithFrame:
                CGRectMake(
                    LABEL_INDENT + 53,              // This places the image to the right of the label
                    LABEL_TOP  + LABEL_HEIGHT,
                    xLength * LABEL_WIDTH,          

// 这里是调整每行宽度的地方 标签_高度] 自动释放];

    [cell.contentView addSubview:myImage];

    myImage.contentMode = UIViewContentModeLeft;
    myImage.image = [UIImage imageNamed:@"ProgressBar.png"];
    myImage.clipsToBounds = YES;

} else {

    // Re-use cells

    myLabel = (UILabel *)[cell viewWithTag:LABEL_TAG];
    myImage = (UIImageView *)[cell viewWithTag:IMAGE_TAG];  
}

return cell;

}

I am using the code below to put together my UITableView. The Cell height allows the first three rows to show in the table without scrolling. Everything is fine with those first three rows. But as soon as I scroll down past the original first three rows, the image in the myImage inherits the width of cells in the first three rows and does not resize according to the value extracted from the array based on indexPath.row.

The cell is obviously being reused from the else statement from the originally painted cells but I need to figure out a way to allow the myImage width to vary for each row.

Any help is Greatly Appreciated!
lq

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

const NSInteger LABEL_TAG = 1001;
const NSInteger IMAGE_TAG = 1002;

UILabel *myLabel;
UIImageView *myImage;

static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [myTableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {

    // Create the cell

    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
                        reuseIdentifier:CellIdentifier]
                        autorelease];

    // Constant values

    const CGFloat LABEL_HEIGHT = 20;
    const CGFloat LABEL_WIDTH = 140;
    const CGFloat LABEL_INDENT = 1;
    const CGFloat LABEL_TOP = 0.065 * myTableView.rowHeight;

    // Create the label;

    myLabel = [[[UILabel alloc] initWithFrame:
            CGRectMake(
                LABEL_INDENT,
                LABEL_TOP  + LABEL_HEIGHT,
                LABEL_WIDTH,
                LABEL_HEIGHT)]
            autorelease];

    [cell.contentView addSubview:myLabel];

    // Configure the label

    myLabel.tag = LABEL_TAG;
    myLabel.backgroundColor = [UIColor clearColor];
    myLabel.textColor = [UIColor blueColor];
    myLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize] - 3];
    myLabel.textAlignment = UITextAlignmentRight;

    // Create the image (NOTE: THIS IS THE PROBLEMATIC PART)

    // Extract the width for the image based on an array value for each row:

    int xValue = [[myArray objectAtIndex:(indexPath.row)]intValue]; 
    float xLength = (float)xValue / 100;

    myImage = [[[UIImageView  alloc] initWithFrame:
                CGRectMake(
                    LABEL_INDENT + 53,              // This places the image to the right of the label
                    LABEL_TOP  + LABEL_HEIGHT,
                    xLength * LABEL_WIDTH,          

// This is where the width of each row is adjusted
LABEL_HEIGHT]
autorelease];

    [cell.contentView addSubview:myImage];

    myImage.contentMode = UIViewContentModeLeft;
    myImage.image = [UIImage imageNamed:@"ProgressBar.png"];
    myImage.clipsToBounds = YES;

} else {

    // Re-use cells

    myLabel = (UILabel *)[cell viewWithTag:LABEL_TAG];
    myImage = (UIImageView *)[cell viewWithTag:IMAGE_TAG];  
}

return cell;

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

酒几许 2024-09-10 02:57:40

正如您在评论中提请注意的那样,上面重复使用了单元格,但是;找到缓存的单元格后,您可以再次进行设置,无论该单元格是旧的还是新的。

UITableViewCell 是一个“两部分”,第一次引用单元格时,它会被实例化并构建,所有后续引用它的时间都应该只更新。 (每次滚动到屏幕上或重新加载表格视图时都会引用一个单元格。这种情况经常发生,因此为了节省 CPU 时间,最好不要一次又一次地进行相同的设置)。

因此,请尝试像这样处理它:

- (void) configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {

    UILabel *settingText = [ISInterfaceElement getLabel:Headline]; //Opps... ISInterfaceElement is my custom class. All it does is return a UILabel with settings that comply for a Headline label, according to an enum in the header.
    [settingText setFrame:CGRectMake(0.0f, 15.0f, 320.0f, 20.0f)];
    [settingText setTextAlignment:UITextAlignmentCenter];
    [settingText setTag:SETTINGS_LABEL];
[cell addSubview:settingText];
    UIView *background = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 50.0f)];
    [cell addSubView:background]; //added
    [background release]; //added

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];     
}

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

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


    [(UILabel*)[cell viewWithTag:SETTINGS_LABEL] setText:@"Settings…"];

    return cell;
}

因此,如果 cellForRowAtIndexPath 需要新的单元设置,则 cellForRowAtIndexPath 会调用 configureCell 方法,否则它只是
使用模型中的正确值更新单元格(通常是 [someArray objectAtIndex:indexPath.row] 但在我的例子中只是一个字符串。

因此,发送任何参数(高度),您需要 configureCell 方法知道能够构建单元格,并在该方法中进行所有构建以及 cellForRowAtIndex 中的所有更新

希望它有意义:)

The above reuses the cells, as you draw attention to in your comments, but; after finding a cached cell you do the setup again, not matter if the cell is old or new.

The UITableViewCell is a "two-parter", the first time a cell is referenced it is instantiated and build, all the subsequent times it is referenced it should only be updated. (a cell is referenced each time it is scrolled onto the screen or the tableview is reloaded etc. this happens often so to save CPU time it is also best not to do the same setup again and again).

So, try approaching it like this instead:

- (void) configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {

    UILabel *settingText = [ISInterfaceElement getLabel:Headline]; //Opps... ISInterfaceElement is my custom class. All it does is return a UILabel with settings that comply for a Headline label, according to an enum in the header.
    [settingText setFrame:CGRectMake(0.0f, 15.0f, 320.0f, 20.0f)];
    [settingText setTextAlignment:UITextAlignmentCenter];
    [settingText setTag:SETTINGS_LABEL];
[cell addSubview:settingText];
    UIView *background = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 50.0f)];
    [cell addSubView:background]; //added
    [background release]; //added

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];     
}

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

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


    [(UILabel*)[cell viewWithTag:SETTINGS_LABEL] setText:@"Settings…"];

    return cell;
}

So the cellForRowAtIndexPath call the configureCell method if it needs a new cell setup, else it simply
updates the cell with the correct value from the model (usually [someArray objectAtIndex:indexPath.row] but in my case just a string.

So send along any parameter(height) you need the configureCell method to know to be able to build your cell, and do all the building in that method and all the updating in cellForRowAtIndex.

Hope it makes sense:)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文