在swift for iOS中以编程方式设置图像的拉伸参数

时间:2016-02-24 16:28:04

标签: ios xcode swift

因此,如果我们只想拉伸图像的某些部分,无论是常规图像还是背景图像,我们都会在布局编辑器中使用以下设置:

enter image description here

如何以编程方式设置?

我正在使用Xcode 7.2.1

1 个答案:

答案 0 :(得分:13)

指定图像的上限隐藏

您可以使用UIImage方法.resizableImageWithCapInsets(_:UIEdgeInsets, resizingMode: UIImageResizingMode)来设置拉伸细节。

  

<强>声明

func resizableImageWithCapInsets(capInsets: UIEdgeInsets, resizingMode: UIImageResizingMode) -> UIImage
     

<强>描述

     

创建并返回具有指定cap insets的新图像对象   和选项。

     

具有指定封面插入和调整大小模式的新图像对象。

     

参数

     

capInsets:用于上限插入的值。

     

resizingMode:图像内部的模式   调整大小。

示例:使用指定的cap insets自定义拉伸

作为一个例子,让我们尝试---以编程方式 - 沿着它的宽度拉伸我的(当前)轮廓图片,精确地在我的右腿(从观察角度看左侧),并留下图像的其余部分原始比例。这可以与将某些按钮纹理的宽度拉伸到其内容大小相当。

首先,让我们将原始图片foo.png加载为UIImage对象:

let foo = UIImage(named: "foo.png") // 328 x 328

enter image description here

现在,使用.resizableImageWithCapInsets(_:UIEdgeInsets, resizingMode: UIImageResizingMode),我们将定义另一个UIImage实例,使用指定的cap insets(到我的右腿中间),并将resizing模式设置为.Stretch:< / p>

/* middle of right leg at ~ |-> 0.48: LEG :0.52 <-| along 
   image width (for width normalized to 1.0)                */
let fooWidth = foo?.size.width ?? 0
let leftCapInset = 0.48*fooWidth
let rightCapInset = fooWidth-leftCapInset // = 0.52*fooWidth

let bar = UIEdgeInsets(top: 0, left: leftCapInset, bottom: 0, right: rightCapInset)
let fooWithInsets = foo?.resizableImageWithCapInsets(bar, resizingMode: .Stretch) ?? UIImage()

请注意,上面的0.48字面值对应于您在界面构建器中为X输入的值,如上面问题中的图像所示(或如in detail in the link provided by matt所述)。< / p>

继续前进,我们最终将带有图片插图的图像放在UIImageView中,并让此图像视图的宽度大于图像的宽度

/* put 'fooWithInsets' in an imageView.
   as per default, frame will cover 'foo.png' size */
let imageView = UIImageView(image: fooWithInsets)

/* expand frame width, 328 -> 600 */
imageView.frame = CGRect(x: 0, y: 0, width: 600, height: 328)

生成的视图按指定的方式拉伸原始图像,产生不成比例的长腿。

enter image description here

现在,只要图像的框架具有1:1 width:height比例(328:328),拉伸就会变得均匀,好像只是将任何图像拟合到更小/更大的框架。对于width值大于heighta:1,比率a>1)的任何一帧,该分段将开始不成比例地延伸。

扩展程序,以匹配界面生成器中的XwidthYheight拉伸属性

最后,为了彻底回答你的问题(我们之前只是隐含地做了),我们可以利用XwidthY的详细解释和height接口生成器在the link provided by matt中展开属性,使用(显然)相同的属性构建我们自己的UIImage扩展名,转换为扩展名中的cap insets:

extension UIImage {
    func resizableImageWithStretchingProperties(
    X X: CGFloat, width widthProportion: CGFloat,
    Y: CGFloat, height heightProportion: CGFloat) -> UIImage {

        let selfWidth = self.size.width
        let selfHeight = self.size.height

        // insets along width
        let leftCapInset = X*selfWidth*(1-widthProportion)
        let rightCapInset = (1-X)*selfWidth*(1-widthProportion)

        // insets along height
        let topCapInset = Y*selfHeight*(1-heightProportion)
        let bottomCapInset = (1-Y)*selfHeight*(1-heightProportion)

        return self.resizableImageWithCapInsets(
            UIEdgeInsets(top: topCapInset, left: leftCapInset,
                bottom: bottomCapInset, right: rightCapInset),
            resizingMode: .Stretch)
    }
}

使用此扩展程序,我们可以实现与上述foo.png相同的水平拉伸,如下所示:

let foo = UIImage(named: "foo.png") // 328 x 328
let fooWithInsets = foo?.resizableImageWithStretchingProperties(
    X: 0.48, width: 0, Y: 0, height: 0) ?? UIImage()

let imageView = UIImageView(image: fooWithInsets)
imageView.frame = CGRect(x: 0, y: 0, width: 600, height: 328)

扩展我们的示例:拉伸宽度和高度

现在,我们想要伸展我的右腿(沿着宽度),但另外还有我的手和左腿沿着图像的高度。我们通过使用上面扩展中的Y属性来控制它:

let foo = UIImage(named: "foo.png") // 328 x 328
let fooWithInsets = foo?.resizableImageWithStretchingProperties(
    X: 0.48, width: 0, Y: 0.45, height: 0) ?? UIImage()

let imageView = UIImageView(image: fooWithInsets)
imageView.frame = CGRect(x: 0, y: 0, width: 500, height: 500)

产生以下拉伸图像:

enter image description here

扩展显然允许更加多样化地使用帽子插入拉伸(与使用Interface Builder相比的多功能性),但请注意,扩展,以其当前形式,不包括任何用户输入验证,因此它取决于调用者在正确的范围内使用参数。

最后,关于图像及其坐标的任何操作的相关注释:

  

注意:图像坐标轴x(宽度)和y(高度)运行

x (width):  left to right (as expected)
y (height): top to bottom (don't miss this!)