布局案例
水果列表切换
swift
import SwiftUI
func myFood() -> String {
return ["🍓", "🍒", "🍇", "🍉", "🍊", "🍐", "🍎", "🍌"].randomElement()!
}
struct ContentView: View {
@State private var todat = myFood()
var body: some View {
VStack {
Spacer() // 撑开
Text("\(todat)") // html 框架
.font(.system(size: 100)) // css 样式
.padding()
Spacer() // 撑开
Button("今天吃啥?") {
// 脚本
todat = myFood()
}
.padding()
.background(.teal)
.foregroundColor(.white)
.cornerRadius(30)
Spacer() // 撑开
}
.padding()
}
}
#Preview {
ContentView()
}
增加心跳数量
swift
import SwiftUI
struct ContentView: View {
@State var num = 12
var body: some View {
VStack {
Spacer()
Image(systemName: "heart")
.font(.largeTitle)
.padding()
.foregroundColor(.white)
.bold()
// 设置背景
.background {
Circle()
.fill(.pink)
}
.shadow(radius: 5)
// 设置前景
.overlay(alignment: .bottomTrailing) {
Circle()
.fill(.green)
.frame(width: 25, height: 25)
}
// 设置前景
.overlay(alignment: .bottomTrailing) {
Text("\(num)")
.foregroundStyle(.white)
.frame(width: 25, height: 25)
}
Spacer()
Button("增加数量") {
num = num + 1
}
Spacer()
}
}
}
#Preview {
ContentView()
}
水平垂直滚动
swift
import SwiftUI
struct ContentView: View {
var body: some View {
ScrollView(.vertical) {
ScrollView(.horizontal) {
HStack {
ForEach(1..<20) { index in
Text("\(index)")
.font(.largeTitle)
.padding()
.background(.orange)
}
}
}
.scrollIndicators(.hidden) // 是否显示滚动指示器
VStack {
ForEach(1..<40) { index in
HStack {
Circle()
.fill(.red)
.frame(width: 20, height: 20)
Text("这是一个标题\(index)")
}
}
}
}
.defaultScrollAnchor(.top) // 模式开始滚动的位置
.scrollIndicators(.hidden) // 是否显示滚动指示器
.scrollContentBackground(.visible) // 滚动的时候是否显示键盘
}
}
#Preview {
ContentView()
}
Button 组件
swift
import SwiftUI
struct CustomButton: View {
var title: String
var color: Color
var action: () -> Void
var body: some View {
Button(action: action) {
Text(title)
.foregroundColor(.white)
.padding()
.padding(.horizontal, 20)
.background(color)
.cornerRadius(8)
}
}
}
struct ContentView: View {
var body: some View {
VStack {
CustomButton(title: "主要按钮", color: .blue) {
print("主要按钮 点击了")
}
CustomButton(title: "成功按钮", color: .green) {
print("成功按钮 点击了")
}
CustomButton(title: "危险按钮", color: .red) {
print("危险按钮 点击了")
}
}
}
}
#Preview {
ContentView()
}
Swift Logo
swift
import SwiftUI
struct ContentView: View {
var body: some View {
Spacer()
Image(systemName: "swift")
.font(.system(size: 300))
.foregroundStyle(
LinearGradient(
colors: [.yellow, .red],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)
.shadow(radius: 15)
Spacer()
}
}
#Preview {
ContentView()
}
筛选食物完整案例
包括筛选、添加喜欢、查看喜欢、滑动操作、我的页面、页面跳转、头像加载等功能
swift
import SwiftUI
let foods: [String] = ["🍒", "🍉", "🥒", "🌽", "🥬", "🥕", "🍅", "🍎", "🍐", "🍇", "🐗", "🍍", "🍈", "🍊", "🍃", "🥥", "🫘", "🎃", "🍳", "🥚", "🌳", "🍔", "🍕", "🥩", "🐮", "🐑", "🐷", "🐔", "🦆", "🍜", "🍚"]
var likeList: [String] = []
class LikeListViewModel: ObservableObject {
@Published var likes: [String] = []
func addLike(_ food: String) {
likes.append(food)
}
func removeLike(at index: Int) {
likes.remove(at: index)
}
}
// 获取随机食物
func getFoods() -> String {
return foods.randomElement() ?? "未找到"
}
// 首页
struct HomePage: View {
@State var activeFood = getFoods()
@State private var showAlert = false
@ObservedObject var likeListViewModel: LikeListViewModel
var body: some View {
VStack {
Spacer()
Text(activeFood)
.font(.system(size: 150))
Spacer()
Button("筛选食物") {
activeFood = getFoods()
}
.padding()
.padding(.horizontal)
.background(.blue)
.foregroundColor(.white)
.bold()
.cornerRadius(16)
Button("喜欢") {
likeListViewModel.addLike(activeFood)
showAlert = true
}
.alert(isPresented: $showAlert, content: {
Alert(title: Text("提示"), message: Text("喜欢成功"), dismissButton: .default(Text("确定")))
})
.foregroundColor(.blue)
.padding(.top, 20)
Spacer()
}
}
}
// 喜欢页面
struct LovePage: View {
// @Binding var fruits: [String]
// @ObservedObject var likeListViewModel = LikeListViewModel()
@ObservedObject var likeListViewModel: LikeListViewModel
var body: some View {
if !likeListViewModel.likes.isEmpty {
List {
ForEach(likeListViewModel.likes, id: \.self) { item in
Text("我喜欢的食物:\(item)")
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
Button("删除") {
// Delete action
// LikeListViewModel.removeLike()
}
.tint(.red)
Button("置顶") {
// Top action
}
.tint(.orange)
Button("不显示") {
// Hide action
}
.tint(.blue)
}
.swipeActions(edge: .leading, allowsFullSwipe: false) {
Button("已完成") {
// Completed action
}
.tint(.black)
}
.badge("食物")
}
// .onDelete(perform: delete)
}
} else {
Text("暂无喜欢内容")
}
}
}
struct MyDetail: View {
@State var sttingItem: String
var body: some View {
NavigationView {
VStack {
Text(sttingItem)
}
}
.navigationTitle(sttingItem)
}
}
// 我的
struct MyPage: View {
@State var infoOptions = ["账号设置", "联系客服", "通用设置"]
var body: some View {
// let imgSrc = URL(string: "https://picsum.photos/200")
let imgSrc = URL(string: "https://finecare-fxk.fxkang.com/rich-text/image/2023-12-22/1187678699633860608.jpg")
NavigationView {
VStack {
// AsyncImage(url: imgSrc) // 直接显示图片
AsyncImage(url: imgSrc) { returnedImage in
returnedImage
.resizable()
// .scaledToFit()
.frame(width: 100, height: 100)
.cornerRadius(70)
} placeholder: {
ProgressView() // loading 动画
Text("头像加载中")
}
Text("我的昵称")
.textSelection(.enabled) // 分享或复制
List {
ForEach(infoOptions, id: \.self) { item in
NavigationLink(
destination: MyDetail(sttingItem: item), label: {
Text(item)
}
)
}
}
// .listStyle(GroupedListStyle())
.navigationTitle("我的信息")
}
}
}
}
struct ContentView: View {
@StateObject var likeListViewModel = LikeListViewModel()
var body: some View {
TabView {
HomePage(likeListViewModel: likeListViewModel)
.tabItem {
Image(systemName: "house")
Text("首页")
}
LovePage(likeListViewModel: likeListViewModel)
.tabItem {
Image(systemName: "heart.fill")
Text("喜欢")
}
MyPage()
.tabItem {
Image(systemName: "person")
Text("我的")
}
}
}
func delete(indexSet: IndexSet) {
print(indexSet)
}
}
#Preview {
ContentView()
}
TabView 标签页面切换 ß
swift
import SwiftUI
struct TabDemoView: View {
@State var active = 0
var body: some View {
NavigationView {
VStack {
TabView(selection: $active) {
ScrollView {
Text("第0页")
}.tag(0)
ScrollView {
Text("第1页")
}.tag(1)
ScrollView {
Text("第2页")
}.tag(2)
}
.tabViewStyle(.page)
}
}
}
}
#Preview {
TabDemoView()
}
调用接口拿到数据展示
swift
import Alamofire
import SwiftUI
// Step 1: 创建一个 Model 来表示数据结构
struct CatImage: Identifiable, Decodable {
let id: String
let url: URL
let width: Int
let height: Int
}
struct Api {
private let baseURL = "https://api.thecatapi.com/v1"
private func http(url: String, callback: @escaping ([CatImage]) -> Void) {
AF.request("https://api.thecatapi.com/v1\(url)")
.responseDecodable(of: [CatImage].self) { response in
if let images = response.value {
// 成功获取到响应数据
callback(images)
} else if let error = response.error {
// 请求失败
print("Error fetching images: \(error)")
callback([])
}
}
}
func getList(callback: @escaping ([CatImage]) -> Void) {
http(url: "/images/search?limit=10&page=1", callback: callback)
}
}
struct DemoView: View {
@State private var catImages: [CatImage] = []
let API = Api()
var body: some View {
List(catImages) { catImage in
VStack(alignment: .leading) {
Text("ID: \(catImage.id)")
.aspectRatio(contentMode: .fit)
Text("Width: \(catImage.width), Height: \(catImage.height)")
}
}
.onAppear {
API.getList { images in
catImages = images
}
}
}
}
#Preview {
DemoView()
}