【问题标题】:How to Make Case Override Previous Case如何使案例覆盖以前的案例
【发布时间】:2014-03-26 07:59:44
【问题描述】:

我有许多案例,每个案例都会生成不同的图像。问题是,图像在生成后似乎会堆叠。如何设置每个案例以覆盖以前的图像?

- (void)setTileValue:(NSInteger)tileValue {
  _tileValue = tileValue;
  self.numberLabel.text = [@(tileValue) stringValue];
    UIImageView *backgroundView = [self backgroundView:[@(tileValue) intValue]];
    [self.numberLabel addSubview:backgroundView];
  self.value = tileValue;
}


- (UIImageView *)backgroundView:(NSUInteger)value {
    switch (value) {
        case 1:
            return [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background"]]; // light gray
        case 2:
            return [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background1"]]; // gray
        case 4:
            return [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background2"]]; // gark gray
        case 8:
            return [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background3"]]; // red
        case 16:
            return [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background4"]]; // orange
        default:
            return [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background"]];
    }
}

更新的代码:所以程序每次都使用 initWithImage 创建一个新图像。我现在将返回设置为只返回 UIImage。为什么这段代码也不能解决问题?

- (void)setTileValue:(NSInteger)tileValue {
  _tileValue = tileValue;
  self.numberLabel.text = [@(tileValue) stringValue];
//    UIImageView *backgroundView = [self backgroundView:[@(tileValue) intValue]];
    UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[self tileBG:[@(tileValue) intValue]]];    [self.numberLabel addSubview:backgroundView];
    self.numberLabel.backgroundColor = [self tileColorForValue:[@(tileValue) intValue]];
    self.backgroundColor = [self tileColorForValue:[@(tileValue) intValue]];
    self.numberLabel.textColor = [self numberColorForValue:[@(tileValue) intValue]];
  self.value = tileValue;
}

- (UIColor *)defaultBackgroundColor {
  return [UIColor lightGrayColor];
}

- (UIColor *)defaultNumberColor {
  return [UIColor colorWithWhite:0.0 alpha:0.0];
}

- (UIImage *)tileBG:(NSUInteger)value {
    switch (value) {
        case 1:
            return [UIImage imageNamed:@"background"]; // light gray
        case 2:
            return [UIImage imageNamed:@"background1"]; // gray
        case 4:
            return [UIImage imageNamed:@"background2"]; // gark gray
        case 8:
            return [UIImage imageNamed:@"background3"]; // red
        case 16:
            return [UIImage imageNamed:@"background4"]; // red
        case 32:
            return [UIImage imageNamed:@"background5"]; // red

        default:
            return [UIImage imageNamed:@"background"]; // red
    }
}

【问题讨论】:

  • 只需返回一个 UIImage 而不是 UIImageView 并将返回的图像设置为 UIImageView 的 .image 属性。旁注:它会堆积起来,因为您每次都返回 UIImageView。不应该那样做。
  • 谢谢。我现在将 return 设置为返回 UIImage。这个问题似乎仍然存在。
  • 问题出在 setTitleValue 方法中。每当调用此代码时,您都在添加 UIImageView。为什么不为 UIImageView 保留一个属性,而不是在每次调用 setTitle 时添加它?
  • 哦,我明白了。如何为 UIImageView 创建单独的属性?
  • 或者在 setTileView 中添加另一个图像之前删除上一个图像会更简单吗?

标签: ios objective-c switch-statement


【解决方案1】:

您每次都创建一个新的图像视图并添加它。最终,这可能会导致您的应用程序由于内存使用而崩溃(大量的图像视图可能是昂贵的)。

创建一次图像视图,并相应地设置其图像(只需从您的 switch 语句中返回一个图像),或者在添加新的图像视图之前删除之前的图像视图。

您需要在某处保留对图像视图的引用,理想情况下是任何类的属性。然后,只需设置其图像属性。不要在这里创建新的图像视图,也不要添加任何子视图。图像视图应该在您的 init 方法中创建一次。

【讨论】:

  • 谢谢。关于这些选项中哪个最有效的建议?
  • 第一个,肯定的。我假设背景的大小都一样?
  • 背景大小略有不同,这就是为什么第一个背景可以在第二个后面部分可见的原因。
  • 我不是最擅长创建高效代码的人。实施第一个选项的最佳方法是什么?
  • 您可能需要在设置每个图像时调整框架,然后使用 sizeToFit 或类似方法。或者它可能只是工作,图像视图经常超出其界限。
【解决方案2】:

请阅读我上面的 cmets。然后修改你的setTitleCode 看起来像这样。

- (void)setTileValue:(NSInteger)tileValue
{
  _tileValue = tileValue;
  self.numberLabel.text = [@(tileValue) stringValue];
  UIImageView *backgroundView = (UIImageView *)[self.numberLabel viewWithTag:1000]; // edited code to avoid warning
  if (!backgroundView)
  {
    backgroundView  = [[UIImageView alloc] initWithImage:[self tileBG:[@(tileValue) intValue]]];
    backgroundView.tag = 1000;
    [self.numberLabel addSubview:backgroundView];
  }

  backgroundView.image = [self tileBG:[@(tileValue) intValue]];
  self.numberLabel.backgroundColor = [self tileColorForValue:[@(tileValue) intValue]];
  self.backgroundColor = [self tileColorForValue:[@(tileValue) intValue]];
  self.numberLabel.textColor = [self numberColorForValue:[@(tileValue) intValue]];
  self.value = tileValue;
}

【讨论】:

  • 非常感谢!这行得通。您介意快速解释一下为什么要添加 viewWithTag 吗?它有什么作用? (对不起,我还在学习)
  • 顺便说一句,有一个警告incompatible pointer types initializing 'UIImageView *' with an expression of type 'UIView *'
  • tag 只是 UIView 中的一个属性。您可以使用此值来查找嵌入在超级视图中的视图。由于您没有 UIImageView 的单独属性,因此您没有其他方法可以找到您创建的上一个 uiimageview。因此,您可以使用此标签值来定位它并设置图像。 (编辑代码以避免警告。)
  • 这是因为每次调用setTileValue: 方法时,您都在执行[self.numberLabel addSubview:backgroundView],因为您不断向标签中添加越来越多的子视图。
  • 谢谢。是否有理由将 viewwithtag 设置为 1000?
【解决方案3】:

如果您的意思是在切换后它会创建多个图像,那么请尝试使用一个

break();

但是安全的做法是创建一个 imageView 并初始化它,然后在 switch 语句中设置它的图像,这样即使它被放置多个,它也会保留最后一个引用。

【讨论】:

  • 中断无关紧要,因为代码在每种情况下都返回。它是break;。问题与switch语句无关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-01
  • 2018-04-04
  • 1970-01-01
  • 2011-08-15
  • 2012-03-17
  • 1970-01-01
相关资源
最近更新 更多