【问题标题】:Unexpected behaviour when adding CALayer as sublayer to UIImage将 CALayer 作为子层添加到 UIImage 时出现意外行为
【发布时间】:2017-01-24 10:32:17
【问题描述】:

我有带有自定义单元格的 tableView。每个单元格都有属性“名称”和“图像”。我想要做的是在图像周围添加边框。这部分有效。但是当我尝试将 backgroundColor 添加到 CALayer 时,我在 tableView 中看到的只是没有 UIImage 的 CALayer。

这里是用于更好理解的代码和设置背景颜色的示例。

 @IBOutlet weak var channelImage: UIImageView! {
        didSet {
            let borderLayer = CALayer()
            let borderFrame = CGRect(x: -4, y: -4, width: channelImage.frame.size.width+8, height: channelImage.frame.size.width+8)
            borderLayer.frame = borderFrame
            borderLayer.cornerRadius = 4
            borderLayer.borderWidth = 0.5
            borderLayer.borderColor = UIColor.lightGray.cgColor
            channelImage.layer.insertSublayer(borderLayer, at: 0)
            channelImage.layer.masksToBounds = false
            borderLayer.backgroundColor = UIColor.lightGray.cgColor
            self.channelImage.layoutIfNeeded()
            self.channelImage.layoutSubviews()
        }
    }

没有背景颜色:

@IBOutlet weak var channelImage: UIImageView! {
    didSet {
        let borderLayer = CALayer()
        let borderFrame = CGRect(x: -4, y: -4, width: channelImage.frame.size.width+8, height: channelImage.frame.size.width+8)
        borderLayer.frame = borderFrame
        borderLayer.cornerRadius = 4
        borderLayer.borderWidth = 0.5
        borderLayer.borderColor = UIColor.lightGray.cgColor
        channelImage.layer.insertSublayer(borderLayer, at: 0)
        channelImage.layer.masksToBounds = false
        self.channelImage.layoutIfNeeded()
        self.channelImage.layoutSubviews()
    }
}

这里还引用了第一个和第二个示例的图像:

我做了很多搜索,但没有找到适合我情况的答案。

这里是这个 Cell 的完整代码

class ChannelCell: UITableViewCell, ChannelSettable {

    static let reusableID = "channelCell"

    var channel: Channel? = nil {
        didSet {
            self.channelName.text = channel?.channelName ?? ""
            self.channelImage.image = UIImage(named: channel?.channel ?? "") ?? UIImage(named: "TV")
            self.channelCategory.text = channel?.chCategory ?? ""
        }
    }

    @IBOutlet weak var channelName: UILabel!
    @IBOutlet weak var channelCategory: UILabel!
    @IBOutlet weak var channelImage: UIImageView! {
        didSet {
            let borderLayer = CALayer()
            let borderFrame = CGRect(x: -4, y: -4, width: channelImage.frame.size.width+8, height: channelImage.frame.size.width+8)
            borderLayer.frame = borderFrame
            borderLayer.cornerRadius = 4
            borderLayer.borderWidth = 0.5
            borderLayer.borderColor = UIColor.lightGray.cgColor
            borderLayer.backgroundColor = UIColor.lightGray.cgColor
            channelImage.layer.insertSublayer(borderLayer, at: 0)
            channelImage.layer.masksToBounds = false
        }
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        self.channelName.font = DesignHelper.channelNameFont
        self.channelCategory.font = DesignHelper.channelCategoryFont
        self.layoutIfNeeded()
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

【问题讨论】:

    标签: swift uiimage calayer


    【解决方案1】:

    您可以像这样直接向 UIImageView 的图层添加边框:

    channelImage.layer.borderWidth = 0.5
    channelImage.layer.borderColor = UIColor.lightGray.cgColor
    

    你不必费心额外的层来做到这一点。

    但是,如果您仍然需要添加额外的 CALayer,请尝试使用以下方法:

    func insertSublayer(CALayer, above: CALayer?)
    func insertSublayer(CALayer, below: CALayer?)
    

    【讨论】:

    • 我知道如何将边框直接添加到 UIImageView,但在我的情况下,我希望边框位于单独的图层中,因为边框的帧大小需要大于图像的帧大小。你提到的两种方法我也试过了,结果还是一样。
    • 如果您只想添加比 ImageView 更大的边框,您可以使用 UIKit 在更大的 imageView 下方插入一个子视图。然后设置它的背景颜色。如果你愿意,你可以用 CALayer 属性绕过它。您可以使用 UIView 类中的 insertSubview(:aboveSubview:) 或 insertSubview(:belowSubview:) 来做到这一点。
    • 这可能会发生,但是当我想更改 CALayer 帧大小与 UIImage 帧大小相比的偏移量时,我将不得不更改约束等,这不是我想要实现的目标。跨度>
    • 您确定您正确隔离了问题吗?我无法重现所描述的行为 - 意思是:我正确地看到了带有边框的图像。然后寻找一些外部因素......
    • 你给CALayer添加了背景色吗?因为没有背景颜色,一切看起来都很好。
    【解决方案2】:

    子层被插入到您的图像视图中。

    如果你想设置 imageView 的背景然后使用

    channelImage.backgroundColor = UIColor.lightGray.cgColor
    

    你可以在你的图层中添加图像(如果你想在图像后面添加图层)

    borderLayer.contents = channelImage.cgImage
    

    【讨论】:

    • 我也知道这一步/可能的解决方案,但由于我的 CALayer 大于图像框架,这对我不起作用,因为只有图像层的背景颜色发生了变化。而且你在 calayer 和图像框架之间有白色边框。真正的问题是为什么即使我将其作为子图层插入,图层也会插入到图像视图上方。
    • 然后只需将您的 UIImage 添加到 CALayer 中(查看更新的答案)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    • 2018-11-26
    • 1970-01-01
    相关资源
    最近更新 更多