在stackView中调整图像大小,保持纵横比

问题描述

我想克隆 Apple Maps App UIButtons,它们看起来像这样:

screenshot Apple Maps app

这是我的代码:

 class CustomView: UIImageView {
    init(frame: CGRect,corners: CACornerMask,systemName: String) {
        super.init(frame: frame)
        self.createBorders(corners: corners)
        self.createImage(systemName: systemName)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func createBorders(corners: CACornerMask) {
        self.contentMode = .scaleAspectFill
        self.clipsToBounds = false
        self.layer.cornerRadius = 10
        self.layer.maskedCorners = corners
        self.layer.masksToBounds = false
        self.layer.shadowOffset = .zero
        self.layer.shadowColor = UIColor.gray.cgColor
        self.layer.shadowRadius = 10
        self.layer.shadowOpacity = 0.2
        self.backgroundColor = .white
        let shadowAmount: CGFloat = 2
        let rect = CGRect(x: 0,y: 2,width: self.bounds.width + shadowAmount * 0.1,height: self.bounds.height + shadowAmount * 0.1)
        self.layer.shadowPath = UIBezierPath(rect: rect).cgPath

    }
    
    func createImage(systemName: String) {
        let image = UIImage(systemName: systemName)!
//        let renderer = UIGraphicsImageRenderer(bounds: self.frame)
//        let renderedImage = renderer.image { (_) in
//            image.draw(in: frame.insetBy(dx: 16,dy: 30))
//        }
//      self.image = renderedImage.withRenderingMode(.alwaysTemplate)
        self.image = image
    }
}

并像这样使用它:

 let size = CGSize(width: 10,height: 10)
    let frame = CGRect(origin: CGPoint(x: 360,y: 45),size: size)
    let infoView = CustomView(frame: frame,corners: [.layerMinXMinYCorner,.layerMaxXMinYCorner],systemName: "info.circle")
    let locationView = CustomView(frame: frame,corners: [],systemName: "location")
    let plusView = CustomView(frame: frame,corners: [.layerMinXMaxYCorner,.layerMaxXMaxYCorner],systemName: "plus.circle")
    let binocularsView = CustomView(frame: frame,.layerMinXMaxYCorner,.layerMaxXMinYCorner,systemName: "binoculars.fill")
    let stackView = UIStackView(arrangedSubviews: [infoView,locationView,plusView,binocularsView])
    stackView.frame = CGRect(origin: CGPoint(x: 360,size: CGSize(width: 45,height: 180))
    stackView.distribution = .fillEqually
    stackView.axis = .vertical
    stackView.setCustomSpacing(3,after: plusView)
    view.addSubview(stackView)

使用这段代码,它看起来像这样:

screenshot BEFORE

如您所见,图标太大...所以这就是我试图缩小它们的原因:(取消注释 createImage() 中的行)

func createImage(systemName: String) {
    let image = UIImage(systemName: systemName)!
    let renderer = UIGraphicsImageRenderer(bounds: self.frame)
    let renderedImage = renderer.image { (_) in
        image.draw(in: frame.insetBy(dx: 16,dy: 30))
    }
  self.image = renderedImage.withRenderingMode(.alwaysTemplate)
}

但后来它被扭曲了......

能帮到我吗? :)

谢谢!!!!

解决方法

而不是继承 UIImageView 子类 UIView 并添加一个 UIImageView 作为子视图。然后,您可以根据需要在图像周围创建尽可能多的间距。

class CustomView: UIView {

    lazy var imageView: UIImageView = {
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        return imageView
    }()

    init(frame: CGRect,corners: CACornerMask,systemName: String) {
        super.init(frame: frame)
        self.setUpViews()
        // ...
    }

    func setUpViews() {
        addSubview(imageView)
        NSLayoutConstraint.activate([
            imageView.leadingAnchor.constraint(equalTo: leadingAnchor,constant: 5),imageView.trailingAnchor.constraint(equalTo: trailingAnchor,constant: -5),imageView.topAnchor.constraint(equalTo: topAnchor,imageView.bottomAnchor.constraint(equalTo: bottomAnchor,])
    }

    func createImage(systemName: String) {
        let image = UIImage(systemName: systemName)!
        self.imageView.image = image
    }
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...