• Swift


    前言:

    用storyboard/xib搞项目时,一些属性在Interface Builder上时无法设置,比如常用的layer的一些属性
    cornerRadius,borderColor等 (有时没必须的关联属性 用代码去设置)。估计大家也都想省事,能Interface Builder解决的绝不代码(特殊情况外),搞个复杂点的界面加上约束条件,我x还不疯了 时间都玩它了。但是wwdc2014其中要解决的问题时:

    • 写的code怎么在Interface Builder动态预览效果?
    • code中的属性是否可以在Interface Builder上设置?

    上边的2个问题就是这篇文章要解决的了:也就是在xcode6中苹果给提供了@IBDesignable和@IBInspectable   这里时必须时UIView/NSView子类使用,看到这可能要冒出 :“No Code you say a JB a”  

    例子1:那么废话少说直接先swift为例drawRect看下效果(注:UIView/NSView):

    @IBDesignable   // 记得@IBDesignable添加 它就是告诉IB可以动态预览
    class SView: UIView {

        override func drawRect(rect:CGRect{
             var context:CGContextRef = UIGraphicsGetCurrentContext()
             CGRectInset(CGRectMake(003030)55)
             UIColor.yellowColor().set()
             CGContextSetLineWidth(context22)
             UIRectFrame(CGRectMake(003030))
       }
    }

    那么就直接看下效果吧:

    ibdesiginbleeruntime

    例子2: 怎么在CustomView上的子视图的属性在IB上设置呢?:

    class DrawView: UIView {

           var runLabel: UILabel!
           @IBInspectable var labelTitle: String!
           @IBInspectable var labelColor: UIColor!

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

               labelTitle "一起扯扯"
               labelColor = UIColor.blackColor()
               runLabel = UILabel(frame:CGRectMake(0018080))
               runLabel.textColor = labelColor
               runLabel.text      = labelTitle
               addSubview(runLabel)
         }

         required init(coder aDecoder: NSCoder{
         super.init(coder: aDecoder)

              labelTitle "一起扯扯"
              labelColor = UIColor.blackColor()
              runLabel = UILabel(frame:CGRectMake(0018080))
              runLabel.textColor = labelColor
              runLabel.text      = labelTitle
              addSubview(runLabel)
         }

         override func layoutSubviews({
              runLabel.textColor = labelColor
              runLabel.text      = labelTitle
         }
    }

    那么就看下自定义的DrawView在IB上Label属性设置效果:

    perpthre

    例子3: 怎么在IB上设置layer的一些属性值呢?

    @IBDesignable
    class SView: UIView {

          @IBInspectable var cornerRadius: CGFloat {
                 didSet {
                       layer.cornerRadius = cornerRadius
                 }
          }

         @IBInspectable var borderWidth: CGFloat {
                 didSet {
                       layer.borderWidth = borderWidth
                 }
         }

         @IBInspectable var borderColor: UIColor{
                 didSet {
                       layer.borderColor = borderColor?.CGColor
                 }
         }
    }

    在User Defined Runtime Attributes 中KeyPath不用自己填写,在设置的时候会自动填充上!还是看下效果吧:perptwo

    例子4: 看到这里可能还会说是不是每个视图用到layer都这么费劲?答案:不会的 搞个UIView扩展就省事多点了!

    extension UIView {
        @IBInspectable var cornerRadius: CGFloat {
             get {
                return layer.cornerRadius
             }
             set {
                layer.cornerRadius = newValue
                layer.masksToBounds = newValue &gt0
              }
        }

        @IBInspectable var borderColor:CGColor {

            get {
               return layer.borderColor
            }
            set {
              layer.borderColor = borderColor;
            }
        }
    }

    最近一直在看苹果公司提供的两本swift官方教程电子书,一部是《The Swift Programming Language》,另一部是《Using Swift With Cocoa and Objective-C》。昨天正好看到第二部电子书的“Writing Swift Classes with Objective-C Behavior”这一节,其中讲述了关于实时渲染这一技术。下面是摘抄的其中一段内容:

    “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.
    
    SWIFT
    
    @IBDesignable
    class MyCustomView: UIView {
    	@IBInspectable var textColor: UIColor
    	@IBInspectable var iconHeight: CGFloat
    	/* ... */
    }
    ”
    
    

    其大意就是说,可以将自定义的代码实时渲染到Interface Builder中。而它们之间的桥梁就是通过两个指令来完成,即@IBDesignable和@IBInspectable。我们通过@IBDesignable告诉Interface Builder这个类可以实时渲染到界面中,但是这个类必须是UIView或者NSView的子类。通过@IBInspectable可以定义动态属性,即可在attribute inspector面板中可视化修改属性值。

    话不多说,下面举一个简单的例子,这个例子自定义一个UIView的子类,该子类拥有一个UIButton。

    import UIKit
    
    @IBDesignable
    class MyCustomView: UIView {
    	
    	@IBInspectable var buttonTitleColor: UIColor!		 //  button title color
    	@IBInspectable var buttonTitle: String!			   //  button title
    	@IBInspectable var buttonFrame: CGRect!			   //  button frame
    	
    	var myButton: UIButton!
    	
    	override init(frame: CGRect) {
    		// init stored properties
    		buttonTitleColor = UIColor.redColor()
    		buttonTitle = "button title"
    		buttonFrame = CGRectMake(0, 0, 100, 50)
    		
    		myButton = UIButton(frame: buttonFrame)
    		myButton.setTitleColor(buttonTitleColor, forState: .Normal)
    		myButton.setTitle(buttonTitle, forState: .Normal)
    		
    		// call super initializer
    		super.init(frame: frame)
    		
    		// add button to self
    		addSubview(myButton)
    
    	}
    	
    	required init(coder aDecoder: NSCoder) {
    		// init stored properties
    		buttonTitleColor = UIColor.redColor()
    		buttonTitle = "button title"
    		buttonFrame = CGRectMake(0, 0, 100, 50)
    		
    		myButton = UIButton(frame: buttonFrame)
    		myButton.setTitleColor(buttonTitleColor, forState: .Normal)
    		myButton.setTitle(buttonTitle, forState: .Normal)
    		
    		// call super initializer
    		super.init(coder: aDecoder)
    		
    		// add button to self
    		addSubview(myButton)
    	}
    	
    	override func layoutSubviews() {
    		// refresh button state through attribute inspector
    		myButton.setTitleColor(buttonTitleColor, forState: .Normal)
    		myButton.setTitle(buttonTitle, forState: .Normal)
    	}
    
    }

    上图:

    从图中可以看到,代码实时渲染到IB中了。

    另外,我们在attribute inspector中也可以看到,由指令@IBInspectable声明的属性也出现在了面板中,通过修改这些值可以动态改变界面的效果(需要实现layoutSubviews方法)

    具体工程一览:

  • 相关阅读:
    批处理学习总结
    深搜广搜
    罗塔的一篇回忆埃尔德什的文字
    一个有意思的东西(挖坑)
    人格风骨出尘俗 道德文章传后人(转载)
    2015年数学日历
    一道关于将弧翻折的问题
    努力要做的是理解,而不是死记硬背
    在博客中使用align*环境
    测试TeX代码的网址
  • 原文地址:https://www.cnblogs.com/gongyuhonglou/p/5977206.html
Copyright © 2020-2023  润新知