【问题标题】:Transparent view is black?透明视图是黑色的?
【发布时间】:2017-08-20 20:08:10
【问题描述】:

我正在尝试创建一个在某些位置透明的视图,以查看后面的图像。但是,由于某种原因,在视图的透明部分,我看到的是黑色,而不是视图后面的内容。我已将其缩减为非常少的代码,并且不明白为什么我的透明视图显示黑色而不是红色(后面视图的颜色)。这是我的代码:

class ViewController: UIViewController {

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        let redView = UIView(frame: view.frame)
        redView.backgroundColor = UIColor.red
        let transparentView = TransparentView(frame: view.frame)

        view.addSubview(redView)
        view.addSubview(transparentView)
    }
}

class TransparentView: UIView {

    override func draw(_ rect: CGRect) {
        UIColor.clear.setFill()
        UIRectFill(rect)
}

我希望屏幕是全红的,但它却显示全黑。在有人说清晰视图要容易得多之前,我实际上是在尝试在 drawRect 中做更复杂的事情,只是下降到最基本的事情来尝试调试我的问题。我在这里错过了什么?

【问题讨论】:

  • self.opaque = false; 将其添加到TransparentView 构造函数中。然后你可以在draw 方法中做任何你想做的事情。

标签: ios swift uikit


【解决方案1】:

使用self.isOpaque = false; 使视图/层透明,即使drawRect 被覆盖。

class TransparentView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame);

        self.isOpaque = false;  //Use this..
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ rect: CGRect) {
        UIColor.clear.setFill()
        UIRectFill(rect)
    }
}

【讨论】:

  • 啊,我不知道那个属性,也许这比我的解决方案更干净。
  • 实际上设置该属性不会改变行为
  • 没关系我是个白痴,我将 isOpaque 设置为 true,这确实有效
【解决方案2】:

我想通了。显然,即使您覆盖draw,似乎仍会考虑背景颜色,并且默认为黑色。我在透明视图类中添加了以下内容:

override init(frame: CGRect) {
    super.init(frame: frame)

    backgroundColor = UIColor.clear
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

【讨论】:

    【解决方案3】:

    “drawRect:如果你的视图绘制自定义内容,实现这个方法。如果你的视图不做任何自定义绘制,避免覆盖这个方法。” Link

    正如你所说的那样,在初始化时设置背景颜色会更好。

    override init(frame: CGRect) {
        super.init(frame: frame)
    
        backgroundColor = UIColor.clear
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    

    就我个人而言,我不会为这么少的自定义子类化视图。只需在创建时设置它。视图设置在 viewDidLoad 上更好,而不是在 viewWillAppear 上。因为它会在每次您的视图进入前台时执行,并且您将以添加两个透明视图结束。 此外,将这些行保留在具有私有函数的扩展中有助于保持代码清晰。

    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            setupViews()
        }
    }
    
    
    //MARK: - Private Methods
    extension ViewController{
        fileprivate func setupViews(){
           let redView = UIView(frame: view.frame)
           redView.backgroundColor = UIColor.red
           view.addSubview(redView)
    
           let transparentView = UIView(frame: view.frame)
           transparentView.backgroundColor = UIColor.clear
           view.addSubview(transparentView)
        }
    }
    

    请注意,更清晰的方法是在情节提要中创建这些视图(而不是通过代码)。保持代码清晰,更容易理解和查看发生了什么。

    【讨论】:

    • @Kven DiTraglia 您是否以我的解决方案结束?如果比选择的更好,加上我的回答。 +1 怎么样?
    • 如果您重新阅读我明确表示的问题,我意识到使用 drawRect 太简单了,但我的实际代码要复杂得多,需要绘制,但您的回答还是删除了它。
    猜你喜欢
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    • 2023-03-17
    • 2012-05-09
    • 2015-08-12
    • 2015-03-18
    • 2013-08-21
    • 1970-01-01
    相关资源
    最近更新 更多