美文网首页
第三十一章 Swift 界面搭建

第三十一章 Swift 界面搭建

作者: 我有小尾巴快看 | 来源:发表于2019-06-04 14:25 被阅读0次

这是一个简单的界面实例。

1. 懒加载

大多数情况下View都是懒加载的,这样你不必在初始化控制器时去初始化View,并且代码更加紧凑了。

OC使用懒加载一般是在getter方法中进行处理,当_ivar == nil时,_ivar == XX.new,Swift中懒加载准确来说是延时加载,只会加载一次,如果置空便无法再次像OC哪样重新懒加载,除非添加变量使用和OC一样的方法进行处理。

  • Objective-C懒加载:
- (UILabel *)label {
    if (!_label) {
        _label = UILabel.new;
    }
    return _label;
}
  • Swift懒加载:
lazy var label: UILabel = {
    return UILabel()
}()
  • Swift仿Objective-C可多次加载的懒加载(以计算属性的方式完成):
var _label: UILabel?
var label: UILabel = {
    if _label == nil {
        _label = UILabel()
    }
    return _label!
}()

2. 初始化控制器

2.1 Swift初始化可以调用init()或者直接使用类型名+()的方式调用

例如UIViewController.init()等价于UIViewController()

2.2 重写或添加初始化方法

  1. 无论重写还是添加新的初始化方法,都必须调用designed 方法,例如ViewController 添加了init(fps:)方法,该方法内部则必须调用UIViewController.init(nibName:bundle:)
  2. 如果父类实现了init(coder:),则必须实现该方法,编译器会提醒,点击插入该代码,代码布局一般是直接返回nil
  3. 初始化方法没有返回值,除非是init?(...)返回可选值的初始化方法允许返回nil。
  4. 子类的属性未初始化完毕前不可使用super,自身初始化完毕前不可使用self.xxx,
  5. 可选值可以不初始化,默认为nil,所有属性均可在属性那里直接初始化
class ViewController: UIViewController {
    lazy var label: UILabel = {
        let view = UILabel()
        return view
    }()
    let fps: UInt
    var index = 0
    var delegate: Any?
    
    init(fps: UInt) {
        self.fps = fps
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        return nil
    }
}

上方代码中

  1. index在属性声明时已初始化为0,通过字面量推断为Int类型
  2. delegateAny可选类型,初始值为nil
    3.label懒加载,为UILabel有值类型
  3. init(fps:)调用了UIViewController.init(nibName:bundle:),在调用super前所有属性均初始化完毕
  4. 父类实现了init(coder:),故子类也需要实现。

3. 简单布局

Swift和OC使用框架的方式几乎完全相同,这里列出相关代码。

class ViewController: UIViewController {
    lazy var label: UILabel = {
        let view = UILabel()
        view.textColor = .black
        view.textAlignment = .center
        view.font = .systemFont(ofSize: 15)
        return view
    }()
    let fps: UInt
    var index = 0
    var delegate: Any?
    
    init(fps: UInt) {
        self.fps = fps
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        return nil
    }
    
    deinit {
        print("ViewController deinit")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(label)
        label.text = "Hello World"
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        label.center = view.center
    }
}

4. 回调

在OC中,有block,delegate,notication三种方式进行消息传递,在Swift中也同样支持。

protocol TextFieldDelegate: NSObjectProtocol {
    func textField(_ textField: TextField, test: Any?) -> Void
}

class TextField: UITextField {
    weak var my_delegate: TextFieldDelegate?
    
    typealias Handle = (() -> ())
    var handle: Handle?
    
    init(handle: Handle?) {
        self.handle = handle
        super.init(frame: .zero)
    }
    
    required init?(coder: NSCoder) {
        return nil
    }
}

class ViewController: UIViewController, TextFieldDelegate {
    lazy var textField: TextField = {
        let view = TextField(handle: {
            print("Pikachu")
        })
        view.textColor = .black
        view.font = .systemFont(ofSize: 15)
        view.my_delegate = self
        return view
    }()
    let fps: UInt
    var index = 0
    var delegate: Any?
    
    init(fps: UInt) {
        self.fps = fps
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        return nil
    }
    
    deinit {
        print("ViewController deinit")
        
        NotificationCenter.default.removeObserver(self)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(textField)
        textField.placeholder = "Hello World"
        
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(keyboardWillShow(_:)),
                                               name: UIControl.keyboardWillShowNotification,
                                               object: nil)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        textField.frame = .init(x: 10, y: 100, width: 200, height: 40)
    }
    
    @objc func keyboardWillShow(_ noti: Notification) {
        
    }
    
    func textField(_ textField: TextField, test: Any?) {
        
    }
}

上面的代码中

  1. TextFieldDelegate协议声明了一个方法textField (_:test:)
  2. TextField有一个无参无返回值的闭包
  3. 监听了键盘将要出现的通知
    这和OC的使用方法是完全一样的。

相关文章

网友评论

      本文标题:第三十一章 Swift 界面搭建

      本文链接:https://www.haomeiwen.com/subject/seblxctx.html