ios入门实例(二): 天气预报app

2,296 阅读3分钟

前言:

本章节通过Swift SwiftUI创建一个简单的天气预报app,主要功能:显示不同星期下的天气情况,使用到了struct,HStack,Vstack,Image,Text,Color

最终效果:

image.png

创建基本UI

首先创建项目:WeatherForecast(点击查看如何创建ios应用)

修改ContentView.swift代码,添加简单天气信息:星期名称,最高摄氏度,最低摄氏度

// ContentView.swift 
import SwiftUI
struct ContentView: View {
   var body: some View {
        VStack {
+            Text("Mon")
+            Text("High: 70")
+            Text("Low: 50")
        }
        .padding()
    }
}

#Preview {
    ContentView()
}
image.png

页面添加icon

这里我们需要添加个标识天晴的‘太阳’icon,点Xcode右上角‘+’查找适合的icon,具体步骤:

image.png

icon sun.max.fill符合预期使用Image引入到代码内

// ContentView.swift 

           Text("Mon")
+          Image(systemName: "sun.max.fill") 
           Text("High: 70")
           Text("Low: 50")
image.png

给icon设置成黄色

// ContentView.swift 

           Text("Mon")
           Image(systemName: "sun.max.fill")
+              .foregroundColor(Color.yellow)
           Text("High: 70")
           Text("Low: 50")
image.png

添加天气为雨天的信息显示

使用HStack(Horizontal Stack)让多个VStack可在水平方向显示,Xcode中查看HStack使用文档:

image.png

点击查看如何在Xcode中查看文档

// ContentView.swift 
     var body: some View {
+        HStack{
            VStack {
                Text("Mon")
                Image(systemName: "sun.max.fill")
                    .foregroundColor(Color.yellow)
                Text("High: 70")
                Text("Low: 50")
            }
            .padding()

+            VStack {
+                Text("Tue")
+                Image(systemName: "cloud.rain.fill")
+                    .foregroundColor(Color.blue)
+                Text("High: 60")
+                Text("Low: 40")
+           }
+            .padding()
+        }
    }
image.png

struct封装天气信息

这里的‘晴天’和‘雨天’UI显示结构是相同的,可以使用struct封装成一个Subview,通过传递参数显示不同天气, Xcode 编辑器中右键快捷生成Subview

image.png
// ContentView.swift 

     var body: some View {
       HStack{
+          ExtractedView()
           
           VStack {
               Text("Tue")
                Image(systemName: "cloud.rain.fill")
                    .foregroundColor(Color.blue)
                Text("High: 60")
                Text("Low: 40")
           }
            .padding()
        }
    }
    ...
    
+ struct ExtractedView: View {
+   var body: some View {
+      VStack {
+           Text("Mon")
+           Image(systemName: "sun.max.fill")
+               .foregroundColor(Color.yellow)
+           Text("High: 70")
+           Text("Low: 50")
+       }
+        .padding()
+    }
+ }

为了好理解代码这里Subview改名: ExtractedView改为DayForecast,‘雨天’也使用DayForecast

// ContentView.swift 

     var body: some View {
       HStack{
+         DayForecast()
+         DayForecast()
        }
    }
image.png

struct 传入参数

通过传参day(星期名称),high(最高摄氏度),low(最低摄氏度)形式显示晴天,雨天信息

// ContentView.swift 

     var body: some View {
       HStack{
+        DayForecast(day:"Mon",high:70,low:50)
+        DayForecast(day:"Mon",high:60,low:40)
        }
    }
    
struct DayForecast: View {
+   let day:String
+   let high: Int
+   let low:Int
   
    var body: some View {
      VStack {
+           Text(day)
            Image(systemName: "sun.max.fill")
                .foregroundColor(Color.yellow)
+            Text("High: \(high)")
+            Text("Low: \(low)")
      }
}  
image.png

其中语法说明可参考官网示意图:

image.png

这里字符串的拼接方法需要注意:

 Text("High: \(high)")

high 为Int类型 ,拼接字符串的方法有点类似前端es6中的模板字符串

通过var 控制icon样式和颜色

首先通过传入 isRainy:Bool 来判断是否为雨天,在通过该变量控制icon的颜色和样式

struct ContentView: View {
    var body: some View {
        HStack{
+          DayForecast(day:"Mon",high:70,low:50,isRainy:false)
+          DayForecast(day:"Tue",high:60,low:40,isRainy:true)
        }
    }
}

struct DayForecast: View {
    let day: String
    let high: Int
    let low:Int
+   let isRainy:Bool
+   var iconName:String{
+        if isRainy{
+            return "cloud.rain.fill"
+        }else{
+            return "sun.max.fill"
+       }
+   }

+    var iconColor:Color{
+        if isRainy{
+            return Color.blue
+       }else{
+           return Color.yellow
+       }        
+    }

    var body: some View {
        VStack {
           Text(day)
+            Image(systemName: iconName)
+               .foregroundColor(iconColor)
            Text("High: \(high)")
            Text("Low: \(low)")
        }
        .padding()
    }
}
image.png

通过Font,Color,padding微调整体样式

struct DayForecast: View {
    ...
  var body: some View {
        VStack {
            Text(day)
 +              .font(Font.headline) // 加粗
            Image(systemName: iconName)
                .foregroundColor(iconColor)
 +               .font(Font.largeTitle) // 图标放大
 +               .padding(5) //增大边距
            Text("High: \(high)")
+                .fontWeight(Font.Weight.semibold) // 加粗
            Text("Low: \(low)")
+               .fontWeight(Font.Weight.medium)  // 加粗
+               .foregroundStyle(Color.secondary) // 灰色
        }
        .padding()
  }
}
image.png