项目初始化(修改为纯代码项目)
1.修改 AppDelegate.swift
和 ViewController.swift
文件
2.删除 SceneDelegate.swift
和 Main.storyboard
文件
3.修改如图所示项
安装第三方库(以SnapKit库为例)
安装CocoaPods
$ gem install cocoapods
初始化项目(添加Podfile
配置文件)
$ pod init
修改Podfile
文件
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'ExDemoApp' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for ExDemoApp
pod 'SnapKit'
end
安装
$ pod install
打开ExDemoApp.xcworkspace
项目并向ViewController.swift
添加示例代码
//
// ViewController.swift
// ExDemoApp
//
// Created by ProsperLee on 2023/2/20.
//
import UIKit
import SnapKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let label: UILabel = UILabel()
view.addSubview(label)
label.text = "Hello"
label.textColor = .red
label.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.centerY.equalToSuperview()
}
}
}
运行效果
桥接OC库(QMUIKit)
安装QMUIKit
# Podfile 文件
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'ExDemoApp' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for ExDemoApp
pod 'SnapKit'
pod 'QMUIKit'
end
$ pod install
方式一:触发xcode自动创建桥接文件机制
方式二:手动创建xcode桥接文件
测试桥接是否成功
//
// ViewController.swift
// ExDemoApp
//
// Created by ProsperLee on 2023/2/20.
//
import UIKit
import SnapKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let button = QMUIButton()
button.adjustsButtonWhenHighlighted = true
button.setTitle("按钮", for: .normal)
button.setTitleColor(.white, for: .normal)
button.backgroundColor = UIColor.tintColor;
button.highlightedBackgroundColor = UIColor.tintColor;
button.layer.cornerRadius = 4
view.addSubview(button)
button.snp.makeConstraints { make in
make.width.equalTo(200)
make.height.equalTo(40)
make.centerX.equalToSuperview()
make.centerY.equalToSuperview()
}
button.addTarget(self, action: #selector(buttonClick), for: UIControl.Event.touchUpInside)
}
@objc func buttonClick(){
print("点击了")
}
}
封装视图并进行导航跳转
效果
项目目录结构
配置导航跳转
//
// AppDelegate.swift
// ExDemoApp
//
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let controller = ViewController()
window = UIWindow(frame: UIScreen.main.bounds)
// 包装一层导航控制器用于在视图间跳转
window!.rootViewController = UINavigationController(rootViewController: controller)
window?.makeKeyAndVisible()
return true
}
}
创建要跳转到的Controller
//
// SettingController.swift
// 设置界面
//
import UIKit
class SettingController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
title = "设置界面"
view.backgroundColor = UIColor(red: 250 / 255, green: 250 / 255, blue: 250 / 255, alpha: 1)
}
}
进行跳转
//
// ViewController.swift
// ExDemoApp
//
import UIKit
import SnapKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = QMUIButton()
button.setTitle("进入设置页面", for: .normal)
view.addSubview(button)
button.addTarget(self, action: #selector(goto(_:)), for: .touchUpInside)
button.snp.makeConstraints{make in
make.center.equalToSuperview()
}
}
@objc func goto(_ sender: QMUIButton){
print(sender.titleLabel!.text!)
let target = SettingController()
navigationController?.pushViewController(target, animated: true)
}
}
封装视图组件
//
// CellView.swift
// ExDemoApp
//
import UIKit
import SnapKit
class CellView: UIView {
/// 左侧图标
lazy var leftIcon: UIImageView = {
let v = UIImageView();
v.image = UIImage(named: "Setting")
return v;
}()
/// 单元格标题
lazy var title: UILabel = {
let v = UILabel();
v.text = "Setting"
return v;
}()
/// 右侧图标
lazy var rightIcon: UIImageView = {
let v = UIImageView();
v.image = UIImage(named: "More")
return v;
}()
// 初始化组件
init() {
super.init(frame: CGRect.zero)
innerInit()
}
// 从数据中初始化一个视图(必需)
required init?(coder: NSCoder) {
super.init(coder: coder)
innerInit()
}
// 组件UIView初始化
func innerInit(){
backgroundColor = .white
addSubview(leftIcon)
addSubview(title)
addSubview(rightIcon)
}
// 当view被首次添加进父级视图的时候调用
override func didMoveToSuperview() {
super.didMoveToSuperview()
leftIcon.snp.makeConstraints{make in
make.width.equalTo(32)
make.height.equalTo(32)
make.centerY.equalToSuperview()
make.left.equalToSuperview().offset(16)
}
title.snp.makeConstraints{make in
make.centerY.equalToSuperview()
make.left.equalTo(leftIcon.snp.right).offset(10)
}
rightIcon.snp.makeConstraints{make in
make.width.equalTo(20)
make.height.equalTo(20)
make.centerY.equalToSuperview()
make.right.equalToSuperview().offset(-16)
}
}
}
使用组件并配置点击事件
//
// SettingController.swift
// 设置界面
//
import UIKit
class SettingController: UIViewController {
// 懒加载单元格并配置相关属性
lazy var cellView: CellView = {
let v = CellView();
v.leftIcon.image = UIImage(named: "Setting")
v.title.text = "设置"
// 单元格整体添加点击事件
v.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onSettingClick(recognizer:))))
return v;
}()
override func viewDidLoad() {
super.viewDidLoad()
title = "设置界面"
view.backgroundColor = UIColor(red: 250 / 255, green: 250 / 255, blue: 250 / 255, alpha: 1)
view.addSubview(cellView)
cellView.snp.makeConstraints{make in
make.height.equalTo(40)
make.top.equalTo(view.safeAreaLayoutGuide.snp.top);
make.left.equalToSuperview()
make.right.equalToSuperview()
}
}
// 点击事件
@objc func onSettingClick (recognizer:UITapGestureRecognizer){
print(recognizer)
cellView.title.text = "点击了!"
}
}
示例:使用 TangramKit 第三方UI布局库
pod 'TangramKit'
let horzLayout = TGLinearLayout(.horz)
horzLayout.tg_gravity = TGGravity.horz.fill // 所有子视图水平宽度充满布局,这样就不需要分别设置每个子视图的宽度了。
horzLayout.backgroundColor = UIColor.white
horzLayout.tg_width.equal(.fill) // 高度填充父布局的所有剩余空间。
horzLayout.tg_height.equal(60)
horzLayout.tg_bottom.equal(TGLayoutPos.tg_safeAreaMargin)
view.addSubview(horzLayout)
let v1 = QMUIButton();
v1.setTitle("v1", for: .normal)
v1.backgroundColor = .red
v1.tg_height.equal(.fill)
horzLayout.addSubview(v1)
let v2 = QMUIButton();
v2.setTitle("v2", for: .normal)
v2.backgroundColor = .green
v2.tg_height.equal(.fill)
horzLayout.addSubview(v2)
let v3 = QMUIButton();
v3.setTitle("v3", for: .normal)
v3.backgroundColor = .blue
v3.tg_height.equal(.fill)
horzLayout.addSubview(v3)
应用国际化
引用公共字符串
/*
Localizable.strings
ExDemoApp
*/
HomeMenuText = "首页";
//
// ViewController.swift
// ExDemoApp
//
import UIKit
import TangramKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(red: 250 / 255, green: 250 / 255, blue: 250 / 255, alpha: 1)
let horzLayout = TGLinearLayout(.horz)
horzLayout.tg_gravity = TGGravity.horz.fill
horzLayout.backgroundColor = UIColor.orange
horzLayout.tg_width.equal(.fill)
horzLayout.tg_height.equal(60)
horzLayout.tg_bottom.equal(TGLayoutPos.tg_safeAreaMargin)
view.addSubview(horzLayout)
let v1 = QMUILabel();
v1.text = NSLocalizedString("HomeMenuText", comment: "") // 引用公共字符串
v1.backgroundColor = .red
v1.textAlignment = .center;
v1.tg_width.equal(.fill)
v1.tg_height.equal(.fill)
horzLayout.addSubview(v1)
let v2 = QMUILabel();
v2.text = "v2"
v2.backgroundColor = .green
v2.textAlignment = .center;
v2.tg_width.equal(.fill)
v2.tg_height.equal(.fill)
horzLayout.addSubview(v2)
let v3 = QMUILabel();
v3.text = "v3"
v3.backgroundColor = .blue
v3.textAlignment = .center;
v3.tg_width.equal(.fill)
v3.tg_height.equal(.fill)
horzLayout.addSubview(v3)
}
}
启用国际化(修改系统语言查看效果)
应用名称国际化(修改系统语言查看效果)
添加 R.swift 框架
用于优化资源获取访问的方式,如图像、字体等
1.添加依赖
pod 'R.swift'
2.创建运行脚本
"$PODS_ROOT/R.swift/rswift" generate "$SRCROOT/R.generated.swift"
$SRCROOT/R.generated.swift
3.执行编译生成 R.generated.swift
文件,并将其添加到项目根目录
4.使用
/*
Localizable.strings
ExDemoApp
*/
HomeMenuText = "%@, 首页";
//
// ViewController.swift
// ExDemoApp
//
let v1 = QMUILabel();
v1.text = NSLocalizedString(R.string.localizable.homeMenuText("你好"), comment: "")
v1.backgroundColor = .red
v1.textAlignment = .center;
v1.tg_width.equal(.fill)
v1.tg_height.equal(.fill)
horzLayout.addSubview(v1)
颜色统一管理(图片相同)
引入动态颜色生成库
pod 'DynamicColor'
实现
//
// SuperUIColorExtension.swift
// ExDemoApp
//
// 扩展系统颜色
//
import Foundation
import DynamicColor
extension UIColor {
/// 背景颜色 (浅色)
static var bgLightColor: UIColor{return DynamicColor(hex: 0xfafafa)}
/// 背景颜色 (深色)
static var bgDarkColor: UIColor{return DynamicColor(hex: 0x000000)}
/// 背景颜色
static var bgColor: UIColor{
return .initColor(normal: bgLightColor, dark: bgDarkColor)
}
/// 红色
static var red: UIColor{return DynamicColor(hex: 0xff0000)}
/// 绿色
static var green: UIColor{return DynamicColor(hex: 0x00ff00)}
/// 蓝色
static var blue: UIColor{return DynamicColor(hex: 0x00ffff)}
/// 深浅颜色随系统切换
static func initColor(normal: UIColor, dark: UIColor) -> UIColor{
if #available(iOS 13.0, *) {
return UIColor{ traitCollection -> UIColor in
return traitCollection.userInterfaceStyle == .dark ? dark : normal
}
}else{
return normal
}
}
}
//
// ViewController.swift
// ExDemoApp
//
import UIKit
import TangramKit
import DynamicColor
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .bgColor
let horzLayout = TGLinearLayout(.horz)
horzLayout.tg_gravity = TGGravity.horz.fill
horzLayout.backgroundColor = .gray
horzLayout.tg_width.equal(.fill)
horzLayout.tg_height.equal(60)
horzLayout.tg_bottom.equal(TGLayoutPos.tg_safeAreaMargin)
view.addSubview(horzLayout)
let v1 = QMUIButton()
v1.setTitle("v1", for: .normal)
v1.setTitleColor(.red, for: .normal)
v1.tg_width.equal(.fill)
v1.tg_height.equal(.fill)
horzLayout.addSubview(v1)
let v2 = QMUIButton()
v2.setTitle("v2", for: .normal)
v2.setTitleColor(.green, for: .normal)
v2.tg_width.equal(.fill)
v2.tg_height.equal(.fill)
horzLayout.addSubview(v2)
let v3 = QMUIButton()
v3.setTitle("v3", for: .normal)
v3.setTitleColor(.blue, for: .normal)
v3.tg_width.equal(.fill)
v3.tg_height.equal(.fill)
horzLayout.addSubview(v3)
}
}
网络请求 Moya
允许http请求
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
</dict>
</plist>
配置请求地址
//
// Config.swift
// ExDemoApp
//
import Foundation
class Config{
/// 接口地址
static let API_URL = "http://127.0.0.1:8080/";
}
引入网络请求框架
pod 'Moya'
使用请求
// 服务端
let http = require('http');
http.createServer((req, res) => {
res.writeHead(200, { 'Content-type': 'application/json' });
if (req.url === '/api/getUserInfo' && req.method === 'POST') {
let data = '';
req.on('data', (chunk) => {
data += chunk;
});
req.on('end', () => {
console.log(JSON.stringify({code: 200, id: Math.random(), ...JSON.parse(data)}));
res.end(JSON.stringify({code: 200, id: Math.random(), ...JSON.parse(data)}));
});
}
}).listen(8080);
console.log('http://127.0.0.1:8080/');
//
// ViewController.swift
// ExDemoApp
//
import UIKit
import TangramKit
import DynamicColor
import Moya
class ViewController: UIViewController {
var label: QMUILabel = QMUILabel()
override func viewDidLoad() {
super.viewDidLoad()
view = TGRelativeLayout()
view.backgroundColor = .bgColor
let button = QMUIButton()
button.setTitle("请求", for: .normal)
button.tg_width.equal(.wrap)
button.tg_height.equal(.wrap)
button.tg_centerX.equal(0)
button.tg_centerY.equal(0)
button.addTarget(self, action: #selector(handleClick(_ :)), for: .touchUpInside)
view.addSubview(button)
label.text = "暂无数据!"
label.tg_width.equal(.wrap)
label.tg_height.equal(.wrap)
label.tg_centerX.equal(0)
label.tg_centerY.equal(30)
view.addSubview(label)
}
@objc func handleClick (_ sender: QMUIButton){
let provider = MoyaProvider<DefaultService>()
provider.request(.getUserInfo(firstName: "Lee", lastName: "Prosper")) { result in
switch result {
case let .success(moyaResponse):
if moyaResponse.statusCode == 200 {
let data: String = String(data: moyaResponse.data, encoding: .utf8)!
self.label.text = data
print(data)
}
case let .failure(error):
print(error)
}
}
}
}
/// 默认服务
enum DefaultService {
case getUserInfo(firstName: String, lastName: String)
}
extension DefaultService: TargetType {
/// 请求地址
var baseURL: URL { return URL(string: Config.API_URL)! }
/// 接口地址
var path: String {
switch self {
case .getUserInfo:
return "/api/getUserInfo"
}
}
/// 请求方式
var method: Moya.Method {
switch self {
case .getUserInfo:
return .post
}
}
/// 请求参数
var task: Task {
switch self {
case let .getUserInfo(firstName, lastName):
return .requestParameters(parameters: ["first_name": firstName, "last_name": lastName], encoding: JSONEncoding.default)
}
}
/// 请求头
var headers: [String: String]? {
let headers: Dictionary<String, String> = [:]
return headers
}
}
网络请求 Moya/RxSwift
Moya/RxSwift
响应式编程,可以对数据在请求前做一些处理,如:provider.rx.request(.xxx()).filter{... in ...}.subscribe { ... }
引入RxSwift
# pod 'Moya'
pod 'Moya/RxSwift'
pod 'NSObject+Rx'
使用文章来源:https://www.toymoban.com/news/detail-486818.html
// ViewController.swift
import RxSwift
import NSObject_Rx
@objc func handleClick (_ sender: QMUIButton){
let provider = MoyaProvider<DefaultService>()
provider.rx.request(.getUserInfo(firstName: "Lee", lastName: "Prosper"))
.subscribe { event in
switch event {
case let .success(response):
if response.statusCode == 200 {
let data: String = String(data: response.data, encoding: .utf8)!
self.label.text = data
print(data)
}
case let .failure(error):
print(error)
}
}
.disposed(by: rx.disposeBag) // 用于释放subscribe资源
}
解析 json
文章来源地址https://www.toymoban.com/news/detail-486818.html
pod 'HandyJSON'
// ViewController.swift
import Moya
import RxSwift
import NSObject_Rx
import HandyJSON
class UserInfo: HandyJSON {
var code: Int! // 不允许空
var id: Double! // 不允许空
var first_name: String? // 允许空
var last_name: String? // 允许空
required init() {}
}
let provider = MoyaProvider<DefaultService>()
provider.rx.request(.getUserInfo(firstName: "Lee", lastName: "Prosper"))
.subscribe { event in
switch event {
case let .success(response):
if response.statusCode == 200 {
let data: String = String(data: response.data, encoding: .utf8)!
if let object = UserInfo.deserialize(from: data) {
self.label.text = "\(object.code!) \n \(object.id!) \n \(object.first_name!) \n \(object.last_name!)"
print(object.toJSONString(prettyPrint: true)!) // 转json字符串 - {"id":0.86519265844265569,"last_name":"Prosper","code":200,"first_name":"Lee"}
}
}
case let .failure(error):
print(error)
}
}
.disposed(by: rx.disposeBag) // 用于释放subscribe资源
到了这里,关于iOS(一):Swift纯代码模式iOS开发入门教程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!