一、控件
控件是app开发最基础的部分,一个页面不可能没有控件。控件的添加比较简单,在故事板中可以通过拖放的方式添加到页面上。但我总是学不会这种所见即所得的编程方式,还是更习惯通过代码的方式创建控件。
控件即可以写在override func viewDidLoad()外面,也可以写在override func viewDidLoad()里面,写在外面表示全局变量,写在里面表示内部变量。
写代码时,总是想起用到什么控件就顺手在正在编辑的代码附近写上创建新控件的代码,这样做写的时候方便,但后期维护起来麻烦。所以我的习惯是在页面代码编辑完成后,再重新布置一下代码的顺序。
推荐顺序:按照实际布局从上到下来写,需要修改控件属性时,找起来也方便一些。写在外面的时候最好将控件和控件写在一起,变量和变量写在一起。
1.创建控件的写法
- 属性写在外面
let view1 = UIView(frame: CGRect(x: 250, y: 250 - 200, width: 1500, height: 400))
view1.backgroundColor = .gray
- 属性写在里面
var startBtn: UIButton = {
let button = UIButton()
button.setTitle("开始练习", for: .normal)
button.backgroundColor = UIColor(hex: "3DAFAE")
button.layer.cornerRadius = 5
return button
}()
我个人常使用第二种写法,因为看着要工整一些。
2.控件颜色
有些控件默认的颜色并不一样,比如slider滑块的颜色和switch选中后的颜色,页面看起来花花绿绿的,所以需要手动对控件的颜色加以控件。值得注意的是,不同种类的控件控制颜色的属性并不一致,需要平时注意积累。
// 音阶数量滑块
let slider: UISlider = {
let slider = UISlider()
slider.minimumValue = 2
slider.maximumValue = 15
slider.value = 8
slider.tintColor = UIColor(hex: "3DAFAE")
return slider
}()
lazy var startBtn: UIButton = {
let button = UIButton()
button.setTitle("开始练习", for: .normal)
button.backgroundColor = UIColor(hex: "3DAFAE")
button.layer.cornerRadius = 5
return button
}()
let loopSwitch: UISwitch = {
let loopSwitch = UISwitch(frame: CGRect(x: UIScreen.main.bounds.size.width / 2, y: UIScreen.main.bounds.size.height - 100, width: 80, height: 50))
loopSwitch.onTintColor = UIColor(hex: "3DAFAE")
return loopSwitch
}()
let stopBtn: UIButton = {
let button = UIButton()
button.frame.size = CGSize(width: 100, height: 200)
button.setTitle("停止练习", for: .normal)
button.backgroundColor = UIColor(hex: "3DAFAE")
button.layer.cornerRadius = 5
return button
}()

3.滚动控件的使用
滚动控件由于有了滚动的功能,所以也多了一些属性设置。
let scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height - 50)) // 设置了可显示的高度
scrollView.contentSize = CGSize(width: Int(view.frame.size.width), height: Int(label5.frame.origin.y + 100)) // 设置了滚动内容的高度
view.addSubview(scrollView)
scrollView.showsHorizontalScrollIndicator = false // 不显示纵向滚动条
scrollView.showsVerticalScrollIndicator = false // 不显示横向滚动条
二、页面标题
通常情况每个页面都会有一个标题,可以通过以下代码来设置
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.navigationItem.title = "音阶练习"
}
三、标题栏按钮
通常标题栏右侧还会有一些按钮,即节省页面,又突出某个功能的重要性,可以通过以下语句来设置
let shuomingBtn = UIBarButtonItem(
title: "说明",
style: .plain,
target: self,
action: #selector(clickShuomingBarBtn))
let purchaseBtn = UIBarButtonItem(
title: "购买",
style: .plain,
target: self,
action: #selector(clickPurchaseBarBtn))
navigationItem.rightBarButtonItems = [purchaseBtn, shuomingBtn] // 此处是从右到左排序

四、布局
我不太会在故事板中进行布局,还是习惯通过代码的方式来布局。
// 布局顶部精准率标签
let jingzhunlvText: UILabel = {
let label = UILabel()
label.text = "精准率:"
label.font = UIFont.systemFont(ofSize: 18)
label.textAlignment = .right
return label
}()
view.addSubview(jingzhunlvText)
jingzhunlvText.translatesAutoresizingMaskIntoConstraints = false
jingzhunlvText.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true // 顶部与安全区域的顶部平齐
jingzhunlvText.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor).isActive = true // 右边缘与安全区域的中线平齐
jingzhunlvText.heightAnchor.constraint(equalToConstant: 50).isActive = true // 高度为50
五、自定义控件
当系统自带的控件不够用时,需要自己自定义
class Zuobiaozhou: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.clear
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
context.setFillColor(UIColor.red.cgColor)
// context.setStrokeColor(UIColor.red.cgColor)
context.setLineWidth(1)
context.move(to: CGPoint(x: 50, y: 50))
context.addLine(to: CGPoint(x: 50, y: 450))
context.move(to: CGPoint(x: 0, y: 50))
context.addLine(to: CGPoint(x: 50, y: 50))
context.move(to: CGPoint(x: 0, y: 450))
context.addLine(to: CGPoint(x: 50, y: 450))
context.drawPath(using: CGPathDrawingMode.fillStroke)
let fontSize: CGFloat = 20 // 设置字体大小
let attributes: [NSAttributedString.Key : Any] = [
.font: UIFont.systemFont(ofSize: fontSize), // 设置字体样式
// .foregroundColor: UIColor.white // 设置前景色(文字颜色)
]
let attributedText1 = NSMutableAttributedString(string: "-50", attributes: attributes)
var originX: CGFloat = (50 - attributedText1.size().width) / 2 // 计算起始点x坐标
var originY: CGFloat = 50 - attributedText1.size().height // 计算起始点y坐标
attributedText1.draw(at: CGPoint(x: originX, y: originY)) // 将文本绘制到视图上
let attributedText2 = NSMutableAttributedString(string: "50", attributes: attributes)
originX = (50 - attributedText2.size().width) / 2 // 计算起始点x坐标
originY = 400 + attributedText2.size().height // 计算起始点y坐标
attributedText2.draw(at: CGPoint(x: originX, y: originY)) // 将文本绘制到视图上
}
}
然后通过以下代码将自定义控件添加至页面中
// 布局坐标轴
let zuobiaozhou = Zuobiaozhou()
view.addSubview(zuobiaozhou)
zuobiaozhou.translatesAutoresizingMaskIntoConstraints = false
zuobiaozhou.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
zuobiaozhou.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 50).isActive = true
zuobiaozhou.widthAnchor.constraint(equalToConstant: 51).isActive = true
zuobiaozhou.heightAnchor.constraint(equalToConstant: 500).isActive = true
六、动画
在swift中,动画有三种写法
1.
UIView.animate(withDuration: TimeInterval((2 * yinjieNum - 1) * 2), delay: 0, options: .curveLinear, animations: {
self.scrollView.contentOffset.x = CGFloat(2000)
})
这种方式写起来最简单,但是在过程中无法对动画进行控制,.curveLinear表示匀速的意思,因为默认情况下,ios动画是有个加速度的。
2.
let rotatedAnim = CABasicAnimation(keyPath: "bounds.origin.x")
rotatedAnim.duration = 10
rotatedAnim.byValue = 200
rotatedAnim.isRemovedOnCompletion = false
rotatedAnim.fillMode = CAMediaTimingFillMode.forwards
self.scrollView.layer.add(rotatedAnim, forKey: "bounds.origin.x")
这种写法也能实现动画,但感觉只是第一种写法的拆分,依然无法在动画运行时对动画进行控制,所以没有深入研究。
3.
var animator = UIViewPropertyAnimator()
animator = UIViewPropertyAnimator(duration: TimeInterval(2 * (2 * yinjieNum - 1)), curve: .linear) { [self] in
scrollView.contentOffset.x = CGFloat(100 * (2 * yinjieNum - 1)) + 150
}
animator.addCompletion { [self] UIViewAnimatingPosition in
if (loopSwitch.isOn) {
clickStartBtn()
}
}
animator.startAnimation()
推荐这种写法,可能通过变量animator随时控制动画的运行状态
七、页面跳转
1.弹出式跳转
@objc func clickShuomingBarBtn() {
let vc = InfoViewController()
present(vc, animated: true)
}

如果需要将InfoViewController完全覆盖住底层的controller,则需设置controller的modalPresentationStyle属性
@objc func clickShuomingBarBtn() {
let vc = InfoViewController()
vc.modalPresentationStyle = .fullScreen
present(vc, animated: true)
}
2.覆盖式跳转
@objc func clickPurchaseBarBtn() {
if let vc = storyboard?.instantiateViewController(identifier: "purchase") as? ProViewController {
navigationController?.pushViewController(vc, animated: true)
}
}

网友评论