快速上手iOS UIKit UIKit是苹果官方的framework, 其中包含了各种UI组件, window和view, 事件处理, 交互, 动画, 资源管理等基础设施支持. 按照前面的介绍, 用UIKit写UI可以用storyboard(Interface Builder)和代码两种方式. 大体的思路都是添加组件后, 设置属性, 设置尺寸位置约束, 处理响应事件. 这里主要介绍用代码写的情形. 希望这篇文章, 可以帮你快速上手UIKit, 熟悉常用的组件, 完成一些简单的UI界面相关任务. 在代码中写UI的基本步骤 在代码中写UI的步骤大致是:
- 初始化.
- addSubview添加到当前view, 或hierarchy中的其他可达view.
- 设置约束.
比如:
class ViewController: UIViewController { var myLabel: UILabel! override func loadView() { view = UIView() view.backgroundColor = .white // 创建实例 myLabel = UILabel() myLabel.translatesAutoresizingMaskIntoConstraints = false myLabel.text = "Hello" // 添加到view中 view.addSubview(myLabel) // 设置约束 NSLayoutConstraint.activate([ myLabel.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor), myLabel.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor), ]) } }
这里有几点说明:
- var** myLabel: UILabel! 组件字段这样声明有lateinit的作用, 如果不带!会报错, 说controller没有init方法.
- 如果在代码中设置UI组件的constraints, 那么这个属性经常要设置为false: translatesAutoresizingMaskIntoConstraints = **false**. 如果组件的位置是通过frame来设置的, 则不用设置这个属性.
- 约束有多种写法, 这里只是其中一种, 用anchor的方式.
常用组件 文字: UILabel 设置文字等属性:
myLabel = UILabel() myLabel.translatesAutoresizingMaskIntoConstraints = false myLabel.font = UIFont.systemFont(ofSize: 24) myLabel.text = "Hello" myLabel.numberOfLines = 0 myLabel.textAlignment = .right
给UILabel设置点击事件:
myLabel.isUserInteractionEnabled = true let tapGesture = UITapGestureRecognizer(target: self, action: #selector(userDidTapLabel(tapGestureRecognizer:))) myLabel.addGestureRecognizer(tapGesture)
点击事件处理方法:
@objc func userDidTapLabel(tapGestureRecognizer _: UITapGestureRecognizer) { print("label clicked!") }
这里有#selector, 对应的userDidTapLabel方法要加上@objc. 便于OC的代码调用能找到swift的方法. 给UILabel设置点击事件和UIButton不同, 这点我们后面说继承关系的时候解释一下. 按钮: UIButton 设置文字:
submitButton = UIButton(type: .system) submitButton.translatesAutoresizingMaskIntoConstraints = false submitButton.titleLabel?.font = UIFont.systemFont(ofSize: 36) submitButton.setTitle("SUBMIT", for: .normal) submitButton.setTitleColor(.black, for: .normal)
设置点击事件:
submitButton.addTarget(self, action: #selector(submitTapped), for: .touchUpInside) @objc func submitTapped(_ sender: UIButton) { }
这里使用@objc的理由同上. 基本上我们在iOS代码中用到#的时候, 对应的方法都要加上@objc. 输入框: UITextField
myTextField = UITextField() myTextField.translatesAutoresizingMaskIntoConstraints = false myTextField.placeholder = "What's your name?" myTextField.textAlignment = .center myTextField.font = UIFont.systemFont(ofSize: 44)
想要禁用输入框可以这样:
myTextField.isUserInteractionEnabled = false
弹框 在app里简单的交互我们经常需要弹出一个对话框:
let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Ok", style: .default)) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel)) present(alert, animated: true)
其中preferredStyle有.alert和.actionSheet两种. .alert是中心的对话框, 一般用于信息提示或者确认操作; .actionSheet是底部的bottom sheet, 一般用来在几个选项中做选择. 其他
- view中比较常用的属性isHidden, 控制view是否需要隐藏.
- 所有的UIView都有一个layer属性.
设置border的宽度和颜色就在layer上设置. CALayer在UIView之下. 所以不知道UIColor, 只知道CGColor.
本文仅列出几个常用组件, 更多的请看官方示例. 这里可以下载 继承关系 NSObject是所有Cocoa Touch class的基类. 所有UIKit中的类都是它的子类. 这里有一个类关系的图:
DSC0000.jpg
2022-10-25 11:07 上传
我们这里不展开讲述所有了, 只解答一下前面提出的关于UILabel点击事件的问题.
DSC0001.jpg
2022-10-25 11:07 上传
这里可以看到UILabel和UIButton虽然都继承了UIView, 但是UIButton的继承层次更深一些, 它还继承了了UIControl. 可以看到和UIButton平级的还有好几个子类. Controls使用的是target-action机制, 所有的action都通过方法: addTarget(_:action:for:) 添加. 约束Constraints 当在代码中设置约束时, 有三种选择:
- 使用layout anchors.
- 使用NSLayoutConstraint类.
- 使用Visual Format Language.
上面我们提到过的就是其中Layout Anchors的写法: 初级单个写法:
buttonsView.topAnchor.constraint(equalTo: view.centerYAnchor).isActive = true buttonsView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true buttonsView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true buttonsView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
放进数组里批量激活写法:
NSLayoutConstraint.activate([ buttonsView.topAnchor.constraint(equalTo: view.centerYAnchor), buttonsView.bottomAnchor.constraint(equalTo: view.bottomAnchor), buttonsView.leadingAnchor.constraint(equalTo: view.leadingAnchor), buttonsView.trailingAnchor.constraint(equalTo: view.trailingAnchor), ])
感觉是对新手比较直观的一种写法. 其他写法文末有参考文档. PS: 项目中更流行用 SnapKit. 区域限制
- safeAreaLayoutGuide : 去掉圆角和刘海.
- layoutMarginsGuide : safe area的内部再加上一些额外的margin.
Bonus
- 友情提示: 在xcode里就可以看官方文档, 快捷键是Cmd + Shift + 0.
References
- UIKit Documentation
- UIKit Catalog
- https://codewithchris.com/swift-tutorial-complete/#uikit
- Programmatically Creating Constraints
作者: 圣骑士Wind 出处: 博客园: 圣骑士Wind Github: https://github.com/mengdd 微信公众号: 圣骑士Wind
|