【问题标题】:UIButton doesn't listen to content mode setting?UIButton 不听内容模式设置?
【发布时间】:2011-02-26 09:28:54
【问题描述】:

firstButton 是自定义类型的 UIButton。我以编程方式将其中三个放在表格的每个单元格中,因此:

[firstButton setImage:markImage forState:UIControlStateNormal];
[firstButton setContentMode:UIViewContentModeScaleAspectFit];
[cell.contentView addSubview:firstButton];

在其他地方,我告诉它clipToBounds。我得到的是图像中心正方形的裁剪,而不是它的纵横比渲染。我已经尝试了很多方法,包括在 firstButton.imageView 上设置 mode 属性,这似乎也不起作用。

【问题讨论】:

  • 查看下面 Chris Nolet 的解决方案:button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
  • 参见stackoverflow.com/a/28205566/481207,这表明 UIViewContentModeScaleAspectFit 需要同时设置 contentVerticalAlignment 和 contentHorizo​​ntalAlignment。

标签: ios uibutton contentmode


【解决方案1】:

我遇到了同样的问题。我看到这个问题有点老了,但我想提供一个清晰而正确的答案,以便在其他人(比如我)在搜索结果中弹出时节省一些时间。

我花了一些时间搜索和试验,但我找到了解决方案。只需设置 UIButton 内的“隐藏”ImageView 的 ContentMode。

[[firstButton imageView] setContentMode: UIViewContentModeScaleAspectFit];
[firstButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];

也许这就是 Dan Ray 在他接受的答案中所暗示的,但我怀疑不是。

【讨论】:

  • 不,不是。我确定的解决方案是使用 UIImageView 来保存图像,然后在其顶部使用一个清晰​​、透明的“自定义”类型的 UIButton。
  • 戴夫,至少在 iOS 3.2 上,您的解决方案似乎对我不起作用。太糟糕了,因为我希望在点击“免费”时突出显示图像。我什至在我设置 contentMode 的地方确保 button.imageView 不为零,并在设置 contentMode 后设置图像,就像你正在做的那样。
  • 澄清一下,“不起作用”是指“图像以全分辨率显示,而不是像我希望的那样缩小”。
  • Jacques,以上内容在 iOS 4.x 中适用于我。不幸的是,在使用 v3.2 目标构建时,我可以重现“不会调整大小”的问题。我尝试更改 UIButton 视图的框架大小,但这似乎也无济于事。呃。
  • 查看下面 Chris Nolet 的解决方案:button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
【解决方案2】:

如果您正在处理 UIButton 的图像(而不是 backgroundImage),则在 UIButton 本身或其 imageView 上设置 contentMode 无效(尽管其他答案说)。

也可以这样做:

self.button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
self.button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;

或相应地调整您的图像大小。

或者只使用一个 UIImageView(它正确地尊重 contentMode),并附加一个 UITapGestureRecognizer,或者在它上面加上一个透明的 UIButton。

【讨论】:

  • 这适用于我在 iOS 7 中的情况,而这里的所有其他情况都没有。
  • 设置 contentHorizo​​ntalAlignment 和 contentVerticalAlignment 是正确的解决方案。有关说明,请参阅 stackoverflow.com/a/28205566/481207
  • 这是我一直在寻找的答案。
  • 这个答案不正确。您确实需要在imageView 上设置contentMode,如果您想进行任何类型的方面填充或拟合,正如其他答案所阐明的那样。参考:stackoverflow.com/a/7944316/746890.
【解决方案3】:

您需要设置contentHorizontalAlignmentcontentVerticalAlignment 属性,而不是设置按钮本身的contentMode,并且(至关重要)设置contentMode 用于按钮的imageView 用于任何类型的方面填充或合身。这是一个例子:

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
button.imageView.contentMode = UIViewContentModeScaleAspectFit;

当然,您还可以执行其他操作,例如将按钮的图像与按钮顶部对齐。如果您不需要方面填充或适合,您可以自行设置对齐方式:

button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;

在 Swift 中,您需要使用:

button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.imageView?.contentMode = .scaleAspectFit

这适用于所有版本的 iOS,包括具有自动布局的最新版本(即 iOS 4 到 iOS 11+)。

【讨论】:

  • 感谢 Chris - 这解决了我的问题,或者更确切地说,它与 contentEdgeInsets 结合使用,以便让我的图像稍微偏离顶部边缘。
【解决方案4】:

经过几个小时的困惑,下面是我如何让它在 iOS 3.2 下工作。正如黄昏者所提到的,使用 setBackgroundImage 而不是 setImage 为我完成了这项工作。

CGRect myButtonFrame = CGRectMake(0, 0, 250, 250);
UIImage *myButtonImage = [UIImage imageNamed:@"buttonImage"];

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];

[myButton setBackgroundImage:myButtonImage forState:UIControlStateNormal];
[myButton setFrame: myButtonFrame];
[myButton setContentMode: UIViewContentModeScaleAspectFit];

【讨论】:

    【解决方案5】:

    答案是使用 UIImageView 和你想要的所有可爱的内容模式设置,然后在它上面放置一个自定义按钮。愚蠢的是你不能一口气做到这一点,但似乎你不能。

    【讨论】:

      【解决方案6】:

      这两件事(最初很难找到)会拉伸你的 UIButton 图像以适应按钮大小:

      应该始终尝试在情节提要而不是代码中进行设置。

      【讨论】:

      • 你是我的英雄!
      【解决方案7】:

      找到了解决此问题的方法。将UIButtonadjustsImageWhenHighlighted属性设置为NO

        UIButton *b = [[UIButton alloc] initWithFrame:rect];
              [b setImage:image forState:UIControlStateNormal];
              [b.imageView setContentMode:UIViewContentModeScaleAspectFill];
              [b setAdjustsImageWhenHighlighted:NO];
      

      希望这会有所帮助。欢迎在下方发表评论,我会跟进您的任何问题。

      【讨论】:

      • 这是完美的解决方案。
      • 不起作用。这只会阻止按钮突出显示。
      【解决方案8】:

      我的回答与 Kuba 的类似。我需要以编程方式设置我的图像。

      UIImage *image = [[UIImage alloc] initWithContentsOfFile:...];
      [button setBackgroundImage:image forState:UIControlStateNormal];
      button.imageView.contentMode = UIViewContentModeScaleAspectFill; //this is needed for some reason, won't work without it.
      for(UIView *view in button.subviews) {
          view.contentMode = UIViewContentModeScaleAspectFill;
      }
      

      【讨论】:

        【解决方案9】:

        唯一对我有用的解决方案:

        [button setImage:image forState:UIControlStateNormal];
        button.imageView.contentMode = UIViewContentModeScaleAspectFill;
        button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
        button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
        

        【讨论】:

          【解决方案10】:

          斯威夫特 3

          self.firstButton.imageView?.contentMode = .scaleAspectFill
          

          【讨论】:

            【解决方案11】:

            用 setBackgroundImage 代替 setImage

            【讨论】:

            • 嗯。 A,这很愚蠢,它应该尊重其内容的内容模式设置,对吧? B,它似乎仍然不尊重模式设置——它现在被锁定为“拉伸”(在这种情况下,更像是“挤压”),并且没有相对于其方面缩放内容比率。
            【解决方案12】:

            我相信我们这里有一个简单的界面构建器问题 - 显然,在您设置图像属性之后,IB 会忽略任何内容模式更改。

            解决方案很简单:设置内容模式,删除之前设置的图像名称(确保在所有状态下删除它,默认,突出显示等),然后在所有需要的状态下重新输入所需的图像名称- 等等。

            【讨论】:

            • 以编程方式设置内容模式也是如此——在设置内容模式之前不要设置图像
            【解决方案13】:

            对于在 iOS 15 和 Xcode 13 上遇到此问题的任何人,请参阅 Matt's answer in this other question

            Xcode 的行为发生了变化,现在将库中的 UIButtons 默认为 plain 样式,这会阻止子图像按预期缩放。

            【讨论】:

              【解决方案14】:

              我还建议查看adjustsImageWhenHighlighted UIButton 属性,以避免在按下按钮时出现奇怪的图像变形。

              【讨论】:

                【解决方案15】:

                为了解决这个问题,随着时间的推移,我的方法变得有点老套了,我最终继承了 UIButton 并覆盖了 setHighlighted:

                对我来说,只需将图像 alpha 降低到 0.5,因为它们位于黑色背景上。

                但是,它只有在我注释掉 [super setHighlighted:] 时才有效(出现图像拉伸代码的地方),这根本不是解决这个问题的正确方法......一切不过,似乎工作正常。在我继续努力的过程中,我们会看看它的表现如何。

                - (void)setHighlighted:(BOOL)highlight {
                    if (highlight) {
                        [self.imageView setAlpha:.5];
                    }  else {
                        [self.imageView setAlpha:1];        
                    }
                
                //    [super setHighlighted:highlight];
                }
                

                【讨论】:

                • 万一有人发现这很相关,我的上述方法似乎可以正常工作,直到我将按钮放在 UIScrollView 上,有时按钮的突出显示“卡住”,这是我怀疑可能最终会发生。
                【解决方案16】:

                如果有人正在寻找适用于 iOS 6 和 iOS 7 以及情节提要的答案:

                您可以在情节提要中设置图像:

                然后:

                for(UIView* testId in self.subviews) {
                    if([testId isKindOfClass:[UIImageView class]])
                        [testId setContentMode:UIViewContentModeScaleAspectFill];
                }
                

                【讨论】:

                  【解决方案17】:

                  如果 UIButton 似乎不听布局约束设置,请检查图像是否大于按钮大小。始终将@2x 和@3x 图像用于视网膜分辨率。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2014-01-21
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-02-14
                    • 1970-01-01
                    • 2018-03-06
                    相关资源
                    最近更新 更多