Swift学习笔记34-MVC架构,SwiftUI与UIkit混编练习
2026/5/30 1:34:06 网站建设 项目流程

Model可以分为三种:

1.存档数据的传输Model

2.网络请求,请求到的数据的Model

3.从数据库拿到的Model·1

MVC的Model

4.页面Model:用于标记页面渲染的元素,是由前三个model生成来的。

一个页面一个Model,除非只有一个元素不需要用结构体包裹;
可以把共有的部分弄在Base里,然后和他有关的子类直接继承它。

如果一个Model里大多数内容都不需要的话,就不要传进去。

只作为Model中static函数里的参数,到时候再把1.2.3类型的Model传进去就好了,这样就可以避免把一整个超大Model传来传去。

一些固定的东西,比如颜色,可以存在一个固定的页面,而共用的东西,应该写在Public里。

网络请求到的Model

//// SImpleReportModel.swift// RequestPratice_0525//// Created by sakiko on 2026/5/25.//structSimpleReportModel{varadvantage:Stringvarcareer:Stringvarcelebritys:Stringvardisadvantage:Stringvarid:Intvarpairing:Stringvarresult_str:String//根据传入的字典中的键来取键值,再将其传入Modelstaticfuncbase(with dic:[String:Any])->SimpleReportModel{letadvantage:String=dic["advantage"]as?String??""letcareer:String=dic["career"]as?String??""letcelebritys:String=dic["celebritys"]as?String??""letdisadvantage:String=dic["disadvantage"]as?String??""letid:Int=dic["id"]as?Int??0letpairing:String=dic["pairing"]as?String??""letresult_str:String=dic["result_str"]as?String??""returnSimpleReportModel(advantage:advantage,career:career,celebritys:celebritys,disadvantage:disadvantage,id:id,pairing:pairing,result_str:result_str)}staticfuncempty()->SimpleReportModel{returnSimpleReportModel(advantage:"",career:"",celebritys:"",disadvantage:"",id:0,pairing:"",result_str:"")}}

用于存放渲染UI元素的Model

structDichoBase{vari:Intvare:Intvarn:Intvars:Intvarf:Intvart:Intvarp:Intvarj:Intvarcolors:[String]=["yellow_eightFuncBg","green_eightFuncBg","blue_eightFuncBg","purple_eightFuncBg"]varmbtiColor:Stringstaticfuncbase(with eightBase:EightFuncBase)->DichoBase{print(eightBase)lete=eightBase.fe_value+eightBase.te_value+eightBase.ne_value+eightBase.se_valueleti=eightBase.fi_value+eightBase.ti_value+eightBase.si_value+eightBase.ni_valueletn=eightBase.ni_value+eightBase.ne_valuelets=eightBase.si_value+eightBase.se_valueletf=eightBase.fe_value+eightBase.fi_valuelett=eightBase.ti_value+eightBase.te_valueletp=eightBase.si_value+eightBase.se_value+eightBase.ni_value+eightBase.ne_valueletj=eightBase.fe_value+eightBase.fi_value+eightBase.ti_value+eightBase.te_valueletcolors=ReportColors.getColors(with:eightBase.result_str)returnDichoBase(i:i,e:e,n:n,s:s,f:f,t:t,p:p,j:j,mbtiColor:colors)}}
MVC的ViewController

一个ViewController必有一个View,这个View新开一页写,通常是用SwiftUI写,然后再创建这个View的实例将其扩展到全屏显示。

MVC的View

这里就是真正写UI的地方,是UI层,用的SwiftUI,需要变的地方就用对应的Model中的变量表示。

一个大View来套ScrollView, 传数据Model进来,再把数据Model传进需要的Cell里,逐个打印。

整页的View:也就是ViewController的View

structReportView:View{varmodel:SimpleReportModelvareightFuncBase:EightFuncBasevarbody:someView{ZStack{ReportMainCell(reportMainBase:ReportMainBase(eightBase:eightFuncBase,bg_img:"result_img_\(ReportColors.getColors(with:model.result_str))bg"))ScrollView(.vertical,showsIndicators:false){//result_img_\(ReportColors.getColors(with: m.result_str))bgVStack{ReportViewTitleCell(reportViewTitileModel:ReportViewTitleModel.getBgColor(with:model.result_str))Spacer()EightFuncMoCell(eightFuncMoModel:EightFuncMoModel.getColor(with:eightFuncBase))Spacer()DichoCell(dichoBase:DichoBase.base(with:eightFuncBase))Spacer()EightFuncOrderCell(eightFuncOrderModel:EightFuncOrderModel.getEightFuncsOrder(with:model.result_str))Spacer()AdvantageCell(advantageModel:AdvantageModel.getAdvantage(with:model))Spacer()DisadvantageCell(disadvantageModel:DisadvantageModel.getAdvantage(with:model))Spacer()CareerCell(careerModel:CareerModel.getCareerStr(with:model))Spacer()PairCell(pairModel:PairModel.get_names_details(with:model.result_str))Spacer()CelebritiesCell(celebritiesModel:CelebritiesModel.getImgs(with:model))}}}}}

Cell,也就是单独部分的View

//// CelebritiesCell.swift// RequestPratice_0525//// Created by sakiko on 2026/5/29.//importSwiftUIstructCelebritiesCell:View{varcelebritiesModel:CelebritiesModel// var eightFuncBase: EightFuncBasevarbody:someView{ZStack{RoundedRectangle(cornerRadius:20).foregroundColor(.white).frame(width:SCREENWIDTH-32)VStack{HStack{Image("result_img_cele_\(celebritiesModel.color)titlebg").resizable().frame(width:175,height:42).offset(x:16+16)Spacer()}.padding(.top,16)VStack{//头像与名字ForEach((0..<celebritiesModel.celeHeadImg.count),id:\.self){idxinletceleName=celebritiesModel.celeHeadImg[idx]letceleName_str=NSLocalizedString(celeName,comment:"")letceleName_front=CelebritiesModel.clipCeleName_front(with:celeName_str)letceleName_behind=CelebritiesModel.cilpCeleName_behind(with:celeName_str)HStack{Image(celeName).resizable().frame(width:32,height:32).cornerRadius(16).offset(x:32)VStack(alignment:.leading){Text(celeName_front).font(.system(size:14)).foregroundColor(.black)Text(celeName_behind).font(.system(size:12)).foregroundColor(.gray).offset(y:2)}.offset(x:32).frame(maxWidth:.infinity,alignment:.leading)Spacer()}.padding(.bottom,8)Text(CelebritiesModel.getDetailIntros(with:celeName)).font(.system(size:14)).foregroundColor(.black).frame(width:SCREENWIDTH-32-32).lineSpacing(4).padding(.bottom,24)// Spacer()}}}}}}

其他:

Text(advantageModel.advantage.replacingOccurrences(of: "-", with: "\n"))

批量更改请求到的文件换行符

矩形切圆角,矩形设置背景渐变。

RoundedRectangle(cornerRadius:10).frame(width:CGFloat((Double(funcNum)/90)*CGFloat(SCREENWIDTH-((16+18)*2))),height:12).background(LinearGradient(colors:[Color(eightFuncColor).opacity(0.2),Color(eightFuncColor)],startPoint:.leading,endPoint:.trailing)).foregroundColor(.clear).clipShape(RoundedRectangle(cornerRadius:10))

拆分从网络上请求下来的字符串,遍历全部元素,并将其存放在数组中

letsub_career=String(m.career).split(separator:"、").map(String.init)print(sub_career)

SwiftUI使用数组遍历数组中的元素,实现打印多个组件的效果。

VStack{ForEach((0..<careerModel.career_str_arr.count),id:\.self){idxinZStack{RoundedRectangle(cornerRadius:16).frame(height:22).foregroundColor(Color(career_colorSet[idx]))Text("\(careerModel.career_str_arr[idx])").font(.system(size:14)).foregroundColor(.black)}}

SwiftUI图片旋转(默认围绕中心旋转)

2D 平面旋转:.rotationEffect()

这是最常用的 API,让图片围绕某一个中心点在屏幕平面内旋转。

Image("your_image_name").resizable().frame(width:100,height:100).rotationEffect(.degrees(45))// 🔄 顺时针旋转 45 度

SwiftUI的text对齐方式

.multilineTextAlignment(.center)

SwiftUI让VStack里的内容绝对靠左, 加在最下面

.frame(maxWidth: .infinity, alignment: .leading)

VStack(alignment:.leading){Text(celeName_front).font(.system(size:14)).foregroundColor(.black)// .offset(x: 8)Text(celeName_behind).font(.system(size:12)).foregroundColor(.gray)// .offset(x: 4)}.offset(x:32).frame(maxWidth:.infinity,alignment:.leading)

Swift中除法是默认整除,小数除法要加Double或者CGFloat。要根据比例去表示的话,必须得加,否则很有可能得出的数被舍为0

RoundedRectangle(cornerRadius:10).frame(width:CGFloat(Double(dichoBase.s)/180)*120,height:12).foregroundColor(Color("green_eightFunc"))

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询