每次发简书都是自己遇到的坑,填平后分享给大家,希望后来者可以少遇到些坑,
发代码前,首先很感谢二位简书的小伙伴给的帮助:
一、螃蟹(http://www.jianshu.com/u/82961c9b9e78) 提供的idea,在 webView的头部和底部分别加上一个view及KVO的思想;
二、杨Hrscy (http://www.jianshu.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
以上这些问题详见代码,先见图然后看代码
上代码了!
// 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 三种待统一
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)
// 设置状态栏属性
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添加监听,监听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: - 修改状态条颜色 没有导航条的情况下 会执行 否则执行 navBar.barStyle = .black
extension WeiTouTiaoDetailController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
哈,就这些了,网上确实有很多针对webView如何加view这个的问题,但总觉得太过于分散,而且有的给的代码存在有不少的坑,觉得自己很有必要把填平完的坑分享给后来者,希望大家喜欢!
还有自己代码水平有限,希望大家多多见谅,再次感谢您浏览!