[英]UIImageView added as subview in an UIView with clipsToBounds is not working
I have a UIView with a UIImageView as subview added, the UIImageView is a texture that repeats.我有一个 UIView,其中添加了 UIImageView 作为子视图, UIImageView 是重复的纹理。 The UIView width and height are correct, but the image is out of the size. UIView 的宽度和高度是正确的,但是图像超出了尺寸。 I added the ClipsToBounds, but it's not clipping the image at all.我添加了 ClipsToBounds,但它根本没有剪裁图像。 Is there a specific order or what am I doing wrong the image is not clipped inside it's parent view?是否有特定的顺序或者我做错了什么,图像没有被剪辑在它的父视图中?
let rectangleView = UIView(frame: CGRect(x: x, y: y, width: width, height: height))
rectangleView.isUserInteractionEnabled = false
if let texturesUrl = layout.Url, let url = texturesUrl.isValidURL() ? URL(string: texturesUrl) : URL(string: String(format: AppManager.shared.baseTexturesUrl, texturesUrl)) {
let widthLimit = scale * CGFloat(layout.Width ?? 0)
let heightLimit = scale * CGFloat(layout.Height ?? 0)
let widthStep = scale * CGFloat(layout.TileWidth ?? layout.Width ?? 0)
let heightStep = scale * CGFloat(layout.TileHeight ?? layout.Height ?? 0)
var locY = CGFloat(0)
let size = CGSize(width: widthStep, height: heightStep)
if widthLimit > 0, heightLimit > 0 {
while locY < heightLimit {
var locX = CGFloat(0)
while locX < widthLimit {
let imageView = UIImageView()
rectangleView.addSubview(imageView)
imageView.contentMode = .scaleAspectFill
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.clipsToBounds = true
imageView.isUserInteractionEnabled = false
imageView.anchor(top: rectangleView.topAnchor, leading: rectangleView.leadingAnchor, bottom: nil, trailing: nil, padding: UIEdgeInsets(top: locY, left: locX, bottom: 0, right: 0), size: size)
imageView.setImage(with: url, size: size)
locX += widthStep
}
locY += heightStep
}
}
}
You don't need to add so many image views, just use it as a repeating background:你不需要添加这么多的图像视图,只需将其用作重复背景即可:
rectangleView.backgroundColor = UIColor(patternImage: myImage)
See documentation for UIColor(patternImage:) .请参阅UIColor(patternImage:)的文档。
You can do this much more efficiently with CAReplicatorLayer
.您可以使用CAReplicatorLayer
更有效地做到这一点。
Here's a quick example:这是一个简单的例子:
class TileExampleViewController: UIViewController {
let tiledView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
tiledView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tiledView)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
tiledView.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
tiledView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
tiledView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
tiledView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -20.0),
])
}
override func viewDidLayoutSubviews() {
// we want to do this here, when we know the
// size / frame of the tiledView
// make sure we can load the image
guard let tileImage = UIImage(named: "tileSquare") else { return }
// let's just pick 80 x 80 for the tile size
let tileSize: CGSize = CGSize(width: 80.0, height: 80.0)
// create a "horizontal" replicator layer
let hReplicatorLayer = CAReplicatorLayer()
hReplicatorLayer.frame.size = tiledView.frame.size
hReplicatorLayer.masksToBounds = true
// create a "vertical" replicator layer
let vReplicatorLayer = CAReplicatorLayer()
vReplicatorLayer.frame.size = tiledView.frame.size
vReplicatorLayer.masksToBounds = true
// create a layer to hold the image
let imageLayer = CALayer()
imageLayer.contents = tileImage.cgImage
imageLayer.frame.size = tileSize
// add the imageLayer to the horizontal replicator layer
hReplicatorLayer.addSublayer(imageLayer)
// add the horizontal replicator layer to the vertical replicator layer
vReplicatorLayer.addSublayer(hReplicatorLayer)
// how many "tiles" do we need to fill the width
let hCount = tiledView.frame.width / tileSize.width
hReplicatorLayer.instanceCount = Int(ceil(hCount))
// Shift each image instance right by tileSize width
hReplicatorLayer.instanceTransform = CATransform3DMakeTranslation(
tileSize.width, 0, 0
)
// how many "rows" do we need to fill the height
let vCount = tiledView.frame.height / tileSize.height
vReplicatorLayer.instanceCount = Int(ceil(vCount))
// shift each "row" down by tileSize height
vReplicatorLayer.instanceTransform = CATransform3DMakeTranslation(
0, tileSize.height, 0
)
// add the vertical replicator layer as a sublayer
tiledView.layer.addSublayer(vReplicatorLayer)
}
}
I used this tile image:我使用了这个平铺图像:
and we get this result with let tileSize: CGSize = CGSize(width: 80.0, height: 80.0)
:我们通过let tileSize: CGSize = CGSize(width: 80.0, height: 80.0)
得到这个结果:
with let tileSize: CGSize = CGSize(width: 120.0, height: 160.0)
: let tileSize: CGSize = CGSize(width: 120.0, height: 160.0)
:
with let tileSize: CGSize = CGSize(width: 40.0, height: 40.0)
: let tileSize: CGSize = CGSize(width: 40.0, height: 40.0)
:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.