【问题标题】:How to create an UIImageView extension that is rounded by itself如何创建一个自身四舍五入的 UIImageView 扩展
【发布时间】:2016-05-28 05:15:58
【问题描述】:

我最近遇到了一个烦人的问题。

假设我想在我的应用程序中的多个地方使用一张图片,并且在任何地方它都必须圆润成圆形。 因为我希望我的代码干净,所以我认为这个功能(舍入本身)应该放在 inside 扩展 UIImageView 的类中。 我创建了一个简单的类,它覆盖故事板构造函数并负责正确设置cornerRadius:

class RoundedImageView: UIImageView {


    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.layer.cornerRadius = self.frame.size.width/2
        self.layer.borderColor = UIColor.redColor().CGColor
        self.layer.borderWidth = 2
        self.layer.masksToBounds = true
    }
}

对于类似的约束

  • 宽度:100,

  • 身高:100

    这显然有效,因为在调用构造函数后框架不会更改(因为它在情节提要中具有正确的尺寸)。例如,当约束如下所示时,就会出现问题:

  • 宽度等于 0.5 superview's

  • 纵横比:1:1

因为在调用构造函数后框架发生了变化。

我最终做的是这样的:

override func viewDidLayoutSubviews(){
    super.viewDidLayoutSubviews()
    myRoundedImageInstance.layer.cornerRadius = ...
}

在每个包含此类实例的视图控制器中... ...这是可行的,因为在 imageView 更改尺寸后会重新计算框架,但这丑陋,并且类的存在似乎在这种情况下是不必要的。。 p>

我尝试将帧的重新计算放入 drawRect - 也不起作用。 有什么想法吗?

【问题讨论】:

  • 为什么不将您的舍入代码移至RoundedImageView.layoutSubviews?另一种选择是将图层蒙版设置为圆形路径。
  • 哇,不知道视图的这种方法(layoutSubviews),而不是视图控制器。我应该在这种方法中调用 super 吗?顺便说一句,您的回答解决了问题。非常感谢!
  • “因为我希望我的代码干净,我认为这个功能(舍入本身)应该放在扩展 UIImageView 的类中”我不明白为什么。你为什么不把功能放在 UIImage 里面,即图像本身将自己裁剪成一个圆圈?
  • 我做了回答

标签: ios swift uiimage


【解决方案1】:

这是一个简单的 IBDesignable 示例(您可以在界面构建器中看到它的外观)

@IBDesignable
    class RoundedUIImageView: UIImageView {
        @IBInspectable var round: Bool = true {
            didSet {
                self.clipsToBounds = true
                self.layer.cornerRadius = self.frame.width / 2
                self.layer.borderWidth = 2.5
                self.layer.borderColor = UIColor(rgba: "#D0D0D0").CGColor
            }
        }
    }

你可以让它更复杂,因为这假设 UIImageView 是一个正方形。如果不是,它将最终成为一个椭圆。您可以计算最小尺寸,然后以这种方式剪辑。但这是您尝试做的最简单的形式。

编辑:同样的想法,但代码更精致。

import UIKit

@IBDesignable
class RoundedUIImageView: UIImageView {
    @IBInspectable var round: Bool = true {
        didSet { self.setNeedsLayout() }
    }

    @IBInspectable var width: CGFloat = 2.5 {
        didSet { self.setNeedsLayout() }
    }

    @IBInspectable var color: UIColor = UIColor(rgba: "#D0D0D0") {
        didSet { self.setNeedsLayout() }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        self.clipsToBounds = true

        if round {
            self.layer.cornerRadius = self.frame.width / 2
        } else {
            self.layer.cornerRadius = 0
        }

        self.layer.borderWidth = self.width
        self.layer.borderColor = self.color.CGColor
    }
}

它有默认值,所以一切都可以保持一致。但它也可以通过故事板进行定制。

【讨论】:

  • 真的很酷(IBDesignable 的东西),唯一的问题是它没有回答我的问题。它不仅不会对布局更改做出反应(根据约束计算帧),而且还需要我每次使用该类时手动设置此值(因为默认将其设置为 true 不会调用 didSet - 我检查了它) .正确答案是对我的问题的第一条评论。
  • 我更新了我的答案,以更具体地解释我想要解释的内容。
【解决方案2】:

您可以将您的圈子更新代码移动到您的layoutSubviews 方法中。

【讨论】:

    猜你喜欢
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    • 2023-03-30
    • 1970-01-01
    • 2011-01-22
    • 2018-08-03
    • 1970-01-01
    相关资源
    最近更新 更多