概述
简介
苹果公司于2019年度 WWDC
全球开发者大会上发布SwiftUI
,它是基于Swift建立的声明式
框架。该框架可以用于 watchOS、tvOS、macOS、iOS 等平台的应用开发。
它的主要目的是帮助开发者从页面布局中解脱出来,将更多的经历放在应用逻辑层面,而不是页面布局以及页面适配方面。
但是,SwiftUI毕竟时间短,有一些功能还没有完善,甚至有些控件是SwiftUI无法满足的。而且对于一个有着多年UIKit框架的开发经验的开发者来说,对于将UIKit封装成SwiftUI是必要的,因此,这篇文章会以UIKit的封装入手,来进行SwiftUI学习的开篇。
UIViewRepresentable
协议
对于SwiftUI的工程的创建,以及基础的View的搭建,我相信不需要我来介绍了,可自行到苹果官方文档中进行查看
UIViewRepresentable
协议是用于将UIView框架封装成SwiftUI的View的。协议内容包括:
associatedtype UIViewType : UIView
要呈现的视图func makeUIView(context: Self.Context) -> Self.UIViewType
UIView的初始化方法,相当于init方法func updateUIView(_ uiView: Self.UIViewType, context: Self.Context)
当SwiftUI中有新内容更新到UIView上static func dismantleUIView(_ uiView: Self.UIViewType, coordinator: Self.Coordinator)
移除UIViewassociatedtype Coordinator = Void
协调UIViewfunc makeCoordinator() -> Self.Coordinator
创建自定义实例,当UIView中有更改时传达给 SwiftUI 界面。typealias Context = UIViewRepresentableContext<Self>
Context
从协议中基本可以看出我们在自定义View
时所需要调用的方法了。
注意
UIViewRepresentable
协议必须使用struct
类型,如果使用class
或enum
类型时则会报错。- 如果需要给视图添加方法时,需要自定义
Coordinator
类,并遵循NSObject
协议 - 并在
makeCoordinator
方法中返回Coordinator
类的对象
实战
好了,到目前为止,UIKit的框架封装原理已经完毕。下面自定义UITextView
,可以直观的查看UIViewRepresentable
协议。
这是一个比较简单的UITextView
的封装,由于SwiftUI
中目前并没有提供多行文本输入,而在应用中,不可避免的会使用到多行文本输入。
import SwiftUI
struct SimpleTextView: UIViewRepresentable {
// 指定Context 可不写
typealias Context = UIViewRepresentableContext<SimpleTextView>
/// 自定义TextView的属性
@State var placeholder: String = ""
@Binding var text: String
@State var onEditingChange: ((Bool) -> Void)? = nil
// 创建UITextView
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.delegate = context.coordinator
textView.font = UIFont.init(name: "PingFang SC", size: 14)
textView.backgroundColor = .clear
textView.textColor = UIColor(0xabbfcc)
textView.text = placeholder
return textView
}
// 更新UITextView中的值
func updateUIView(_ textView: UITextView, context: Context) {
if textView.text != self.placeholder && !context.coordinator.isEditing {
textView.text = text
}
}
// 用于UITextView的扩展,由于需要使用UITextViewDelegate协议方法,因此该方法需实现
func makeCoordinator() -> Coordinator {
return Coordinator.init(self.placeholder, text: $text, onEditingChange: self.onEditingChange)
}
// 用于实现UITextViewDelegate方法
class Coordinator: NSObject, UITextViewDelegate {
var text: Binding<String>
var placeholder: String = ""
var isEditing = false
var onEditingChange: ((Bool) -> Void)?
init(_ placeholder: String = "", text: Binding<String>, onEditingChange: ((Bool) -> Void)? = nil) {
self.placeholder = placeholder
self.text = text
self.onEditingChange = onEditingChange
}
func textViewDidChange(_ textView: UITextView) {
self.text.wrappedValue = textView.text
}
func textViewDidBeginEditing(_ textView: UITextView) {
if textView.text.isEmpty || textView.text == self.placeholder {
textView.text = ""
self.text.wrappedValue = ""
} else {
self.text.wrappedValue = textView.text
}
self.isEditing = true
self.onEditingChange?(true)
}
func textViewDidEndEditing(_ textView: UITextView) {
if textView.text.isEmpty || textView.text == self.placeholder {
textView.text = self.placeholder
self.text.wrappedValue = ""
} else {
self.text.wrappedValue = textView.text
}
self.isEditing = false
self.onEditingChange?(false)
}
}
}
从上面的代码中就可以比较直观的查看该协议了。后续我会慢慢的讲解SwiftUI中的属性定义名称如 @State
, @Binding
, @Published
, @Environment
, @ObservedObject
等所代表的含义以及相对于Swift中的含义。
最后
以上就是舒适含羞草为你收集整理的iOS SwiftUI ☞ UIKit框架的封装使用的全部内容,希望文章能够帮你解决iOS SwiftUI ☞ UIKit框架的封装使用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复