天气预报
本版本的天气预报使用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文件保存