【问题标题】:Interface Builder (iPhone dev) custom button background Image does not respect Stretching settingsInterface Builder(iPhone dev)自定义按钮背景图像不尊重拉伸设置
【发布时间】:2025-12-28 09:30:06
【问题描述】:

我正在尝试使用 Interface Builder 中的背景图像创建自定义按钮。图像具有可拉伸和不可拉伸的部分,因此可以调整其大小。

IB 公开了 Stretching 属性以允许这样做,但我输入的任何值都不会影响按钮的显示方式。它总是被完全拉伸以填充框架的大小。

这是 IB 或 UIButton 中不支持的功能吗?

http://img.skitch.com/20100103-rjabkq2c2jkqynw47crxepdtwb.jpg

(注意:上面的拉伸值并不是正确处理图像的值,而只是我在截屏时弄乱的值)

【问题讨论】:

  • 来自 UICatalog 的相同示例文件存在相同问题。任何进展?你必须在代码中设置它吗?

标签: iphone xcode uikit interface-builder uibutton


【解决方案1】:

使用 Xcode 切片功能来指定图像可调整大小的中心区域的尺寸,并可选择指定端盖,即不应被可调整大小的区域填充的图像区域。 见About Asset Catalogs

【讨论】:

    【解决方案2】:

    按钮的背景图像将始终调整大小以填充框架;前景图像不会调整大小(如果没有文本,则居中)。拉伸的逻辑是在保持边界不变的情况下调整中间的大小;例如,对于圆角矩形,这意味着圆角不会变形。

    【讨论】:

      【解决方案3】:

      我已经成功了!!!对我来说魔法值是 0.2 和 0.2。

      我的图像是一个盒子里的盒子,都有圆角。

      当它是0.2和0.8时,它使图像的顶部不被拉伸,但底部被拉伸和扭曲。

      我猜,第一个 0.2 是偏移量,意思是不拉伸多少,第二个可能是拉伸多少。至少,0.2 和 0.6 也可以。

      原则上,您可以做一个实验:获取格子或同心圆或颜色渐变的图像并拉伸它。如果你这样做,请张贴图片:)。

      【讨论】:

        【解决方案4】:

        如果您想要拉伸多个像素(即按钮中心的图案),可拉伸的 UIImage 将不起作用。

        UIButton 的 contentStretch 也不能正常工作。

        我是如何解决的:我将 UIButton 子类化并添加了一个 UIImageView *backgroundImageView 作为属性,并将其作为 UIButton 中的子视图放置在索引 0 处。然后我在 layoutSubviews 中确保它完全适合按钮并设置 imageView 的突出显示状态。您需要做的就是移交一个应用了正确 contentStretch 和 contentMode 的 UIImageView。

        .h 文件

        @interface ButtonWithBackgroundImage : UIButton {
            UIImageView *backgroundImageView;
        }
        @property (retain) UIImageView *backgroundImageView;
        + (ButtonWithBackgroundImage*)button;
        @end
        

        .m 文件

        @implementation ButtonWithBackgroundImage
        @synthesize backgroundImageView;
        
        + (ButtonWithBackgroundImage*)button {
        return [self buttonWithType:UIButtonTypeCustom];
        }
        - (void)setBackgroundImageView:(UIImageView*)img {
            [backgroundImageView removeFromSuperview];
            [backgroundImageView release];
        
            backgroundImageView = [img retain];
        
            if(backgroundImageView){
                [self insertSubview:backgroundImageView atIndex:0];
                [self setNeedsLayout];
            }
        }
        
        - (void)setSelected:(BOOL)select {
            [super setSelected:select];
            // we subclass the setSelect method to highlight the background imageview
        [backgroundImageView setHighlighted:select||self.highlighted];
        }
        - (void)setHighlighted:(BOOL)highl {
            [super setHighlighted:highl];
        
            // we subclass the setHighlighted method to highlight the background imageview    
            [backgroundImageView setHighlighted:highl||self.selected];
        }
        
        - (void)layoutSubviews {
            [super layoutSubviews];
        
            self.backgroundImageView.frame = self.bounds;
        }
        
        - (void)dealloc {
            [backgroundImageView release];
            backgroundImageView = nil;
            [super dealloc];
        }
        @end
        

        【讨论】:

          【解决方案5】:

          Beginning iPhone 3 Development 中的示例中,仅使用了 UIImage leftCapWidthtopCapHeight,并以编程方式创建/设置图像,因此,如果 contentStretch 不起作用,这是另一种方法。

          【讨论】:

          • 似乎这似乎不起作用。文档谈论这些值完全符合我的要求(整个按钮图像拉伸)。必须以编程方式使按钮看起来正确有点奇怪,因为我们有一个完整的 GUI 制作 GUI...又名 IB。
          • 查看 contentStretch 的文档,IB 显示的默认值(特别是 0.50 的)不是 h/w 0,0 和大小 1,1 的实际默认值,所以我想这不是太令人惊讶的是 IB 中的设置不起作用。看起来 contentStretch 是在 3.0 中添加的,所以这可能与它有关。 bugreport.apple.com
          • 我不关注。我没有使用默认值。正如我所说,我在那里输入的任何值都没有任何影响。屏幕截图中显示的不是默认值。我在 3.0 下运行。
          • 这里遇到了同样的问题。到目前为止,总是在代码中做到这一点,但希望它也能在 IB 中工作......为我保存代码一个 IBOutlets。
          • 如果你们中的任何人/所有人都希望看到此修复或更好的文档,请考虑提交错误(或至少重复 rdar://7706446)。 bugreporter.apple.com