Xcode8.1中@IBDesignable以及@IBInspectable不能自动刷新的解决办法

Xcode中的@IBDesignable和@IBInspectable关键字出来也有一段时间了,目的是当用户改变View属性时InterfaceBuilder的界面里可以得到即时刷新反馈.

这无疑对于App界面的调整带来很多方便.不过网上很多童鞋都会抱怨使用时会出现或多或少的问题,不要着急,就让本猫带领大家来看看到底该怎么使用这两个关键字. ;)

官方对这两个关键字(属性)是这么说的:

"Live Rendering
You can use two different attributes—@IBDesignable and @IBInspectable—to enable live, interactive custom view design in Interface Builder. When you create a custom view that inherits from the UIView class or the NSView class, you can add the @IBDesignable attribute just before the class declaration. After you add the custom view to Interface Builder (by setting the custom class of the view in the inspector pane), Interface Builder renders your view in the canvas. You can also add the @IBInspectable attribute to properties with types compatible with user defined runtime attributes. After you add your custom view to Interface Builder, you can edit these properties in the inspector."

我们使用@IBDesignable告诉Interface Builder这个类可以实时渲染到界面中,但是这个类必须是UIView或者NSView的子类。使用@IBInspectable可以定义动态属性,即可在attribute inspector面板中可视化修改属性值。

下面我们就来尝试一下,首先建立一个新的类继承于UIView,名称为GradientView,其定义如下:

@IBDesignable class GradientView: UIView {
    @IBInspectable var topColor = UIColor.white
    @IBInspectable var bottomColor = UIColor.black

    override func layoutSubviews() {
        (layer as! CAGradientLayer).colors = [topColor.cgColor,bottomColor.cgColor]
    }

    //override class func layerClass()->AnyClass{
    override class var layerClass:AnyClass{
        return CAGradientLayer.self
    }

注意上述代码中的最后一段,在Swift3.0后layerClass已经不是以方法来实现,所以我们要重载为计算属性.

我们打开InterfaceBuilder(以下简称IB),将默认View的类改为我们新创建的类名GradientView,但是之后你会发现IB中并没有出现我们希望的topColor和bottomColor两个可视属性.原来对于IBInspectable修饰的属性我们不可以使用”智能推测类型”,必须明确指明属性类型,将代码修改为显式声明类型:

@IBInspectable var topColor:UIColor = UIColor.white
@IBInspectable var bottomColor:UIColor = UIColor.black

这下OK了!不过随后你会发现另一个问题,当你修改topColor和bottomColor两个属性的时候IB界面对应的View背景并没有发生变化.
这时你可以采取的办法为:

  1. 重启Xcode
  2. 勾选Xcode->Editor->Automatically Refresh Views
  3. 点击Xcode->Editor->Refresh All Views

当你执行完上述步骤后,多半你会发现………..还是不能自动刷新!!! ;(

这时我们就要看一下你的GradientView类代码实现的问题了.

首先你此时编译运行App时会发现,运行的App的背景是完全符合我们在IB里设置的内容的.但我们在IB界面里直接修改topColor和bottomColor时并不能得到即时的反馈!

我可以告诉你,IB也是通过对你的GradientView代码的执行来更新IB界面的,而你在GradientView中是在layoutSubviews方法里更新top/bottom这两个颜色属性的,所以你只会得到一次刷新,就是在第一次view layout的时候,而且此时使用的是默认值即白色和黑色;之后你再怎么在IB中修改属性,layoutSubviews方法都不会再调用了,所以你的IB界面不能即时刷新!

我要做的就是将更新View放到其draw方法中去!在GradientView中添加如下方法:

override func draw(_ rect: CGRect) {
        (layer as! CAGradientLayer).colors = [topColor.cgColor,bottomColor.cgColor]
    }

回到IB中,你会发现—–还是不能即时刷新!!!!!!

对!你没看错,还是不行!!!不但不行,你的View背景还变为了纯白色!!!

不过别急,我们离目标已经很近了! ;)之所以还不能刷新的原因是,View的背景被设置为了纯色,即在draw绘制的东东会被背景所覆盖哦!所以我们只需要将View的背景颜色设置为clear(透明色)即可!

Xcode8.1中@IBDesignable以及@IBInspectable不能自动刷新的解决办法_第1张图片

成功!收工!

你可能感兴趣的:(xcode,自动刷新,IB,Designable,Inspectabl)