在Xcode故事板中使用可伸缩的图像

时间:2012-08-01 18:43:43

标签: iphone ios xcode cocoa-touch uistoryboard

我正在使用故事板来布置我的视图控制器,我想为我的按钮使用可伸缩的图像(这样我就不需要生成不同大小的多个图像)。

这可以在没有编写任何代码的情况下直接在故事板中进行吗?我真的很喜欢将故事板用于所有图形内容的可能性,并保持代码清洁UI的东西,但似乎我无法在这里摆脱它。

如果不可能,你会建议别的什么?

5 个答案:

答案 0 :(得分:73)

iOS 7 +更新
iOS 7+现在通过资产目录本地支持可伸缩图像。使用资产目录,您现在可以指定图像的切片方式以及图像的缩放方式(拉伸或平铺)。图像的这些资产目录属性将立即反映在故事板中。伟大的新改进。有关详细信息,请参阅Apple's docs on the Asset Catalog

在7之前部署到iOS版本:
这是一个鲜为人知的事实,但您只能使用Interface Builder / Storyboard和属性检查器中的拉伸属性来设置图像的上限。感谢Victor原来的答案。

查看UIImage的属性检查器中的拉伸属性,X和Y值是拉伸起始点相对于图像的整个宽度和高度的位置。值0.5表示图像中间的一个点。

宽度和高度是可伸展区域相对于图像大小的大小。因此,将宽度设置为1 / imageWidth的值会将可伸展区域设置为1px宽。

大多数可伸缩图像将从中间伸展,因此将这些值用于X,Y,Width和&高度通常会起作用:

X = 0.5
Y = 0.5
Width = 1/imageWidth
Height = 1/imageHeight

注意:除非您正在拉伸非常小的图像,否则这意味着宽度和高度属性将非常小(例如0.008),并且可以使用0.0。因此,实际上,0.5,0.5,0.0,0.0几乎总是适用于X,Y,Width&高度。

在少数情况下,0.0不适用于宽度和高度,这意味着您需要使用计算器在IB中设置这些值。但是,我认为这通常比必须以编程方式设置它更可取,因为您将能够在IB(WYSIWYG)中看到生成的拉伸图像。

Stretchable image attributes

更新:有些人指出,尽管使用上述建议在Storyboard中拉伸图像仍然有效,但是在按钮上拉伸图像仍然会被破坏,即使是iOS7也是如此。不用担心,通过创建UIButton类别可以轻松解决这个问题,该类别负责为控件状态设置上限内容:

@implementation UIButton (Stretchable)

/* Automatically set cap insets for the background image. This assumes that
   the image is a standard slice size with a 1 px stretchable interior */
- (void)setBackgroundImageStretchableForState:(UIControlState)controlState
{
    UIImage *image = [self backgroundImageForState:controlState];
    if (image)
    {
       CGFloat capWidth =  floorf(image.size.width / 2);
       CGFloat capHeight =  floorf(image.size.height / 2);
       UIImage *capImage = [image resizableImageWithCapInsets:
                     UIEdgeInsetsMake(capHeight, capWidth, capHeight, capWidth)];

       [self setBackgroundImage:capImage forState:controlState];
    }
}

使用此类别,您可以通过Storyboard为按钮设置可伸缩图像,然后通过调用-setBackgroundImageStretchableForState:中的-viewDidLoad轻松确保其伸缩。通过视图层次结构进行迭代,即使对于视图中的大量按钮,也可以轻松完成此操作:

NSPredicate *predicate = 
    [NSPredicate predicateWithFormat:@"self isKindOfClass:%@",[UIButton class]];
NSArray *buttons = [self.view.subviews filteredArrayUsingPredicate:predicate];
for (UIButton *button in buttons)
   [button setBackgroundImageStretchableForState:UIControlStateNormal];

虽然这不如拥有一个UIButton子类自动为你做的那样好(子类化UIButton因为它是一个类集群而不实用),它确实给你几乎与viewDidLoad中的一些样板代码相同的功能 - 您可以在Storyboard中设置所有按钮图像,并仍然可以使它们正确拉伸。

答案 1 :(得分:14)

使用Xcode 6(和 iOS7 + 目标),您可以在处理图像资源时使用切片编辑器。 使用编辑器切换切片模式 - >显示切片菜单或在使用编辑器选择特定图像时按显示切片按钮(如下所示)。

Show Slicing button

然后,您可以选择特定显示比例的图像并拖动规则或手动编辑插图值。

Rules

之后,您可以在 Interface Builder 中选择此图像。例如,我将它用于 UIButton 背景图像(IB按钮的表示看起来很糟糕,但运行时应该没问题。)

我的按钮看起来很好(运行iOS 7.1模拟器和iOS 8设备)。

enter image description here

此Apple文档link可能会有所帮助。

答案 2 :(得分:11)

在XCode的5.0 Interface Builder中可以使用资产目录。创建图像资源(如果您还没有资产目录,可以按如下方式创建一个:

  1. File - > New - > File - > Resources - > Asset Catalog
  2. 然后Editor - > New Image Set
  3. 为每个Idiom&设置图像。 Scale
  4. 然后点击Show Slicing按钮,根据需要设置切片。
  5. 点击此处查看Apple文档:Developer Apple: Asset Catalog Help 然后,您所要做的就是将按钮的背景图像设置为所请求的资产。

    编辑:我忘了提到它只能在iOS7中运行

答案 3 :(得分:2)

这是我做的: 我为按钮设置了一个插座并将其连接,然后在viewDidLoad中执行此操作:

[self.someButton setBackgroundImage:[[self.someButton backgroundImageForState:UIControlStateNormal] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 4, 3)] forState:UIControlStateNormal];

这使得它重新使用您在故事板中设置的图像,因此如果您将其从一种颜色更改为另一种颜色,只要插图不会改变,它就会起作用。

对于包含许多这些内容的视图,我这样做了:

for (UIView * subview in self.view.subviews) {
        if ([subview isKindOfClass:[UIImageView class]] && subview.tag == 10) {
            UIImageView* textFieldImageBackground = (UIImageView*)subview;
            textFieldImageBackground.image = [textFieldImageBackground.image stretchableImageWithLeftCapWidth:7 topCapHeight:5];
        } else if([subview isKindOfClass:[UIButton  class]] && subview.tag == 11) {
            UIButton * button = (UIButton*)subview;
            [button setBackgroundImage:[[button backgroundImageForState:UIControlStateNormal] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 4, 3)] forState:UIControlStateNormal];
        }
    }

请注意,我为所有想拉伸的标签设置了标签。

我和你在同一条船上,我希望能够在故事板上设置这些以UI为中心的东西。

答案 4 :(得分:0)

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