当前位置: > > > Swift - 在StoryBoard中添加使用自定义组件(自定义进度条组件为例)

Swift - 在StoryBoard中添加使用自定义组件(自定义进度条组件为例)

通常在开发中,为了使代码更加简洁,我们常常会把常用的功能封装成一个个组件(或者称UI元件、UI控件),同时这样也更利于代码的复用。
我原来写过一篇文章,介绍如何通过继承UIView来实现自定义组件:Swift - 继承UIView实现自定义可视化组件(附记分牌样例)
原文样例是直接在代码中添加使用自定义组件的。

本文介绍如何在StoryBoard中使用自定义组件,有如下优势:
(1)在StoryBoard中我们就可以很方便地调整自定义组件的位置、布局以及相关约束。
(2)可以在属性面板设置自定义组件的各个属性(包括自定义属性),同时StoryBoard的视图区域中也会实时地将样式体现出来。

1,自定义可视化组件的创建
这里以自定义一个简单的进度条组件为例,用户可以自由设置进度条的进度、尺寸、文字颜色、进度条颜色、背景颜色。

自定义组件的关键是使用如下两个Interface Builder(下文用IB简称)属性声明:IBInspectableIBDesignable
@IBDesignable:用来标识自定义组件类,这样在StoryBoard中就能能实时更新视图。
@IBInspectable:用来标识属性,这样在Attribute Inspector(属性检查器)中查看设置该属性。
import UIKit

@IBDesignable class MyProgressBar: UIView {
    
    //显示进度的文本标签
    private let textLabel = UILabel()
    
    //显示当前进度区域
    private let bar = UIView()
    
    //进度
    @IBInspectable var percent: Int = 0 {
        didSet {
            if percent > 100 {
                percent = 100
            }else if percent < 0 {
                percent = 0
            }
            textLabel.text =  "\(percent)%"
            setNeedsLayout()
        }
    }
    
    //文本颜色
    @IBInspectable var color: UIColor = .white {
        didSet {
            textLabel.textColor = color
        }
    }
    
    //进度条颜色
    @IBInspectable var barColor: UIColor = UIColor.orange {
        didSet {
            bar.backgroundColor = barColor
        }
    }
    
    //进度条背景颜色
    @IBInspectable var barBgColor: UIColor = UIColor.lightGray {
        didSet {
            layer.backgroundColor = barBgColor.cgColor
        }
    }
    
    //init方法
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        initialSetup()
    }
    
    //init方法
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        initialSetup()
    }
    
    //页面初始化相关设置
    private func initialSetup() -> Void {
        bar.backgroundColor = self.barColor
        addSubview(bar)
        
        textLabel.textAlignment = .center
        textLabel.numberOfLines = 0
        textLabel.textColor = self.color
        textLabel.text = "\(self.percent)%"
        addSubview(textLabel)
    }
    
    //布局相关设置
    override func layoutSubviews() {
        super.layoutSubviews()
        
        layer.backgroundColor = self.barBgColor.cgColor
        
        var barFrame = bounds
        barFrame.size.width *= (CGFloat(self.percent) / 100)
        bar.frame = barFrame
        
        textLabel.frame = bounds
    }
}
可以先使用代码测试下:
import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let myProgressBar = MyProgressBar(frame: CGRect(x:50, y:50, width:200, height:20))
        myProgressBar.percent = 50
        self.view.addSubview(myProgressBar)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}


2,在StoryBoard中使用自定义组件
(1)打开Main.storyboard,从组件库里添加一个视图(View

(2)在Identity Inspector里把视图类改成MyProgressBar

(3)可以看到自定义组件已经渲染显示出来了

(4)在Attributes inspector面板中可以调整组件的各个自定义属性

(注:如果自定义组件是没有使用IB关键字,也是可以在StoryBoard中添加使用的。只不过在StoryBoard中不能实时更新视图和属性,显示的是一个空白矩形。)

源码下载:
hangge_1016.zip(2016-02-25 Swift2)
hangge_1016.zip(2016-10-11 Swift3最新版)
评论6
  • 6楼
    2016-08-11 11:43
    cat

    五星好评!找了很久才在这里看到

    站长回复

    很高兴我的文章能对你有所帮助。欢迎常来看看,我会持续更新的。

  • 5楼
    2016-06-23 08:19
    Alleluia

    希望到时候3.0出来会同步下Swift的版本更新,站长做的很不错哦!赞一个~

    站长回复

    谢谢你的支持和鼓励。Swift语法变动地很快。所以我平时除了写新文章外,也会定期把过去的文章更新下。

    不过文章太多,难免会有遗漏。所以如果大家发现有哪里语法不对,或者在新版下报错,可以及时通知我。我会在第一时间修正的。

  • 4楼
    2016-03-17 09:16

    好多好用的知识,明了清晰,不像其他充斥网络中的所谓教程打着新手入门的旗号,实质上只是扯些专业名词,说些空洞的东西。
    感谢航歌,这将近一个月来帮了我很多很多

    站长回复

    很高兴我的文章对你有帮助。我一直觉得既然写东西给大家看还是要用心写,要不大家看了半天也没收获,那反而浪费大家的时间。最后也谢谢你对我文章的认可,我会继续创作下去的,欢迎常来看看。

  • 3楼
    2016-02-28 21:21
    s

    好网站,支持!

    站长回复

    欢迎常来看看,我会坚持更新下去的。

  • 2楼
    2016-02-25 09:24

    在Identity Inspector里把视图类改成MyProgressBar 无法显示 怎么回事?

    站长回复

    估计你哪里写错了。我把项目源码放到文章末尾了,你可以下下来比较下。

  • 1楼
    2016-02-17 22:03
    小华

    学习了,谢谢分享

    站长回复

    不客气,欢迎常来看看