SwiftUI:仿写天气

  • 创建一个新的Xcode项目
  • 选择单视图应用程序,然后单击下一步
  • 为您的应用命名,并确保用户界面为Swift UI
  • 最后,单击“完成”
  • 您新创建的项目见截图:
image

这是您首次创建项目时的默认项目布局。如果模拟器未显示,请单击恢复。

ContentView文件和结构重命名为WeatherApp,并确保在以下位置重命名其引用SceneDelegate

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    
        // Create the SwiftUI view that provides the window contents.
        let weatherApp = WeatherApp()
    
        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = ::UIHostingController(rootView: weatherApp)::
            self.window = window
            window.makeKeyAndVisible()
        }
    }

更改您看到的ContentViewWeatherApp的引用。

每次进行重大更改时,预览都会消失,只需单击“恢复”即可再次显示。

我将逐步更易于理解的UI。这是我要执行的操作分析:

image

image

第1步:自定义导航栏

  1. 创建一个名为NavBarView
  2. 创建了一个带有系统名称的图像,这些图标可以通过从Apple开发人员网站下载SF Symbol来找到这些图像
  3. 我设置resizable()修改器是为了给图像提供一个不同的帧,然后在它之后设置resible()
  4. 我将标题放置Text在2个Spacer视图之间以使其水平居中。
  5. HStackView的所有侧面上添加了一个填充
  6. 将所有内容括在一个VStack块中,并在@State private var selected = 0上面添加 body
    NavBarView.swift应如下所示:
import SwiftUI

struct NavBarView: View {
    
    var country = "深圳天气"
    
    var body: some View{
        HStack {
            Image(systemName: "ellipsis.circle.fill")
                .resizable()
                .frame(width: 25, height: 25)
            Spacer()
            Text(country).font(.title)
            Spacer()
            Image(systemName: "magnifyingglass")
                .resizable()
                .frame(width: 25, height: 25)
            
        }.padding()
    }
}


struct NavBarView_Previews: PreviewProvider {
    static var previews: some View {
        NavBarView()
    }
}

WeatherApp结构现在应如下所示:

struct WeatherApp: View {
     @State private var selected = 0
    
    var body: some View {
        
        VStack {
            NavBarView(country: "深圳天气")
            
            Picker("", selection: $selected){
                     Text("今天").tag(0)
                     Text("明天").tag(1)
                 }.pickerStyle(SegmentedPickerStyle() )
                     .padding(.horizontal)
        }
    }
}

现在,预览应该在屏幕中央显示以下内容:

image

第2步:模型

需要为该步骤创建2个文件,第一个文件是一个模态文件,将保存我们的虚拟数据,另一个文件是MainCardView

import Foundation

struct Weather: Hashable, Identifiable {
    let id: Int
    let day: String
    let weatherIcon: String
    let currentTemp: String
    let minTemp: String
    let maxTemp: String
    let color: String
    
    static var sampleData: [Weather] {
        return [
            Weather(id: 1, day: "星期一", weatherIcon: "sun.max", currentTemp: "30", minTemp: "32", maxTemp: "29", color: "mainCard"),
             Weather(id: 2, day: "星期二", weatherIcon: "sun.dust", currentTemp: "33", minTemp: "32", maxTemp: "29", color: "tuesday"),
             Weather(id: 3, day: "星期三", weatherIcon: "cloud.sun.rain", currentTemp: "32", minTemp: "28", maxTemp: "29", color: "wednesday"),
             Weather(id: 4, day: "星期四", weatherIcon: "cloud.sun.bolt", currentTemp: "33", minTemp: "27", maxTemp: "30", color: "thursday"),
             Weather(id: 5, day: "星期五", weatherIcon: "sun.haze", currentTemp: "30", minTemp: "27", maxTemp: "29", color: "friday"),
             Weather(id: 6, day: "星期六", weatherIcon: "sun.dust", currentTemp: "30", minTemp: "32", maxTemp: "34", color: "saturday"),
             Weather(id: 7, day: "星期天", weatherIcon: "sun.max", currentTemp: "30", minTemp: "22", maxTemp: "32", color: "sunday")
        ]
    }
}

然后创建一个swiftUI View文件,命名为MainCardView.swift。如果未显示预览,请单击“恢复”。

import SwiftUI

struct MainCardView: View {
    
    @Binding var weather: Weather
    
    var body: some View {
        ZStack {
            
            Image("card-bg")
                .resizable()
                .aspectRatio(contentMode: .fill)
            
            VStack(spacing: 10) {
        
                Text("\(weather.currentTemp)°")
                    .foregroundColor(Color.white)
                    .fontWeight(Font.Weight.heavy)
                    .font(Font.system(size: 70))
                
                Image(systemName: weather.weatherIcon)
                    .resizable()
                    .foregroundColor(Color.white)
                    .frame(width: 100, height: 100)
                    .aspectRatio(contentMode: .fit)
                
                Text("\(weather.maxTemp)°")
                    .foregroundColor(Color.white)
                    .font(.title)
                    .padding(.vertical)
            }
        }
        .frame(minWidth: 0, maxWidth: .infinity)
        .background(Color(weather.color))
    }
}

struct MainCardView_Previews: PreviewProvider {
    static var previews: some View {
        MainCardView(weather: .constant(Weather.sampleData[0]))
    }
}
  • @Bindingweather属性之前添加了该属性,并使用swiftUI自动监视该属性的更改并更新了使用的UI部分。@Binding的工作方式@State与之相同,但它不是全局的,而是全局的。
  • 图像调整大小,然后将其内容模式设置为fill
  • 垂直堆叠了2个文本视图和weatherIcon
  • 将框架的minWidth和maxWidth设置为0和.infinity以使该宽度与所有设备尺寸上的屏幕宽度均匹配。
  • 提示:无论屏幕大小如何,都可以使用.frame(minWidth: 0 , maxWidth: .infinity)或 .frame(minHeight: 0 , maxHeight: .infinity)填充父母的宽度或高度

预览现在应该显示以下内容:


image

下一步是将我们新创建的视图添加到WeatherApp视图中。
将其添加到selected属性下面:

@State private var weather =  Weather(id: 1, day: "星期一", weatherIcon: "sun.max", currentTemp: "29", minTemp:"31", maxTemp: "33", color: "mainCard")

  MainCardView(weather: $weather)
                .cornerRadius(CGFloat(20))
                .padding()
                .shadow(color: Color(self.weather.color)
                .opacity(0.4), radius: 20, x: 0, y: 20)

$(美元符号)weather表示此本地天气属性的状态绑定到MainCardView中的属性,只要其中一个发生更改,就会通知另一个并相应更改。简而言之,它们是同步的。
其余代码是不言自明的。

ZStack {
    ScrollView(.vertical, showsIndicators: false) {
        MainCardView(weather: $weather)
            .cornerRadius(CGFloat(20))
            .padding()
            .shadow(color: Color(self.weather.color)
                .opacity(0.4), radius: 20, x: 0, y: 20)
    }
}

预览现在应该显示以下内容:


image

步骤3:水平滚动卡片列表

首先创建标题。在下面添加以下代码MainCardView:

Text("未来七天")
.font(.system(size: 22))
.fontWeight(.bold)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.padding(.top)
.padding(.horizontal)

上面的代码只是创建一个文本,将其向左对齐并应用水平填充。

下一步是创建一张卡,将其重复使用以创建水平滚动列表。

创建新的swiftUI文件,创建方式和创建MainCardView一样,对此命名为SmallCard

import SwiftUI

struct SmallCard: View {
    var weather: Weather = Weather(id: 1, day: "星期一", weatherIcon: "sun.max", currentTemp: "30", minTemp: "32", maxTemp: "29", color: "mainCard")
    
    var body: some View {
        
        VStack(spacing: 20) {
            Text(self.weather.day).fontWeight(.bold)
                .foregroundColor(Color.white)
            
            Image(systemName: self.weather.weatherIcon)
            .resizable()
                .foregroundColor(Color.white)
                .frame(width: 60, height: 60)
            
            ZStack {
                
                Image("cloud")
                    .resizable()
                    .scaledToFill()
                    .offset(CGSize(width: 0, height: 30))
                
                VStack(spacing: 8) {
                    Text("\(self.weather.currentTemp)°").font(.title).foregroundColor(Color.white).fontWeight(.bold)
                    HStack {
                        Text("\(self.weather.minTemp)°").foregroundColor(Color("light-text"))
                        Text("\(self.weather.maxTemp)°").foregroundColor(Color.white)
                    }
                }
            }
        }
            
            
        .frame(width: 200, height: 300)
        .background(Color(self.weather.color))
        .cornerRadius(30)
        .shadow(color: Color(weather.color).opacity(0.7), radius: 10, x: 0, y: 8)
    }
}

struct SmallCard_Previews: PreviewProvider {
    static var previews: some View {
        SmallCard()
    }
}

代码相似。唯一的新事物是ZStack容器。ZStack是将其子视图彼此叠加的视图。(“ Z”代表在3D空间中基于深度的Z轴)

我通过将其y偏移设置为30将云图标向下推30,这很容易解释。

预览现在应该显示以下内容:


image
  1. 现在,让我们创建水平滚动列表。返回WeatherApp文件。
  2. 在接下来的7天文本下方添加以下代码:
ScrollView(.horizontal, showsIndicators: false) {
    HStack(spacing: 20) {
        ForEach(Weather.sampleData, id: \.id) { weather in
            SmallCard(weather: weather).onTapGesture {
                withAnimation(.spring()) {
                    self.showDetails.toggle()
                    self.weather = weather
                }
            }
        }
    }.frame( height: 340)
        .padding(.horizontal)
}.frame( height: 350, alignment: .top)

预览应显示以下内容:

image

步骤4:弹出详情

当单击其中一张小卡片时,我们要显示从底部开始动画的详细视图。

继续并创建一个名为swiftUI的新文件,DetailView.swift
用以下内容替换文件的内容:

import SwiftUI

struct DetailView: View {
    
    @Binding var weather: Weather
    
    var body: some View {
        GeometryReader { gr in
            VStack(spacing: 20) {
                
                // Day text
                Text(self.weather.day).fontWeight(.bold)
                    .font(.system(size: 60))
                    .frame(height: gr.size.height * 1/10)
                    .minimumScaleFactor(0.5)
                    .foregroundColor(Color.white)
                
                // Weather image
                Image(systemName: self.weather.weatherIcon)
                    .resizable()
                    .foregroundColor(Color.white)
                    .frame(width: gr.size.height * 3 / 10, height: gr.size.height * 3 / 10)
                
                // Degrees texts
                VStack {
                    VStack(spacing: 20) {
                        Text("\(self.weather.currentTemp)°")
                            .font(.system(size: 50))
                            .foregroundColor(Color.white)
                            .fontWeight(.bold)
                            .frame(height: gr.size.height * 0.7/10)
                            .minimumScaleFactor(0.5)
                        
                        HStack(spacing: 40) {
                            Text("\(self.weather.minTemp)°")
                                .foregroundColor(Color("light-text"))
                                .font(.title)
                                .minimumScaleFactor(0.5)
                            
                            Text("\(self.weather.maxTemp)°")
                                .foregroundColor(Color.white)
                                .font(.title)
                                .minimumScaleFactor(0.5)
                        }
                    }
                }
                }.frame(minWidth: 0, maxWidth: .infinity, minHeight: gr.size.height, alignment: .bottom)
            .background(Color(self.weather.color))
        }
    }
}

struct DetailView_Previews: PreviewProvider {
    static var previews: some View {
        DetailView(weather: .constant(Weather(id: 1, day: "星期一", weatherIcon:  "sun.max", currentTemp:  "24", minTemp: "25", maxTemp: "29", color: "mainCard")), showDetails: .constant(false))
    }
}

注意:GeometryReader是一个容器视图,根据其自身大小和坐标空间定义其内容。这意味着GeometryReader给我们尺寸和位置,我们可以使用它来动态定位和调整子视图的大小

我们将创建一个自定义形状,用于裁剪视图。

将DetailsView其添加到其块的下方和外部:

struct CustomShape: Shape {
    func path(in rect: CGRect) -> Path {
        let cornerRadius:CGFloat = 40
        var path = Path()
        
        path.move(to:  CGPoint(x: 0, y: cornerRadius))
        path.addQuadCurve(to: CGPoint(x: cornerRadius, y: 0), control: CGPoint.zero)
        path.addLine(to: CGPoint(x: rect.width - cornerRadius, y: 0))
        path.addQuadCurve(to: CGPoint(x: rect.width, y: cornerRadius), control: CGPoint(x: rect.width , y: 0))
        path.addLine(to: CGPoint(x: rect.width, y: rect.height))
        path.addLine(to: CGPoint(x: 0, y: rect.height))
        path.closeSubpath()

        return path
    }
}

VStackDetailsView之后的父级上添加此修饰符.background(Color(self.weather.color)):

 .clipShape(CustomShape(), style: FillStyle.init(eoFill: true, antialiased: true))

预览应显示以下内容:

image

接下来,我们将创建接下来的5小时视图:
在代码CustomShape块下方添加以下代码:

struct HourView: View {
    var hour = "14:00"
    var icon = "sun.max.fill"
    var color = "wednesday"
    
    var body: some View {
        GeometryReader { gr in
            VStack{
                Text(self.hour).foregroundColor(Color("text"))
                Image(systemName: self.icon)
                    .resizable()
                    .foregroundColor(Color(self.color))
                    .frame(width: gr.size.height * 1/3, height: gr.size.height * 1/3)
                
                Text("24°")
                    .font(.system(size: 24))
                    .foregroundColor(Color("text"))
                    .fontWeight(.semibold)
            }
        }.padding(.vertical, 30)
    }
}

和创建这样的水平堆叠视图:
将以下代码的下方,VStackDetailView身体。

HStack (spacing: 20){
    HourView()
    HourView(hour: "15:00", icon: "sun.dust.fill", color: "tuesday")
    HourView(hour: "16:00",icon: "cloud.rain.fill", color: "thursday")
    HourView(hour: "17:00",icon: "cloud.bolt.fill", color: "sunday")
    HourView(hour: "18:00",icon: "snow", color: "mainCard")
}.frame(minWidth: 0, maxWidth: .infinity, minHeight: gr.size.height * 2 / 10)
    .padding(.horizontal)
    .background(Color.white)
    .cornerRadius(30)
    .padding()

如您所见,我正在重HourView用来创建每小时的预测。

预览应显示如下内容:

image

现在让我们将其集成DetailViewWeatherApp中:

我们想tapGesture在每个上添加一个,SmallCardView以便当我们单击它们中的任何一个时,我们都显示相应的详细信息。

SmallCard(weather: weather).onTapGesture {
                            self.showDetails.toggle()
                            self.weather = weather
                        
                    }

并将其添加到下面文件的顶部 weather

@State private var showDetails = false

每次SmallCard点击其中一个时,我们都想切换 showDetails的值。

在下面添加showDetails

private var detailSize = CGSize(width: 0, height: UIScreen.main.bounds.height)

现在,将新添加ScrollView的ZStack容器放入容器中,并ScrollView在ZStack块内部下面添加以下代码:

DetailView(weather:  self.$weather)
    .offset( self.showDetails ? CGSize.zero : detailSize)

而下面这个detailSize属性到顶部:

@State private var sampleData = Weather.sampleData

为了使DetailView动画效果漂亮地围绕在这两个调用中onTapGesturewithAnimation(.spring())如下所示:

  withAnimation(.spring()) {
        self.showDetails.toggle()
        self.weather = weather
    }

关闭按钮

在中DetailView.swift,VStack用a 包围外部,在外部ZStack下方VStack添加以下内容

HStack {
    Image(systemName: "xmark")
        .resizable()
        .foregroundColor(Color.red)
        .frame(width: 20, height: 20)
    
}.padding(20
).background(Color.white)
    .cornerRadius(100)
    .offset(x: 0, y: -gr.size.height / 2)
    .shadow(radius: 20)

重要的是这个 .offset(x: 0, y: -gr.size.height / 2)。在ZStack容器中添加视图时,它们将在容器(在本例中为ZStack容器)的中心彼此堆叠。因此,要将其定位到顶部,我们将其向上移动1/2 ZStack高度。

现在添加onTapGesture允许删除DetailView

首先,将其添加@Binding var showDetails: Bool
到主体上方,并showDetails: .constant(false)DetailView_Previews块内的DetailView的构造函数中添加此 参数。

最后,添加此修改器关闭图标HStatckshadow

 .onTapGesture {
        withAnimation(.spring()) {
            self.showDetails.toggle()
        }
}

中会出现错误WeatherApp。只需将此参数添加,showDetails: self.$showDetails到构造函数即可。

完整DetailView.swift文件应如下所示

import SwiftUI


struct DetailView: View {
    
     @Binding var weather: Weather
    @Binding var showDetails: Bool

    
    var body: some View {
        GeometryReader { gr in
            ZStack {
                VStack(spacing: 20) {
                    
                    // Day text
                    Text(self.weather.day).fontWeight(.bold)
                        .font(.system(size: 60))
                        .frame(height: gr.size.height * 1/10)
                        .minimumScaleFactor(0.5)
                        .foregroundColor(Color.white)
                    
                    // Weather image
                    Image(systemName: self.weather.weatherIcon)
                        .resizable()
                        .foregroundColor(Color.white)
                        .frame(width: gr.size.height * 3 / 10, height: gr.size.height * 3 / 10)
                    
                    // Degrees texts
                    VStack {
                        VStack(spacing: 20) {
                            Text("\(self.weather.currentTemp)°")
                                .font(.system(size: 50))
                                .foregroundColor(Color.white)
                                .fontWeight(.bold)
                                .frame(height: gr.size.height * 0.7/10)
                                .minimumScaleFactor(0.5)
                            
                            HStack(spacing: 40) {
                                Text("\(self.weather.minTemp)°")
                                    .foregroundColor(Color("light-text"))
                                    .font(.title)
                                    .minimumScaleFactor(0.5)
                                
                                Text("\(self.weather.maxTemp)°")
                                    .foregroundColor(Color.white)
                                    .font(.title)
                                    .minimumScaleFactor(0.5)
                            }
                        }
                    }
                    
                    // Hourly views
                    HStack (spacing: 20){
                        HourView()
                        HourView(hour: "15:00", icon: "sun.dust.fill", color: "tuesday")
                        HourView(hour: "16:00",icon: "cloud.rain.fill", color: "thursday")
                        HourView(hour: "17:00",icon: "cloud.bolt.fill", color: "sunday")
                        HourView(hour: "18:00",icon: "snow", color: "mainCard")
                    }.frame(minWidth: 0, maxWidth: .infinity, minHeight: gr.size.height * 2 / 10)
                        .padding(.horizontal)
                        .background(Color.white)
                        .cornerRadius(30)
                        .padding()
                    
                }.frame(minWidth: 0, maxWidth: .infinity, minHeight: gr.size.height, alignment: .bottom)
                    .background(Color(self.weather.color))
                    .clipShape(CustomShape(), style: FillStyle.init(eoFill: true, antialiased: true))
                
                // Close icon
                HStack {
                    Image(systemName: "xmark")
                        .resizable()
                        .foregroundColor(Color.red)
                        .frame(width: 20, height: 20)
                    
                }.padding(20
                ).background(Color.white)
                    .cornerRadius(100)
                    .offset(x: 0, y: -gr.size.height / 2)
                    .shadow(radius: 20)
                    .onTapGesture {
                        withAnimation(.spring()) {
                            self.showDetails.toggle()
                        }
                }
                
            }
        }
    }
}

struct CustomShape: Shape {
    func path(in rect: CGRect) -> Path {
        let cornerRadius:CGFloat = 40
        var path = Path()
        
        path.move(to:  CGPoint(x: 0, y: cornerRadius))
        path.addQuadCurve(to: CGPoint(x: cornerRadius, y: 0), control: CGPoint.zero)
        path.addLine(to: CGPoint(x: rect.width - cornerRadius, y: 0))
        path.addQuadCurve(to: CGPoint(x: rect.width, y: cornerRadius), control: CGPoint(x: rect.width , y: 0))
        path.addLine(to: CGPoint(x: rect.width, y: rect.height))
        path.addLine(to: CGPoint(x: 0, y: rect.height))
        path.closeSubpath()

        return path
    }
}

struct HourView: View {
    var hour = "14:00"
    var icon = "sun.max.fill"
    var color = "wednesday"
    
    var body: some View {
        GeometryReader { gr in
            VStack{
                Text(self.hour).foregroundColor(Color("text"))
                Image(systemName: self.icon)
                    .resizable()
                    .foregroundColor(Color(self.color))
                    .frame(width: gr.size.height * 1/3, height: gr.size.height * 1/3)
                
                Text("24°")
                    .font(.system(size: 24))
                    .foregroundColor(Color("text"))
                    .fontWeight(.semibold)
            }
        }.padding(.vertical, 30)
    }
}


struct DetailView_Previews: PreviewProvider {
    static var previews: some View {
        DetailView(weather: .constant(Weather(id: 1, day: "星期一", weatherIcon:  "sun.max", currentTemp:  "24", minTemp: "25", maxTemp: "29", color: "mainCard")), showDetails: .constant(false))
    }
}

总结一下

  • 关于项目的内容,并不是文章就能给大家讲明白的,想要了解更多内容,请多看SwiftUI有关知识,特别是国外一些资料
  • 代码下载地址
    点击跳转下载
  • 欢迎点赞和反馈
    本文为作者原著,欢迎转载,转载请注明作者出处
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349