【问题标题】:Custom @IBDesignable UIButton crashes Xcode自定义 @IBDesignable UIButton 使 Xcode 崩溃
【发布时间】:2020-12-03 02:12:38
【问题描述】:

我想在 Swift 中为我的 iOS 项目设计一个带阴影的圆形按钮。所以我想出了以下自定义按钮类:

import UIKit

@IBDesignable class MainButton: UIButton {
    private var shadowLayer: CAShapeLayer!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        let image = createBackgroundImage()
        setBackgroundImage(image, for: UIControl.State.normal)
        clipsToBounds = true
        
        contentEdgeInsets = UIEdgeInsets(top: 5, left: 20, bottom: 5, right: 20)
        
        layer.masksToBounds = false
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 3)
        layer.shadowOpacity = 0.2
        layer.shadowRadius = 6
    }
    
    func createBackgroundImage() -> UIImage {
        let rect = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
        UIGraphicsBeginImageContextWithOptions(frame.size, false, 0)
        let color = UIColor.white
        color.setFill()
        UIBezierPath(roundedRect: rect, cornerRadius: frame.height * 0.5).addClip()
        color.setFill()
        UIRectFill(rect)
        let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }
}

一旦我在 Storyboard 中为按钮设置了此类,“IBDEsignablesAgent-iOS”进程就会占用我近 100% 的 CPU,而 Xcode 会自行挂起。这种行为几乎不可能正确调试问题。

我很确定我以错误的顺序或错误的方法做某事。但我不知道如何解决它。希望这里有人可以指出正确的方向。

谢谢, 延斯

【问题讨论】:

  • 你试过Instruments -> TimeProfiler吗?
  • layoutSubviews 被频繁调用(每秒数十次)。你不应该做任何设置(绝对不设置图像)。如果你想在那里设置一些东西,它应该与视图大小有关,你应该检查大小是否真的改变了。否则,您的更改只会导致新的布局。

标签: ios swift xcode uibutton ibdesignable


【解决方案1】:

只需检查视图的大小是否实际发生了变化:

private var lastSize: CGSize = .zero

override func layoutSubviews() {
   super.layoutSubviews()

   guard frame.size != lastSize else { return }

   lastSize = frame.size

   ...
}

创建阴影很慢,layoutSubviews 每秒被调用数十次(基本上是每帧一次)。

【讨论】:

    【解决方案2】:

    我的自定义按钮带有一些阴影和圆角,我直接在情节提要中使用它,无需以编程方式触摸它。

    class RoundedCornerButtonWithShadow: UIButton {
        override func awakeFromNib() {
            super.awakeFromNib()
            self.layer.masksToBounds = false
            self.layer.cornerRadius = self.frame.height/2
            self.layer.shadowColor = UIColor.black.cgColor
            self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.layer.cornerRadius).cgPath
            self.layer.shadowOffset = CGSize(width: 0.0, height: 3.0)
            self.layer.shadowOpacity = 0.5
            self.layer.shadowRadius = 1.0
        }
    }
    

    【讨论】:

    • 在动态更改按钮大小后将不起作用,例如更改标题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 2014-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多