每次發(fā)簡書都是自己遇到的坑招拙,填平后分享給大家臭脓,希望后來者可以少遇到些坑镜盯,
發(fā)代碼前尸昧,首先很感謝二位簡書的小伙伴給的幫助:
一揩页、螃蟹(http://www.reibang.com/u/82961c9b9e78) 提供的idea,在 webView的頭部和底部分別加上一個view及KVO的思想烹俗;
二爆侣、楊Hrscy (http://www.reibang.com/u/c0a496a1c168)提供的controller 導入xib的代碼及幫助萍程;
tableView的頭部直接加 webView是很簡單的,難點在于如何:
1兔仰、又在 tableView的tableHeaderView上的webView多加上一個頂部還有一個尾部view茫负,因為webView的高度不確定性,加在webView底部的footerView要等計算出webView的實際高度后再加入
2乎赴、webView得用webView.scrollView.contentInset = UIEdgeInsetsMake(80, 0, 160, 0)偏移出相應的高度朽褪,并利用多出來的空間加上相應的headerView和footerView
以上這些問題詳見代碼,先見圖然后看代碼
webView1.png
webView2.png
webView3.png
webView4.png
webView8.png
webView9.png
webView10.png
上代碼了无虚!
// HomeDetailController.swift
// Created by Apiapia on 2017/9/30.
// Copyright ? 2017年 www.elinknet.cn All rights reserved.
// view 作為 tableView 的 tableHeaderView缔赠,單純的改變 view 的 frame 是無濟于事的 tableView不會大度到時刻適應它的高度
import UIKit
import WebKit
import RxSwift
import RxCocoa
import MJRefresh
import SVProgressHUD
import Kingfisher
import IBAnimatable
import IQKeyboardManager
class WeiTouTiaoDetailController: UIViewController,WKUIDelegate,WKNavigationDelegate {
fileprivate let disposeBag = DisposeBag() // RX
fileprivate var commentValue :Int = 0 // 評論數量
fileprivate var content:String = ""
@IBOutlet weak var tableView: UITableView!
var comments = [NewsDetailImageComment]() // 評論列表
var imgStr = ""
var htmlString: String = ""
var weitoutiao: WeiTouTiao? { //FIXME: user ,user_info,mediao_info 三種待統(tǒng)一
didSet {
if let content = weitoutiao!.content {
self.content = content as String
}
weitoutiao?.large_image_list.forEach({ (image) in
imgStr += "<img src=\"\(String(describing: image.url!))\">"
})
commentValue = (weitoutiao?.comment_count)! // 評論數量
if let user = weitoutiao!.user {
navView.usernameLabel.text = user.name
navView.avatarImageView.kf.setImage(with: URL(string: user.avatar_url!))
} else if let userInfo = weitoutiao!.user_info {
navView.usernameLabel.text = userInfo.name
navView.avatarImageView.kf.setImage(with: URL(string: userInfo.avatar_url!))
} else if let mediaInfo = weitoutiao!.media_info {
navView.usernameLabel.text = mediaInfo.name
navView.avatarImageView.kf.setImage(with: URL(string: mediaInfo.avatar_url!))
}
/// 設置headerView屬性
webViewHeaderView.weitoutiao = weitoutiao!
/// 獲取評論
NetworkTool.loadNewsDetailComments(offset: 0, weitoutiao: weitoutiao!) { (comments) in
self.comments = comments
self.tableView.reloadData()
}
}
}
fileprivate lazy var navView: ConcernNavigationView = {
let navView = ConcernNavigationView.concernNavView()
navView.returnButton.setImage(UIImage(named: "leftbackicon_white_titlebar_24x24_"), for: .normal)
navView.bottomLine.isHidden = false // 顯示分割線
navView.backgroundColor = UIColor.globalRedColor()
navView.delegate = self
navView.vipImageView.isHidden = false
navView.avatarImageView.isHidden = false
navView.usernameLabel.isHidden = false
if let userVerified = self.weitoutiao!.user_verified {
navView.vipImageView.isHidden = !userVerified
}
return navView
}()
/// 微頭條詳情頁 頭部
fileprivate lazy var webViewHeaderView: NewsDetailHeaderView = {
let headerView = NewsDetailHeaderView.headerView()
headerView.frame = CGRect(x: 0, y: -80, width: screenWidth, height: 80)
return headerView
}()
fileprivate lazy var webViewHeaderViewBak: UIView = {
let headerView = UIView.init()
headerView.frame = CGRect(x: 0, y: -80, width: screenWidth, height: 80)
headerView.backgroundColor = UIColor.yellow
return headerView
}()
fileprivate lazy var webViewFooterView:WebViewFooterView = {
let footerView = WebViewFooterView.footerView()
footerView.frame.size.height = 160
return footerView
}()
fileprivate lazy var webViewFooterViewBak: UIView = {
let footerView = UIView.init()
footerView.frame.size.height = 160
footerView.backgroundColor = UIColor.red
return footerView
}()
fileprivate lazy var webView: WKWebView = {
let webView = WKWebView.init()
webView.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
webView.scrollView.contentInset = UIEdgeInsetsMake(80, 0, 160, 0)
webView.uiDelegate = self
webView.navigationDelegate = self
webView.scrollView.isScrollEnabled = false // 設置不能滾動
return webView
}()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// 設置狀態(tài)欄屬性
navigationController?.navigationBar.barStyle = .black
navigationController?.setNavigationBarHidden(true, animated: animated) // 導航條Hidden
//navigationController?.setUpGlobalPan() // 開啟全局手勢
setupUI()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.setNavigationBarHidden(false, animated: animated)
//navigationController?.removeGlobalPanGes() // 清除全局手勢
}
override func viewDidLoad() {
super.viewDidLoad()
IQKeyboardManager.shared().isEnabled = false //MARK:- 這個庫時不時會有小BUG...禁用
htmlString += "<html>"
htmlString += "<head>"
htmlString += "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,user-scalable=0\">"
htmlString += "<style>img{width:99%;margin:5;}body,html{margin:5;padding:5;border:0;}</style>"
htmlString += "</head>"
htmlString += "<body>"
htmlString += "\(self.content)<br>"
htmlString += "\(imgStr)"
htmlString += "</body>"
htmlString += "</html>"
printLog(htmlString)
webView.loadHTMLString(htmlString, baseURL: Bundle.main.bundleURL)
//使用kvo為webView添加監(jiān)聽,監(jiān)聽webView的內容高度
webView.scrollView.addObserver(self, forKeyPath: "contentSize", options: [.old,.new], context: nil)
webView.scrollView.addSubview(webViewHeaderView)
//webView.scrollView.addSubview(webViewFooterView) // 底部
self.tableView.tableHeaderView = webView
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
deinit {
self.webView.scrollView.removeObserver(self, forKeyPath: "contentSize")
}
}
//MARK: - 表格代理 ##################################
extension WeiTouTiaoDetailController: UITableViewDelegate, UITableViewDataSource {
/// cell 的高度
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// let comment = comments[indexPath.row]
// return comment.cellHeight!
return 50
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return comments.count != 0 ? comments.count : 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
/*let comment = comments[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: NewsDetailImageCommentCell.self), for: indexPath) as! NewsDetailImageCommentCell
/// 判斷評論是不是作者
if let user = weitoutiao!.user {
if comment.user_id! == user.user_id! {
cell.isAuthor = true
}
} else if let userInfo = weitoutiao!.user_info {
if comment.user_id! == userInfo.user_id! {
cell.isAuthor = true
}
} else if let mediaInfo = weitoutiao!.media_info {
if comment.user_id! == mediaInfo.user_id! {
cell.isAuthor = true
}
}
cell.comment = comments[indexPath.row]
cellClickedEvent(cell: cell)
*/
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = String(indexPath.row+1)
return cell
}
/// 設置 present 出來的控制器
private func setupPresentationController(cell: NewsDetailImageCommentCell) {
let followDetailVC = FollowDetailViewController()
followDetailVC.userid = cell.comment!.user_id!
followDetailVC.dismissalAnimationType = .cover(from: .right)
followDetailVC.presentationAnimationType = .cover(from: .right)
followDetailVC.modalSize = (width: .full, height: .full)
self.present(followDetailVC, animated: true, completion: nil)
}
/// cell 按鈕點擊事件
private func cellClickedEvent(cell: NewsDetailImageCommentCell) {
// 頭像按鈕點擊
cell.avatarButton.rx.controlEvent(.touchUpInside)
.subscribe(onNext: { [weak self] in
self!.setupPresentationController(cell: cell)
})
.addDisposableTo(disposeBag)
// 用戶名點擊
cell.nameLabel.rx.controlEvent(.touchUpInside)
.subscribe(onNext: { [weak self] in
self!.setupPresentationController(cell: cell)
})
.addDisposableTo(disposeBag)
// 點擊了 評論內容或者回復
cell.coverReplayButton.rx.controlEvent(.touchUpInside)
.subscribe(onNext: {
})
.addDisposableTo(disposeBag)
}
}
extension WeiTouTiaoDetailController {
func setupUI() {
automaticallyAdjustsScrollViewInsets = false
tableView.delegate = self
tableView.dataSource = self
view.addSubview(navView)
}
}
//MARK: - webView代理 實時觀察HTML的高度 ##############
extension WeiTouTiaoDetailController {
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("document.body.offsetHeight;") { (result, error) in
var frame:CGRect = webView.frame
frame.size.height = result as! CGFloat
frame.size.height += self.webViewHeaderView.frame.size.height //頂部
frame.size.height += self.webViewFooterView.frame.size.height //底部
webView.frame = frame
self.webView.scrollView.addSubview(self.webViewFooterView) // 加載完畢后再加載
self.webViewFooterView.frame =
CGRect(x: 0,
y: webView.frame.maxY-self.webViewHeaderView.frame.size.height-self.webViewFooterView.frame.size.height,
width: screenWidth,
height: 160)
self.tableView.tableHeaderView = webView
}
}
}
// MARK: - webView KVO 實時改變webView的控件高度友题,使其高度跟內容高度一致
extension WeiTouTiaoDetailController {
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if (keyPath == "contentSize") {
// 加延遲以保證獲得的高度包含偏移的部份
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.1 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: {() -> Void in
var frame: CGRect = self.webView.frame
frame.size.height = self.webView.scrollView.contentSize.height //webView loadHtml加載后的內容高度
//self.webView.frame = CGRect(x: 0, y: 0, width: screenWidth, height: self.webView.scrollView.contentSize.height)
self.webView.frame = frame
self.tableView.tableHeaderView = self.webView
})
}
}
}
// MARK: - 代理回調 Mine我的 / ConcernNavigationViewDelegate
extension WeiTouTiaoDetailController: ConcernNavigationViewDelegate {
/// 返回按鈕點擊
func concernHeaderViewReturnButtonClicked() {
if (navigationController != nil) {
navigationController?.popViewController(animated: true)
} else {
dismiss(animated: true, completion: nil)
}
}
/// 更多按鈕點擊
func concernHeaderViewMoreButtonClicked() {
let userVC = FollowDetailViewController()
if let user = weitoutiao?.user {
userVC.userid = user.user_id!
} else if let user_info = weitoutiao?.user_info {
userVC.userid = user_info.user_id!
}
navigationController?.pushViewController(userVC, animated: true)
}
func concernHeaderUsernameButtonClicked() {
let userVC = FollowDetailViewController()
if let user = weitoutiao?.user {
userVC.userid = user.user_id!
} else if let user_info = weitoutiao?.user_info {
userVC.userid = user_info.user_id!
}
navigationController?.pushViewController(userVC, animated: true)
}
}
//MARK: - 修改狀態(tài)條顏色 沒有導航條的情況下 會執(zhí)行 否則執(zhí)行 navBar.barStyle = .black
extension WeiTouTiaoDetailController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
哈嗤堰,就這些了,網上確實有很多針對webView如何加view這個的問題度宦,但總覺得太過于分散踢匣,而且有的給的代碼存在有不少的坑,覺得自己很有必要把填平完的坑分享給后來者戈抄,希望大家喜歡离唬!
還有自己代碼水平有限,希望大家多多見諒划鸽,再次感謝您瀏覽输莺!