美文网首页
Swift: 天气预报

Swift: 天气预报

作者: 小唐朝 | 来源:发表于2016-08-15 09:45 被阅读790次

    天气预报

    启动.png 切换.png 管理.png 添加.png 删除.png

    本版本的天气预报使用cocoapods添加了第三方代码

    具体:

    # Uncomment this line to define a global platform for your project
    # platform :ios, '9.0'
    
    target 'WeatherNew' do
      # Comment this line if you're not using Swift and don't want to use dynamic frameworks
      use_frameworks!
    
      # Pods for WeatherNew
      pod 'Kingfisher', '~> 2.4.2'
      pod 'SnapKit', '~> 0.30.0.beta2'
      pod 'SwiftyJSON', '~> 2.3.2'
      pod 'Alamofire', '~> 3.4.1'
    end
    

    项目文件:

    云盘:

    链接: http://pan.baidu.com/s/1i5jnHHj 密码: rwp7
    

    代码及简单说明

    启动:

    //
    //  AppDelegate.swift
    //  WeatherNew
    //
    //  Created by Input on 16/8/13.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    
    import UIKit
    import SwiftyJSON
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        var window: UIWindow?
    
        func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
            
            let IDPath = NSBundle.mainBundle().pathForResource("weatherId", ofType: "plist")
            let data = NSArray(contentsOfFile: IDPath!)
            
            for i in data!{
                let h = i as! NSDictionary
                WeatherId.weatherId["\(h["weatherName"]!)"] = "w\(h["weatherId"]!)"
            }
            self.window = UIWindow()
            self.window?.frame = UIScreen.mainScreen().bounds
            self.window?.makeKeyAndVisible()
            
            let conTroller = MainView()
            
            let pilot = UINavigationController(rootViewController: conTroller)
            self.window?.rootViewController = pilot
            
            return true
        }
    }
    
    

    此代码用于启动,创建一个导航控制器,MainView(天气界面)作为第一个界面

    MainView

    
    //
    //  MainView.swift
    //  WeatherNew
    //
    //  Created by Input on 16/8/13.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    
    import UIKit
    import SnapKit
    import Kingfisher
    import Alamofire
    
    class MainView: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
    
        var countyNameLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 400, height: 20))  //显示城市名称
        var backGroundView = UIImageView()  //首页背景
        var positionBtn: UIButton!
        var managerBtn: UIButton!
        var countyList = Array<CountyData>()  //城市列表
        let str = NSHomeDirectory() + "/Documents/"  //app文档保存路径
        var coll: UICollectionView!  //coll->显示天气
        var weatherDict = Dictionary<String,CityWeatherData>()  //保存城市天气数据
        var flag = false  //判断是否定位
        var cityFlag = 0
        //系统时间
        var date = NSDate()
        var timeFormatter = NSDateFormatter()
        var timeLabel: UILabel!
    
        override func viewDidLoad() {
            super.viewDidLoad()        
            self.view.backgroundColor = UIColor.grayColor()
            self.navigationItem.titleView = countyNameLabel
            self.view.addSubview(backGroundView)
            
            positionBtn = UIButton(type: .Custom)
            managerBtn = UIButton(type: .Custom)
            self.view.addSubview(positionBtn)
            self.view.addSubview(managerBtn)
    
            timeLabel = UILabel()
            self.view.addSubview(timeLabel)
            
            //coll设置
            collManage()
            
            //Btn关联函数
            positionBtn.addTarget(self, action: #selector(positionBtnFun), forControlEvents: .TouchUpInside)
            managerBtn.addTarget(self, action: #selector(managerBtnFun), forControlEvents: .TouchUpInside)
            
            
            //读取本地配置文件获得已添加城市列表
            readFileCity()
            
            //页面布局
            arrangementView()
            
            //设置View内容
            showView()
            
            if countyList.isEmpty{
                positionBtnFun()
            }
        }
        
        //coll设置
        func collManage(){
            
            let layout = UICollectionViewFlowLayout()
            let frame = CGRect(x: 0, y: 64, width: self.view.bounds.width , height: self.view.bounds.height - 109)
            layout.scrollDirection = .Horizontal
            layout.itemSize = CGSize(width: frame.size.width, height: frame.size.height)
            layout.minimumLineSpacing = 0
            
            coll = UICollectionView(frame: frame, collectionViewLayout: layout)
            coll.registerClass(MainWeatherCell.self, forCellWithReuseIdentifier: "cell")
            self.view.addSubview(coll)
            coll.dataSource = self
            coll.delegate = self
            coll.pagingEnabled = true
            coll.showsHorizontalScrollIndicator = false
            coll.allowsSelection = false
        }
    
        func arrangementView(){
            //布局背景View
            backGroundView.snp.makeConstraints { (make) in
                make.top.left.trailing.equalTo(self.view)
                make.bottom.equalTo(self.view).offset(0)
            }
            //Btn布局
            positionBtn.snp.makeConstraints { (make) in
                make.bottom.left.equalTo(self.view)
                make.width.equalTo(90)
                make.height.equalTo(45)
            }
            managerBtn.snp.makeConstraints { (make) in
                make.bottom.trailing.equalTo(self.view)
                make.width.equalTo(90)
                make.height.equalTo(45)
            }
            //时间布局
            timeLabel.snp.makeConstraints { (make) in
                make.centerX.equalTo(self.view)
                make.centerY.height.equalTo(self.managerBtn)
                make.width.equalTo(self.view).multipliedBy(0.4)
            }
            //设置系统时间及字体颜色
            timeLabel.adjustsFontSizeToFitWidth = true
            timeLabel.font = UIFont.systemFontOfSize(45)
            timeLabel.textColor = UIColor.whiteColor()
            timeLabel.textAlignment = .Center
    
            //城市Name显示设置
            countyNameLabel.textAlignment = .Center
            countyNameLabel.font = UIFont.systemFontOfSize(28)
        }
        
        func showView(){
            //设置背景
            backGroundView.image = UIImage(named: "shanhe")
            //Btn图标设置
            managerBtn.setImage(UIImage(named: "manage"), forState: .Normal)
            positionBtn.setImage(UIImage(named: "dingwei"), forState: .Normal)
            //设置coll背景色
            coll.backgroundColor = UIColor.clearColor()
            //获取系统时间并显示
            timeFormatter.dateFormat = "yyyy年MM月dd日"
            timeLabel.text = timeFormatter.stringFromDate(date) as String
        }
        
        //初始化读取本地已添加城市
        func readFileCity(){
            let fileUrl = "\(self.str)/json/localCity.json"
    //        print(fileUrl)
            let fileManager = NSFileManager.defaultManager()
            let filePath: String = "\(self.str)/json"
            let exist = fileManager.fileExistsAtPath(filePath)
            
            if exist{
                if fileManager.fileExistsAtPath("\(filePath)/localCity.json"){
                    let data = NSData(contentsOfFile: fileUrl)
                    let json = JSON(data: data!)
                    
                    for h in json{
                        let city = CountyData(json: h.1)
                        if countyList.filter({ $0.id == city.id }).isEmpty{
                            countyList.insert(city, atIndex: 0)
                        }
                    }
                }
                else{
                    let s = ""
                    try! s.writeToFile("\(filePath)/localCity.json", atomically: true, encoding: NSUTF8StringEncoding)
                }
            }else{
            
                try! fileManager.createDirectoryAtPath(filePath,withIntermediateDirectories: true, attributes: nil)
                let s = ""
            
                try! s.writeToFile("\(filePath)/localCity.json", atomically: true, encoding: NSUTF8StringEncoding)
            }
        }
        
        //通过cityid请求天气数据
        func requestWeatherDataForId(cityId id: String){
    
            let weatherUrl = "http://apis.baidu.com/heweather/weather/free?cityid=CN" + id
            requestFOrUrl(weatherUrl)
            
        }
        
        //通过localIP请求天气数据
        func requestWeatherDataForIp(localIP ip: String){
            let weatherUrl = "http://apis.baidu.com/heweather/weather/free?cityip=" + ip
            requestFOrUrl(weatherUrl)
        }
        
        //通过URL请求数据
        func requestFOrUrl(url: String){
            var json: JSON!
            //请求预报
            Alamofire.request(.GET, url, parameters: nil, encoding: .URL, headers: ["apikey" : "f4ffdda1810f05375e4755257e7baca5"]).responseData { (Response) in
                if Response.result.error == nil{
                    let data = Response.result.value
                    json = JSON(data: data!)["HeWeather data service 3.0"]
                    let da = CityWeatherData(json: json)
                    let id = da.id
    //                print(id)
                    self.weatherDict[id] = da
                    //请求24小时
                    let hourUrl = "http://m.weather.com.cn/mpub/hours/\(id).html"
                    
                    Alamofire.request(.GET, hourUrl).responseData { (Response) in
                        if Response.result.error == nil{
                            let data = Response.result.value
                            json = JSON(data: data!)["jh"]
                            for i in json{
                                self.weatherDict[id]!.hourData.append(HourData(json: i.1))
                            }
    //                        print(self.weatherDict[id]!.hourData.count)
                            self.upMainView()
                            if self.flag{
                                self.flag = false
                                self.positionForIP(da)
                            }
                        }
                    }
                }
            }
    
        }
        
        //ip定位
        func positionForIP(city: CityWeatherData){
            var citytmp: CountyData!
            var sup0 = String((Int(city.id))!/10000)
            var sup1 = String((Int(city.id))!%10000/100)
            
            let cityUrl = "http://www.weather.com.cn/data/city3jdata/china.html"
            Alamofire.request(.GET, cityUrl).responseJSON { (Response) in
                if Response.result.error == nil{
                    let data = Response.result.value
                    let tyUrl = "http://www.weather.com.cn/data/city3jdata/provshi/\(sup0).html"
                    sup0 = data![sup0] as! String
                    Alamofire.request(.GET, tyUrl).responseJSON { (Response) in
                        if Response.result.error == nil{
                            let da = Response.result.value
                            if sup1 < "10"{
                                sup1 = "0" + sup1
                            }
                            sup1 = da![sup1] as! String
    //                        print(sup0, sup1)
                            citytmp = CountyData(id: city.id, name: city.name, enName: "ip", sup0: sup0, sup1: sup1)
                            for i in 0 ..< self.countyList.count{
                                if self.countyList[i].id == citytmp.id{
                                    self.countyList.removeAtIndex(i)
                                    break
                                }
                            }
                            self.countyList.insert(citytmp, atIndex: 0)
                            self.writeFile()
                            self.upMainView()
                            self.coll.scrollToItemAtIndexPath(NSIndexPath(forItem: 0, inSection: 0), atScrollPosition: .Left, animated: true)
                            
                            self.countyNameLabel.text = self.countyList[0].sup0 + "·" + self.countyList[0].name
                            if self.countyList[0].sup0 == self.countyList[0].name{
                                self.countyNameLabel.text = self.countyList[0].name
                            }
                        }
                    }
                }
            }
        }
        //通过城市对应indexPath跳转cell
        func toCellForIndexPath(str: String){
            
            if let ind = self.countyList.filter({ $0.id == str }).first?.indexPath{
                self.coll.scrollToItemAtIndexPath(NSIndexPath(forItem: ind.item, inSection: 0), atScrollPosition: .Left, animated: true)
            }
        }
        
        //更新Main视图的所有View
        func upMainView(){
            self.coll.reloadData()
        }
        
        
        //"管理"按钮点击事件
        func managerBtnFun(){
            let manageViewCtr = ManageViewController()
            
            manageViewCtr.cityAim(self.countyList)
            
            manageViewCtr.citySite = {
                (county: CountyData) in
                for i in 0 ..< self.countyList.count{
                    if self.countyList[i].id == county.id{
                        self.countyList.removeAtIndex(i)
                        break
                    }
                }
                self.countyList.insert(county, atIndex: 0)
                self.upMainView()
                self.coll.scrollToItemAtIndexPath(NSIndexPath(forItem: 0, inSection: 0), atScrollPosition: .Left, animated: true)
                manageViewCtr.navigationController?.popViewControllerAnimated(true)
            }
    
            manageViewCtr.delCounty = {
                (county: CountyData) in
                for i in 0 ..< self.countyList.count{
                    if self.countyList[i].id == county.id{
                        self.countyList.removeAtIndex(i)
                        break
                    }
                }
                self.upMainView()
            }
            
            self.navigationController?.pushViewController(manageViewCtr, animated: true)
    
        }
        
        //"定位"按钮点击事件
        func positionBtnFun(){
            self.flag = true
            var ip: String!
            let url = "http://www.net.cn/static/customercare/yourip.asp"
            Alamofire.request(.GET, url).responseString { (Response) in
                if Response.result.error == nil{
                    let data = Response.result.value
    //                print(data!)
                    ip = data?.substringFromIndex((data?.rangeOfString("您的本地上网IP是:<h2>")?.endIndex.advancedBy(0))!)
                    ip = ip.substringToIndex((ip.rangeOfString(",")?.startIndex.advancedBy(0))!)
                    self.requestWeatherDataForIp(localIP: ip)
                }
            }
        }
        
        //取城市数量
        func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return self.countyList.count
        }
        
        //取城市数据
        func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
            let  cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! MainWeatherCell
            let i = indexPath.item
    
            if let data = self.weatherDict["\(self.countyList[i].id)"]{
                cell.countyData = data
                cell.tableView.reloadData()
                cell.tmpLable.text = data.now.tmp!
                cell.weatherView.image = UIImage(named: WeatherId.weatherId["\(data.now.txt!)"]!)
                cell.weatherTxt.text = data.now.txt
                self.countyList[i].indexPath = indexPath
    //            print(self.countyList[i].name, self.countyList[i].indexPath.item)
                if data.aqi != nil{
                    cell.qltyLabel.text = "空气质量: \(data.aqi.qlty)  指数:\(data.aqi.aqi)"
                }
                else{
                    cell.qltyLabel.text = "空气质量: 无数据  指数:  无数据"
                }
                cell.upDataTime.text = "更新: " + data.update
            }
            
            return cell
        }
        //更新显示城市名称
        func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
            let index = collectionView.indexPathsForVisibleItems()
            let i = index.first?.item
            countyNameLabel.text = self.countyList[i!].sup0 + "·" + self.countyList[i!].name
    
            if self.countyList[i!].sup0 == self.countyList[i!].name{
                countyNameLabel.text = self.countyList[i!].name
            }
        }
        //请求新的城市的天气
        func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
            let i = indexPath.item
            if self.weatherDict["\(self.countyList[i].id)"] == nil{
                requestWeatherDataForId(cityId: self.countyList[i].id)
            }
        }
        func writeFile(){
            let fileUrl =  NSHomeDirectory() + "/Documents/json/localCity.json"
            var str = "["
            let n = countyList.count
            for i in 1 ... n{
                str += countyList[n - i].classToString() + ","
            }
            str = str.substringToIndex(str.characters.endIndex.advancedBy(-1))
            str += "]"
            //        print(str)
            try! str.writeToFile(fileUrl, atomically: true, encoding: NSUTF8StringEncoding)
        }
    }
    
    

    第一个界面的实现!使用snapkit自动布局实现界面的排版
    在self.view上面加载一个collectionView,每一个cell是一个城市的天气

    MainWeatherCell

    //
    //  WeatherCell.swift
    //  WeatherNew
    //
    //  Created by Input on 16/8/13.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    
    import UIKit
    import SnapKit
    
    class MainWeatherCell: UICollectionViewCell, UITableViewDataSource, UITableViewDelegate {
        var tmpLable: UILabel!
        var weatherTxt: UILabel!
        var weatherView: UIImageView!
        var countyData: CityWeatherData!
        var tableView: UITableView!
        var qltyLabel: UILabel!
        var upDataTime: UILabel!
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            tmpLable = UILabel()
            weatherTxt = UILabel()
            weatherView = UIImageView()
            tableView = UITableView()
            qltyLabel = UILabel()
            upDataTime = UILabel()
            
            self.contentView.addSubview(tmpLable)
            self.contentView.addSubview(weatherView)
            self.contentView.addSubview(weatherTxt)
            self.contentView.addSubview(tableView)
            self.contentView.addSubview(qltyLabel)
            self.contentView.addSubview(upDataTime)
            //布局及设置其属性
            manageView()
        }
        
        func manageView(){
            tmpLable.snp.makeConstraints { (make) in
                make.left.top.equalTo(self.contentView).offset(10)
                make.width.height.equalTo(self.contentView.snp.width).multipliedBy(0.25)
            }
            tmpLable.font = UIFont.systemFontOfSize(72)
            tmpLable.textAlignment = .Center
            tmpLable.adjustsFontSizeToFitWidth = true
            
            weatherView.snp.makeConstraints { (make) in
                make.top.equalTo(self.contentView).offset(10)
                make.trailing.equalTo(self.contentView).offset(-20)
                make.width.height.equalTo(self.contentView.snp.width).multipliedBy(0.2)
            }
            
            weatherTxt.snp.makeConstraints { (make) in
                make.top.equalTo(self.tmpLable.snp.bottom)
                make.left.equalTo(self.contentView).offset(20)
                make.width.equalTo(self.contentView.snp.width).multipliedBy(0.4)
                make.height.equalTo(24)
            }
            weatherTxt.font = UIFont.systemFontOfSize(20)
            weatherTxt.textAlignment = .Center
            weatherTxt.adjustsFontSizeToFitWidth = true
            
            tableView.snp.makeConstraints { (make) in
                make.bottom.left.trailing.equalTo(self.contentView)
                make.height.equalTo(self.contentView).multipliedBy(0.7)
            }
            tableView.dataSource = self
            tableView.delegate = self
            tableView.registerClass(WeatherTableViewCell.self, forCellReuseIdentifier: "cell")
            tableView.showsVerticalScrollIndicator = false
            tableView.backgroundColor = UIColor.clearColor()
            tableView.separatorStyle = .None
            tableView.tableFooterView = UIView()
            tableView.allowsSelectionDuringEditing = false
            tableView.allowsSelection = false
            
            
            upDataTime.snp.makeConstraints { (make) in
                make.centerY.equalTo(self.weatherTxt)
                make.trailing.equalTo(self.contentView).offset(-20)
                make.height.equalTo(30)
                make.width.equalTo(50)
            }
            upDataTime.adjustsFontSizeToFitWidth = true
            upDataTime.textColor = UIColor.whiteColor()
            upDataTime.textAlignment = .Center
            
            qltyLabel.snp.makeConstraints { (make) in
                make.centerX.equalTo(self.contentView)
                make.bottom.equalTo(tmpLable.snp.bottom)
                make.width.equalTo(self.contentView).multipliedBy(0.4)
                make.height.equalTo(30)
            }
            qltyLabel.adjustsFontSizeToFitWidth = true
            qltyLabel.textColor = UIColor.whiteColor()
            qltyLabel.textAlignment = .Center
    
            
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 7
        }
        //七天预报信息
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! WeatherTableViewCell
            if let data = countyData{
                let d = data.daily[indexPath.row]
                cell.textLabel?.text = d.date
                cell.imgView?.image = UIImage(named: "\(WeatherId.weatherId["\(d.condTxt_d)"]!)")
                cell.tmpLabel.text = d.tmpMin + "℃~" + d.tmpMax + "℃"
             }
            
            cell.backgroundColor = UIColor.clearColor()
            return cell
        }
        //tableView的分组数量
        func numberOfSectionsInTableView(tableView: UITableView) -> Int {
            return 1
        }
        //tableView HeaderView
        func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
            let headerView = TableHeaderView()
            if let data = countyData{
                headerView.hourData = data.hourData
            }
            return headerView
        }
        //tableView的头的高度
        func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
            return self.contentView.bounds.height * 0.2
        }
        func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
            return 60
        }
    }
    
    
    

    在cell上使用一个tableView显示七天及24小时预报

    TableHeaderView

    //
    //  TableHeaderView.swift
    //  WeatherNew
    //
    //  Created by Input on 16/8/14.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    
    import UIKit
    import SnapKit
    
    class TableHeaderView: UIView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
        var hourData = Array<HourData>()
        var hourCollection: UICollectionView!
        var imgView: UIImageView!
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            imgView = UIImageView()
            imgView.image = UIImage(named: "hour")
            self.addSubview(imgView)
            imgView.snp.makeConstraints { (make) in
                make.top.left.trailing.bottom.equalTo(self)
            }
            let w = UIScreen.mainScreen().bounds.width
            let h = UIScreen.mainScreen().bounds.height - 109
            let layout = UICollectionViewFlowLayout()
    
            layout.itemSize = CGSize(width: 0.1 * h, height: 0.2 * h)
            layout.scrollDirection = .Horizontal
            
            let frame = CGRect(x: 0, y: 0, width: w, height: h * 0.2)
            layout.minimumLineSpacing = 0
            layout.minimumInteritemSpacing = 0
            hourCollection = UICollectionView(frame: frame, collectionViewLayout: layout)
            hourCollection.registerClass(HourCollectionViewCell.self, forCellWithReuseIdentifier: "cell")
            
            hourCollection.dataSource = self
            hourCollection.delegate = self
            hourCollection.backgroundColor = UIColor.clearColor()
            self.addSubview(hourCollection)
    
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        //cell数量
        func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return 24
        }
        //cell数据
        func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
            let i = indexPath
            let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: i) as! HourCollectionViewCell
            
            if !hourData.isEmpty{
                let h = hourData[i.item]
                cell.timeLabel.text = "\(h.hour)时"
                cell.imgView.image = UIImage(named: "w\(h.TQ)")
                cell.tmpLabel.text = h.temp + "℃"
            }
            cell.backgroundColor = UIColor.clearColor()
            return cell
        }
    }
    

    tableView一个分组,分组的头部放入一个collection,用于显示24小时预报

    WeatherTableViewCell

    //
    // WeatherTableViewCell.swift
    //  WeatherNew
    //
    //  Created by Input on 16/8/14.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    
    import UIKit
    import SnapKit
    
    class WeatherTableViewCell: UITableViewCell {
        var imgView: UIImageView!
        var tmpLabel: UILabel!
    
        override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            imgView = UIImageView()
            tmpLabel = UILabel()
            self.contentView.addSubview(imgView)
            self.contentView.addSubview(tmpLabel)
            
            imgView.snp.makeConstraints { (make) in
                make.centerX.centerY.equalTo(self.contentView)
                make.width.height.equalTo(self.contentView.snp.height).multipliedBy(0.8)
            }
            
            tmpLabel.snp.makeConstraints { (make) in
                make.height.equalTo(40)
                make.centerY.equalTo(self.contentView)
                make.trailing.equalTo(self.contentView).offset(-20)
                make.width.equalTo(self.contentView.snp.width).multipliedBy(0.25)
            }
            tmpLabel.font = UIFont.systemFontOfSize(36)
            tmpLabel.textColor = UIColor.whiteColor()
            tmpLabel.textAlignment = .Center
            tmpLabel.adjustsFontSizeToFitWidth = true
            
            self.textLabel?.textColor = UIColor.whiteColor()
            self.textLabel?.font = UIFont.systemFontOfSize(28)
            self.textLabel?.adjustsFontSizeToFitWidth = true
            self.textLabel?.textAlignment = .Left
            
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    

    table的cell定义 显示7天预报//(将天气状况文字转weatherId字典不是很全)

    HourCollectionViewCell

    //
    //  HourCollectionViewCell.swift
    //  WeatherNew
    //
    //  Created by Input on 16/8/14.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    
    import UIKit
    import SnapKit
    
    class HourCollectionViewCell: UICollectionViewCell {
        var imgView: UIImageView!
        var timeLabel: UILabel!
        var tmpLabel: UILabel!
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            imgView = UIImageView()
            timeLabel = UILabel()
            tmpLabel = UILabel()
            self.contentView.addSubview(imgView)
            self.contentView.addSubview(tmpLabel)
            self.contentView.addSubview(timeLabel)
            manageView()
        }
        
        func manageView(){
            timeLabel.snp.makeConstraints { (make) in
                make.top.left.trailing.equalTo(self.contentView)
                make.height.equalTo(self.contentView).multipliedBy(0.25)
            }
            timeLabel.adjustsFontSizeToFitWidth = true
            timeLabel.font = UIFont.systemFontOfSize(16)
            timeLabel.textAlignment = .Center
            timeLabel.textColor = UIColor.whiteColor()
            
            imgView.snp.makeConstraints { (make) in
                make.top.equalTo(self.timeLabel.snp.bottom)
                make.left.trailing.equalTo(self.contentView)
                make.height.equalTo(self.contentView).multipliedBy(0.5)
            }
            
            tmpLabel.snp.makeConstraints { (make) in
                make.top.equalTo(self.imgView.snp.bottom)
                make.left.trailing.equalTo(self.contentView)
                make.height.equalTo(self.contentView).multipliedBy(0.25)
            }
            tmpLabel.adjustsFontSizeToFitWidth = true
            tmpLabel.font = UIFont.systemFontOfSize(14)
            tmpLabel.textAlignment = .Center
            tmpLabel.textColor = UIColor.whiteColor()
    
            
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    

    用于显示24小时collection的cell的自定义

    CityWeatherData

    //
    //  CityWeatherData.swift
    //  WeatherNew
    //
    //  Created by Input on 16/8/13.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    //  http://apis.baidu.com/heweather/weather/free?cityid=CN101250101 测试通过
    //  定稿(08.13 -> 22:30)
    //  记录: 
    //
    import UIKit
    import SwiftyJSON
    
    class CityWeatherData: NSObject {
        var id: String!  //当前城市的id
        var name: String!
        var aqi: AQI!  //当天AQI(只有大陆城市有)
        var now: NOW!  //实况
        var daily = Array<Daily_Forecast>()  //七天预报
        var hourData = Array<HourData>()  //城市当天24小时天气
        var update: String! //数据更新时间
        
        init(json: JSON){
            daily.removeAll()
            
            let i = json.first!.1
            var s = i["basic"]["id"].string!
            id = s.substringFromIndex(s.startIndex.advancedBy(2))
            s = i["basic"]["update"]["loc"].string!
            update = s.substringFromIndex(s.startIndex.advancedBy(11))
            name = i["basic"]["city"].string!
            for j in i["daily_forecast"]{
                daily.append(Daily_Forecast(json: j.1))
            }
            now = NOW(json: i["now"])
            if i["aqi"] != nil{
                aqi = AQI(json: i["aqi"])
            }
        }
    }
    
    class AQI: NSObject {
        
        var qlty: String!  //空气质量情况
        var pm25: String!
        var aqi: String!
        var pm10: String!
        
        init(json: JSON){
            let j = json["city"]
            
            if let q = j["qlty"].string {
                qlty = q
            }
            if let q = j["pm10"].string{
                pm10 = q
            }
            if let q = j["pm25"].string{
                pm25 = q
            }
            if let q = j["aqi"].string{
                aqi = q
            }
            
        }
        
    }
    
    
    class NOW: NSObject {
        var tmp: String!
        var windDir: String!
        var windSc: String!
        var hum: String!  //湿度
        var txt: String!  //天气
        
        init(json: JSON){
            tmp = json["tmp"].string!
            windSc = json["wind"]["sc"].string!
            hum = json["hum"].string!
            windDir = json["wind"]["dir"].string!
            txt = json["cond"]["txt"].string!
        }
    
    }
    class Daily_Forecast: NSObject{
        var astroSs: String!  //日落
        var astroSr: String!  //日出
        var tmpMax: String!
        var tmpMin: String!
        var windDir: String!
        var windSc: String!
        var hum: String!
        var date: String!
        var condTxt_d: String!
        var condtxt_n: String!
        
        init(json: JSON){
            astroSs = json["astro"]["ss"].string!
            astroSr = json["astro"]["sr"].string!
            tmpMax = json["tmp"]["max"].string!
            tmpMin = json["tmp"]["min"].string!
            windDir = json["wind"]["dir"].string!
            windSc = json["wind"]["sc"].string!
            hum = json["hum"].string!
            date = json["date"].string!.substringFromIndex(json["date"].string!.startIndex.advancedBy(5))
            condTxt_d = json["cond"]["txt_d"].string!
            condtxt_n = json["cond"]["txt_n"].string!
        }
    }
    

    用于存放城市天气数据的类,请求天气的api需要百度的apikey

    CountyData

    //
    //  CountyData.swift
    //  WeatherNew
    //
    //  Created by Input on 16/8/13.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    //  定稿(08.13 -> 22:30)
    
    import UIKit
    import SwiftyJSON
    
    class CountyData: NSObject {
        
        var id: String!
        var name: String!
        var enName: String!
        var sup0: String!
        var sup1: String!
        var indexPath: NSIndexPath!
        
        init(json: JSON) {
        
            self.id = json["id"].string!
            self.name = json["name"].string!
            self.enName = json["enName"].string!
            self.sup0 = json["sup0"].string!
            self.sup1 = json["sup1"].string!
        
        }
        
        init(id: String, name: String, enName: String, sup0: String, sup1: String) {
            
            self.id = id
            self.name = name
            self.enName = enName
            self.sup0 = sup0
            self.sup1 = sup1
    
        }
        
        init(json: NSDictionary) {
            
            self.id = "\(json["county_id"]!)"
            self.name = json["county_name"] as! String
            self.enName = json["county_en"] as! String
            
        }
        func classToString() -> String{
            
            let str = "{\"id\": \"\(self.id)\", \"name\": \"\(self.name)\", \"enName\": \"\(self.enName)\", \"sup0\": \"\(self.sup0)\", \"sup1\": \"\(self.sup1)\"}"
            return str
        }
    }
    

    用于处理城市基本信息的类

    HourData

    //
    //  HourData.swift
    //  weather
    //
    //  Created by Input on 16/8/5.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    //  "http://m.weather.com.cn/mpub/hours/cityid.html"
    //  定稿(08.13 -> 22:30)
    
    import UIKit
    import SwiftyJSON
    
    class HourData: NSObject {
        var hour: Int!
        var temp: String!
        var TQ: Int!
        
        init(json: JSON){
            let s = json["jf"].string!.substringFromIndex(json["jf"].string!.startIndex.advancedBy(8))
            hour = (Int(s))!%10000/100
            temp = json["jb"].string!
            TQ = Int(json["ja"].string!)
        }
    }
    
    

    用于处理24小时天气预报

    WeatherId

    //
    //  WeatherId.swift
    //  WeatherNew
    //
    //  Created by Input on 16/8/14.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    
    import UIKit
    
    class WeatherId: NSObject {
        static var weatherId = Dictionary<String, String>()
    }
    

    将天气状况文字转id通过id获取图标

    ManageViewController

    //
    //  ManageViewController.swift
    //  WeatherNew
    //
    //  Created by Input on 16/8/14.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    
    import UIKit
    
    class ManageViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
        
        var citySite:((county: CountyData)->Void)!
        var delCounty:((county: CountyData)->Void)!
        var manageTable: UITableView!
        var countyList = Array<CountyData>()  //城市列表
        var add: AddCountyViewController!
        
        func cityAim(array: Array<CountyData>){
            countyList = array
            
            let btn = UIButton(type: .System)
            manageTable = UITableView(frame: self.view.frame, style: .Plain)
            self.countyList = array
            manageTable.delegate = self
            manageTable.dataSource = self
            manageTable.tableFooterView = btn
            self.view.addSubview(manageTable)
    
            btn.frame = CGRect(x: 0, y: 0, width: 600, height: 44)
            btn.backgroundColor = UIColor.greenColor()
            btn.setTitle("添加城市", forState: .Normal)
            btn.addTarget(self, action: #selector(upMain), forControlEvents: .TouchUpInside)
            manageTable.reloadData()
        }
        
        
        override func viewDidLoad() {
            super.viewDidLoad()
            add = AddCountyViewController()
            
            add.citySite = {
                (county: CountyData) in
                if self.countyList.filter({ $0.id == county.id }).isEmpty{
                    self.countyList.insert(county, atIndex: 0)
                }
                self.citySite(county: county)
                self.writeFile()
            }
        }
        
        func writeFile(){
            let fileUrl =  NSHomeDirectory() + "/Documents/json/localCity.json"
            var str = "["
            let n = countyList.count
            for i in 1 ... n{
                str += countyList[n - i].classToString() + ","
            }
            str = str.substringToIndex(str.characters.endIndex.advancedBy(-1))
            str += "]"
            try! str.writeToFile(fileUrl, atomically: true, encoding: NSUTF8StringEncoding)
        }
        
        func upMain(){
            self.navigationController?.pushViewController(add, animated: true)
        }
    
        
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            if !countyList.isEmpty{
                return countyList.count
            }
            return 0
        }
        
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            
            let i = indexPath.row
            
            var cell = tableView.dequeueReusableCellWithIdentifier("cell")
            
            if cell == nil {
                cell = UITableViewCell(style: .Default, reuseIdentifier: "cell")
            }
            
            cell?.textLabel?.text = "\(i + 1).  \(countyList[i].name)"
            cell?.backgroundColor = UIColor.clearColor()
            
            return cell!
        }
        
        func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
            
            let i = indexPath.row
            self.citySite(county: countyList[i])
            
        }
        
        
        func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
            if editingStyle == UITableViewCellEditingStyle.Delete {
                delCounty(county: countyList[indexPath.row])
                countyList.removeAtIndex(indexPath.row)
                writeFile()
                tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
            }
            self.manageTable.reloadData()
        }
        
        func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
            if indexPath.row == 0{
                return false
            }
            return true
        }
        
        deinit{
            writeFile()
        }
    }
    

    管理界面的实现,就一个tableView,将tableView.tableFooterView设置为添加城市按钮
    包括将所添加的城市的信息写入本地文件

    AddCountyViewController

    //
    //  AddCountyViewController.swift
    //  WeatherNew
    //
    //  Created by Input on 16/8/14.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    
    import UIKit
    
    class AddCountyViewController: UIViewController {
        
        var citySite:((county: CountyData)->Void)!
        let provinceTableDeDa = ProvinceTableViewCell()
        let cityTableDeDa = CityTableViewCell()
        let countyTableDeDa = CountyTableViewCell()
        var provinceTable: UITableView!
        var cityTable: UITableView!
        var countyTable: UITableView!
        var addCityTmp: CountyData!
        var sup0: String!
        var sup1: String!
        
        override func viewDidLoad() {
            super.viewDidLoad()
            let w = self.view.frame.size.width/3
            let h = self.view.frame.size.height
            
            let rectProvince = CGRect(x: 0, y: 0, width: w * 3, height: h)
            let rectCity = CGRect(x: w - 20, y: 64, width: w * 2 + 20, height: h - 64)
            let rectCounty = CGRect(x: 2 * w - 20, y: 64, width: w + 20, height: h - 64)
            
            provinceTable = UITableView(frame: rectProvince, style: .Plain)
            cityTable = UITableView(frame: rectCity, style: .Plain)
            countyTable = UITableView(frame: rectCounty, style: .Plain)
            self.view.addSubview(provinceTable)
            self.view.addSubview(cityTable)
            self.view.addSubview(countyTable)
            
            //设置table属性
            manageTable()
        }
    
        func manageTable(){
            provinceTable.delegate = provinceTableDeDa
            provinceTable.dataSource = provinceTableDeDa
            
            countyTable.dataSource = countyTableDeDa
            countyTable.delegate = countyTableDeDa
            
            cityTable.dataSource = cityTableDeDa
            cityTable.delegate = cityTableDeDa
            
            provinceTable.separatorStyle = .None
            countyTable.separatorStyle = .None
            cityTable.separatorStyle = .None
            
            provinceTableDeDa.citySite = {
                (city: String, id: String) in
                self.countyTable.hidden = true
                self.sup0 = city
                self.cityTableDeDa.cityAim = {
                  id
                }
                self.cityTable.reloadData()
            }
            
            cityTableDeDa.citySite = {
                (city: String, array: Array<NSDictionary>) in
                self.countyTable.hidden = false
                self.sup1 = city
                self.countyTableDeDa.cityAim = {
                    city
                }
                self.countyTableDeDa.list(array)
                self.countyTable.reloadData()
            }
            
            countyTableDeDa.citySite = {
                (county: CountyData) in
                county.sup0 = self.sup0
                county.sup1 = self.sup1
                self.addCityTmp = county
                self.citySite(county: county)
                self.navigationController?.popViewControllerAnimated(false)
            }
        }
    }
    

    添加城市的界面,通过ManageView的tableView的尾巴上的按钮显示

    ProvinceTableViewCell

    //
    //  ProvinceTableViewCell.swift
    //  WeatherNew
    //
    //  Created by Input on 16/8/14.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    
    import UIKit
    
    class ProvinceTableViewCell: NSObject, UITableViewDataSource, UITableViewDelegate {
        var selectTime: ((i: Int)->Void)!
        
        let str = NSBundle.mainBundle().bundlePath
        var table: UITableView!
        var readArray: NSArray!
        
        var cityAim = {() -> CountyData! in nil }
        var citySite = {(city: String, id: String) in }
        
        
        override init() {
            
            let fileUrl = "\(self.str)/ID101.json"
            let data = NSData(contentsOfFile: fileUrl)
            readArray = try! NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments) as! NSArray
        }
        
        func tableFun(table: UITableView){
            self.table = table
        }
        
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return self.readArray.count
        }
        
        func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
            let i = indexPath.row
            let str = readArray[i]["province_name"] as! String
            let num = "\(readArray[i]["province_id"]!!)"
            self.citySite(str, num)
            
        }
        
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            
            var cell = tableView.dequeueReusableCellWithIdentifier("cell")
            if cell == nil {
                cell = UITableViewCell(style: .Default, reuseIdentifier: "cell")
                cell?.backgroundColor = UIColor.clearColor()
            }
            
            cell?.textLabel?.text = "\(indexPath.row + 1). \(readArray[indexPath.row]["province_name"]!!)"
            
            cell?.textLabel?.adjustsFontSizeToFitWidth = true
            
            return cell!
        }
    }
    
    

    为省份列表提供数据及交互

    CityTableViewCell

    //
    //  CityTableViewCell.swift
    //  WeatherNew
    //
    //  Created by Input on 16/8/14.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    
    import UIKit
    import SwiftyJSON
    class CityTableViewCell: NSObject, UITableViewDataSource, UITableViewDelegate {
    
        let str = NSBundle.mainBundle().bundlePath
        var table: UITableView!
        var readArray: NSArray!
        
        var cityAim = {() -> String! in nil}
        var citySite: ((city: String, array: Array<NSDictionary>)->Void)!
        
        func readFile(i: String) {
            let fileUrl = "\(self.str)/ID\(i).json"
            let data = NSData(contentsOfFile: fileUrl)
            readArray = try! NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments) as! Array<NSDictionary>
        }
        
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            if let i = self.cityAim(){
                self.readFile(i)
                return readArray.count
            }
            return 0
        }
        
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            
            let i = indexPath.row
            
            var cell = tableView.dequeueReusableCellWithIdentifier("cell")
            
            if cell == nil {
                cell = UITableViewCell(style: .Default, reuseIdentifier: "cell")
            }
            cell?.textLabel?.text = "\(i + 1).\(readArray[i]["city_name"] as! String)"
            cell?.backgroundColor = UIColor.clearColor()
            
            return cell!
        }
        
        func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
            
            let i = indexPath.row
                    
            let h = readArray[i]["county_list"] as? Array<NSDictionary>
            self.citySite(city: (readArray[i]["city_name"] as! String), array: h!)
        }
    }
    
    

    为市级城市列表提供数据及交互

    CountyTableViewCell

    //
    //  CountyTableViewCell.swift
    //  WeatherNew
    //
    //  Created by Input on 16/8/14.
    //  Copyright © 2016年 Input. All rights reserved.
    //
    
    import UIKit
    
    class CountyTableViewCell: NSObject, UITableViewDataSource, UITableViewDelegate {
    
        var citySite:((county: CountyData)->Void)!
        var cityAim: (()->String)!
        
        var countyList = Array<CountyData>()
        
        func list(i: Array<NSDictionary>){
            countyList.removeAll()
            for j in i{
                let n = CountyData(json: j)
                countyList.append(n)
            }
        }
        
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            if let _ = self.cityAim{
                return countyList.count
            }
            return 0
        }
        
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            
            let i = indexPath.row
            
            var cell = tableView.dequeueReusableCellWithIdentifier("cell")
            
            if cell == nil {
                cell = UITableViewCell(style: .Default, reuseIdentifier: "cell")
            }
            
            cell?.textLabel?.text = "\(i + 1).\(countyList[i].name)"
            cell?.backgroundColor = UIColor.clearColor()
            
            return cell!
        }
        
        func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
            
            let i = indexPath.row
            
            self.citySite(county: countyList[i])
        }
    
        
    }
    
    

    为第三级城市列表提供数据及交互

    cityID以Json格式文件保存,weatherId使用Plist文件保存

    相关文章

      网友评论

          本文标题:Swift: 天气预报

          本文链接:https://www.haomeiwen.com/subject/wmhusttx.html