Swift UI佈局 讀取網路資料 Swift、OC混編

Swift UI佈局 讀取網路資料 Swift、OC混編

這裡寫圖描述

先建立我們所要用到的檔案,如:StudentsViewController MyUIViewController NewsViewController 這三個檔案建立的時候語言要選擇Swift; 接著建立 DetailViewController News檔案 語言要選擇OC,用以實現與Swift語言的混編

接著實現我們具體的程式碼,與OC不同,在Swift中我們要先在AppDelegate.swift中書寫

class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}

如圖: 這是AppDelegate.swift中系統自帶的一個類,在其中書寫我們的程式碼, 具體如下:

class AppDelegate: UIResponder, UIApplicationDelegate {
// 視窗物件
var window: UIWindow?
// 標籤欄控制器
var tabCtl : UITabBarController = UITabBarController.init()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let stuVC:StudentsViewController = StudentsViewController()
stuVC.navigationItem.title = "學生名單"
stuVC.view.backgroundColor  = UIColor.white
let stuNav:UINavigationController = UINavigationController.init(rootViewController: stuVC)
// UI
let uiVC = MyUIViewController()
uiVC.navigationItem.title = "控制元件檢視"
uiVC.view.backgroundColor  = UIColor.white
let uiNav = UINavigationController(rootViewController: uiVC)
// News
let newsVC = NewsViewController()
newsVC.navigationItem.title = "新聞頭條"
newsVC.view.backgroundColor  = UIColor.white
let newsNav = UINavigationController(rootViewController: newsVC)
// 給導航新增標籤欄標籤
stuNav.tabBarItem = UITabBarItem.init(title: "學生", image:UIImage.init(named:"22.png"), tag: 100)
uiNav.tabBarItem = UITabBarItem.init(tabBarSystemItem: UITabBarSystemItem.contacts, tag: 101)
newsNav.tabBarItem = UITabBarItem.init(tabBarSystemItem: UITabBarSystemItem.bookmarks, tag: 102)
self.tabCtl.viewControllers  = [stuNav,uiNav,newsNav]
self.window?.rootViewController = self.tabCtl
return true
}

在StudentsViewController .swift中我們實現一個表格,將陣列內容展示在表格中,具體程式碼如下:(注意Swift中一些特殊的書寫格式,略與OC不同)

import UIKit
class StudentsViewController: UIViewController,UITableViewDataSource {
var studentsData:[String]?
override func viewDidLoad() {
super.viewDidLoad()
studentsData = ["小李","小王","小紅","小張","小明"]
let table:UITableView = UITableView.init(frame: self.view.frame, style: .plain)
table.dataSource = self
self.view.addSubview(table)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let count = self.studentsData?.count{
return count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let str = "identifier"
var cell = tableView.dequeueReusableCell(withIdentifier: str)
if  cell == nil {
cell = UITableViewCell.init(style: .default, reuseIdentifier: str)
}
cell?.textLabel?.text = self.studentsData?[indexPath.row]
return cell!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}

在MyUIViewController.swift中我們用Swift實現一些簡單的UI控制元件,程式碼以供參考

import UIKit
class MyUIViewController: UIViewController,UITextFieldDelegate {
// lable控制元件
var myLable:UILabel = UILabel.init(frame: CGRect(x: 20, y: 60, width: 100, height: 30))
// button
var myBtn:UIButton?
// TextField
var textFiled:UITextField?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// ===========Lable==============
myLable.textColor = UIColor.red
myLable.textAlignment = .center
myLable.backgroundColor = UIColor.white
myLable.text = "JJJJJJJJJJJJJJJJJ"
myLable.font = UIFont.systemFont(ofSize: 17)
self.view.addSubview(myLable)
// ===========button==============
myBtn = UIButton.init(type: .roundedRect)
myBtn?.frame = CGRect(x: 20, y: 120, width: 100, height: 30)
myBtn?.setTitle("播放", for: .normal)
myBtn?.setTitleColor(.blue, for: .normal)
myBtn?.setTitle("暫停", for: .selected)
myBtn?.setTitleColor(.red, for: .selected)
myBtn?.addTarget(self, action: #selector(btnPress(sender:)), for: .touchUpInside)
self.view.addSubview(myBtn!)
// ===========textField==============
textFiled = UITextField.init(frame: CGRect(x: 20, y: 200, width: 200, height: 50))
textFiled?.placeholder = "請輸入賬號"
textFiled?.textAlignment = .center
textFiled?.textColor = .red
textFiled?.keyboardType = .default
textFiled?.clearButtonMode = .whileEditing
textFiled?.clearsOnBeginEditing = true
textFiled?.isSecureTextEntry = false
textFiled?.autocapitalizationType = .allCharacters
textFiled?.borderStyle = .line
textFiled?.delegate = self
self.view.addSubview(textFiled!)
}
func btnPress(sender:UIButton) -> Void {
sender.isSelected = !sender.isSelected
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
self.view.endEditing(true)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textFiled?.resignFirstResponder()
return true
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// 獲取目前textField控制元件中的文字內容
var text = textField.text
// 現在文字框 的內容
//獲取目前textfield控制元件中的文字
var newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
return newString.characters.count <= 8
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}

此段程式碼中 按鈕實現了點選切換的功能 類似音樂按鈕的點選播放 暫停

**

重點來了!!!!!!!!!!!!**

在NewsViewController.swift 中,我們採用json解析 實現了從網路獲取新聞資料並解析最後展示在表格上,資料來自極速資料。
具體程式碼 :

import UIKit
class NewsViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
var datas:Array<News>?
var tableView:UITableView?
// =========    表格協議 =======
func tableView(_ tableView:UITableView, numberOfRowsInSection section :Int) -> Int {
if let count = datas?.count{
return count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let iderfier = "cell"
var cell = tableView.dequeueReusableCell(withIdentifier: iderfier)
if cell == nil{
cell = UITableViewCell.init(style: .subtitle, reuseIdentifier: iderfier)
}
let  oneNew = self.datas![indexPath.row]
cell?.textLabel?.text = oneNew.title
cell?.detailTextLabel?.text = oneNew.time
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let oneNews = self.datas![indexPath.row]
let detailVc = DetailViewController()
detailVc.detailUrl = oneNews.weburl
self.navigationController?.pushViewController(detailVc, animated: true)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.getURLDatas()
}
override func viewDidLoad() {
super.viewDidLoad()
tableView = UITableView.init(frame: self.view.frame, style: .plain)
tableView?.dataSource = self
tableView?.delegate = self
self.view.addSubview(tableView!)
self.getURLDatas()
}
func getURLDatas()
{
// 此處是極速資料的appKey,若有需要可以去極速資料網站註冊並申請
let appKey = "*************"
let urlStr = "http://api.jisuapi.com/news/get?channel=頭條&start=0&num=10&appkey=\(appKey)"
print(urlStr)
let urlString = urlStr.addingPercentEncoding(withAllowedCharacters: CharacterSet(charactersIn: "`#%^{}\"[]|\\<> ").inverted)
let url = URL.init(string: urlString!)
let request = URLRequest(url:url!, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 15.0)
let session = URLSession.shared
let task =   session.dataTask(with: request)
{   (data, response, error) in
// 解析獲取的二進位制網路資料
if error != nil
{
print("錯誤:\(error!)")
return
}
let obj = try! JSONSerialization.jsonObject(with: data!, options: . allowFragments) as! Dictionary<String,Any>
print(obj)
let result = obj["result"] as! Dictionary<String,Any>
let list = result["list"] as! Array<Any>
var newsArr:[News]? = []
for item in list{
let newsDic = item as! Dictionary<String,Any>
let oneNew = News()
oneNew.title = newsDic["title"] as! String
oneNew.time = newsDic["time"]  as! String
oneNew.url = newsDic["url"] as! String
oneNew.weburl = newsDic["weburl"] as! String
newsArr?.append(oneNew)
}
self.datas = newsArr
// 回到UI主執行緒重新整理表格
DispatchQueue.main.async(execute:
{
self.tableView?.reloadData()
})
}
task.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}

接下來 我們實現cell的點選進入詳情的效果 在建立兩個OC檔案中,系統會自動生成如圖所示的檔案:
這裡寫圖片描述
把OC的標頭檔案在這個檔案中 再次書寫下用以實現與OC的混編
程式碼如下:

#import "DetailViewController.h"
#import "News.h"

DetailViewController.h 與 .m檔案是實現的是新聞的詳情
在DetailViewController.h中寫一個對外的屬性

#import <UIKit/UIKit.h>
@interface DetailViewController : UIViewController
@property(nonatomic,strong)NSString *detailUrl; // 對外詳情介面
@end

.m 程式碼:

#import "DetailViewController.h"
@interface DetailViewController ()
@property(nonatomic,strong)UIWebView *webView;
@end
@implementation DetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.webView = [[UIWebView alloc] initWithFrame:self.view.frame];
[self.view addSubview:self.webView];
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSString *urlStr = [self.detailUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlStr];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:req];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end

在New.h中定義一些要用到的屬性

#import <Foundation/Foundation.h>
@interface News : NSObject
@property(nonatomic,strong)NSString *title;
@property(nonatomic,strong)NSString *time;
@property(nonatomic,strong)NSString *url;
@property(nonatomic,strong)NSString *weburl;
@end

想要實現網路資料的展示 還要在pch檔案中做一些修改,具體如圖:
這裡寫圖片描述