答案 0 :(得分:13)
您可以使用UIImage
方法.resizableImageWithCapInsets(_:UIEdgeInsets, resizingMode: UIImageResizingMode)
来设置拉伸细节。
<强>声明强>
func resizableImageWithCapInsets(capInsets: UIEdgeInsets, resizingMode: UIImageResizingMode) -> UIImage
<强>描述强>
创建并返回具有指定cap insets的新图像对象 和选项。
具有指定封面插入和调整大小模式的新图像对象。
参数
capInsets
:用于上限插入的值。
resizingMode
:图像内部的模式 调整大小。
作为一个例子,让我们尝试---以编程方式 - 沿着它的宽度拉伸我的(当前)轮廓图片,精确地在我的右腿(从观察角度看左侧),并留下图像的其余部分原始比例。这可以与将某些按钮纹理的宽度拉伸到其内容大小相当。
首先,让我们将原始图片foo.png
加载为UIImage
对象:
let foo = UIImage(named: "foo.png") // 328 x 328
现在,使用.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)
生成的视图按指定的方式拉伸原始图像,产生不成比例的长腿。
现在,只要图像的框架具有1:1
width:height
比例(328:328
),拉伸就会变得均匀,好像只是将任何图像拟合到更小/更大的框架。对于width
值大于height
(a:1
,比率a>1
)的任何一帧,该分段将开始不成比例地延伸。
X
,width
,Y
和height
拉伸属性最后,为了彻底回答你的问题(我们之前只是隐含地做了),我们可以利用X
,width
,Y
的详细解释和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)
产生以下拉伸图像:
扩展显然允许更加多样化地使用帽子插入拉伸(与使用Interface Builder相比的多功能性),但请注意,扩展,以其当前形式,不包括任何用户输入验证,因此它取决于调用者在正确的范围内使用参数。
最后,关于图像及其坐标的任何操作的相关注释:
注意:图像坐标轴
x
(宽度)和y
(高度)运行x (width): left to right (as expected) y (height): top to bottom (don't miss this!)