wkWebView有headerView和footerView并加在tableView的頭部的方法及坑

每次發(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這個的問題度宦,但總覺得太過于分散踢匣,而且有的給的代碼存在有不少的坑,覺得自己很有必要把填平完的坑分享給后來者戈抄,希望大家喜歡离唬!

還有自己代碼水平有限,希望大家多多見諒划鸽,再次感謝您瀏覽输莺!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市裸诽,隨后出現的幾起案子嫂用,更是在濱河造成了極大的恐慌,老刑警劉巖丈冬,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘱函,死亡現場離奇詭異,居然都是意外死亡埂蕊,警方通過查閱死者的電腦和手機往弓,發(fā)現死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蓄氧,“玉大人函似,你說我怎么就攤上這事≡让牵” “怎么了缴淋?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵准给,是天一觀的道長泄朴。 經常有香客問我重抖,道長,這世上最難降的妖魔是什么祖灰? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任钟沛,我火速辦了婚禮,結果婚禮上局扶,老公的妹妹穿的比我還像新娘恨统。我一直安慰自己,他們只是感情好三妈,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布畜埋。 她就那樣靜靜地躺著,像睡著了一般畴蒲。 火紅的嫁衣襯著肌膚如雪悠鞍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天模燥,我揣著相機與錄音咖祭,去河邊找鬼。 笑死蔫骂,一個胖子當著我的面吹牛么翰,可吹牛的內容都是我干的。 我是一名探鬼主播辽旋,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼浩嫌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了补胚?” 一聲冷哼從身側響起固该,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎糖儡,沒想到半個月后伐坏,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡握联,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年桦沉,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片金闽。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡纯露,死狀恐怖,靈堂內的尸體忽然破棺而出代芜,到底是詐尸還是另有隱情埠褪,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站钞速,受9級特大地震影響贷掖,放射性物質發(fā)生泄漏。R本人自食惡果不足惜渴语,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一苹威、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧驾凶,春花似錦牙甫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至技肩,卻和暖如春脏答,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背亩鬼。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工殖告, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人雳锋。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓垃喊,卻偏偏與公主長得像靴寂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,117評論 25 707
  • 發(fā)現 關注 消息 iOS 第三方庫缺虐、插件油啤、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,103評論 4 62
  • 怎么我突然又好想你。又想起那天我們擁抱的場景袋马。 我們很沉默初澎,很快樂,聽著你的我的心跳聲匯在一起虑凛,是溫暖的旋律碑宴。你抱...
    若風輕舞閱讀 78評論 0 0
  • 身在異鄉(xiāng)延柠,我不知道別人怕什么。我最怕的是在非同尋常的時間接到家里打來的電話锣披。 這種恐懼感形成在高中時期贞间。有次媽媽打...
    車手嫻和她的朋友閱讀 1,915評論 0 5
  • 今天上完naati贿条,實在餓的不行,在flinders買了點壽司增热,走到7號站臺整以,我決定吃完再上車,畢竟火車上吃東西感...
    樹小妞閱讀 1,383評論 0 1