【问题标题】:Open pdf in tableview from a json file从 json 文件在 tableview 中打开 pdf
【发布时间】:2020-06-26 05:36:42
【问题描述】:

我陷入困境。

我的常规开发人员已经获得了一份全职工作,我正在努力完成一个项目。

字面上卡在最后一行代码.....

我有一个表格视图,它解析一个 json 文件以在选择一行时填充并打开一个 pdf 文件。

我重新设计了 tableview 以添加一个搜索栏和相关代码,这在运行包时可以工作。

但是,我坚持将 didSelectRow 与适当的 pdf 文件连接起来。

有人可以帮忙吗?谢谢

import UIKit
import WebKit

// Model
struct Section {
var section: String
var pdfs: [PDF]
}

struct PDF {
var code: String
var name: String
var airport: String
}

class PdfVC: UIViewController {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var webView: WKWebView!
@IBOutlet weak var tableViewLeft: NSLayoutConstraint!
@IBOutlet weak var btnMenuLeft: NSLayoutConstraint!
@IBOutlet weak var btnMenu: UIButton!
@IBOutlet weak var searchBar: UISearchBar!

//json
var jsonData: [Section] = []
var filtedJsonData: [Section] = []
//WebView
var fileName: String?
var isVideo: Bool = false

var btnMenuClose:UIBarButtonItem?

override func viewDidLoad() {
    super.viewDidLoad()
    hideKeyboardWhenTappedAround()

     // Setup TableView
    tableView.delegate = self
    tableView.dataSource = self
           
    setupData()
    tableView.reloadData()
           
    // Setup SearchBar
    searchBar.delegate = self
    
    // Setup WebView
    if let fileName = fileName {
        isVideo = fileName.contains(".mp4")
        if let range = fileName.range(of: isVideo ? ".mp4" : ".pdf") {
            self.fileName!.removeSubrange(range)
        }
    }
    
    if let file = Bundle.main.url(forResource: fileName ?? "", withExtension: isVideo ? ".mp4" : ".pdf", subdirectory: nil, localization: nil)  {
        let request = URLRequest(url: file)
        webView.load(request)
    }
    
    if let image = UIImage(named: "ico_close") {
        navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(onWebTap))
        //self.navigationItem.leftItemsSupplementBackButton = true
        btnMenuClose = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(onWebTap))
        self.navigationItem.rightBarButtonItems = [btnMenuClose!];

    }
    //navigationItem.title = "Airport Maps"
}

private func hideKeyboardWhenTappedAround() {
    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
    tap.cancelsTouchesInView = false
    view.addGestureRecognizer(tap)
}

@objc private func dismissKeyboard() {
    view.endEditing(true)
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    navigationController?.setNavigationBarHidden(false, animated: animated)
    
    // title color to white
    let titleTextAttributed: [NSAttributedString.Key: Any] = [.foregroundColor: UIColor.white, .font: UIFont(name: "HelveticaNeue-Light", size: 20) as Any]
    self.navigationController?.navigationBar.titleTextAttributes = titleTextAttributed
                
    // back arrow white
    self.navigationController?.navigationBar.tintColor = UIColor.white
    
    // blueish navigation bar
    self.navigationController?.navigationBar.barTintColor = UIColor(red: 0.00, green: 0.54, blue: 0.92, alpha: 1.00)
    self.navigationController?.navigationBar.isTranslucent = false
    
    showMenu(false, animated: false)
}

private func setupData() {
    // Parse data from local json file
    if let path = Bundle.main.path(forResource: "airports", ofType: "json") {
        do {
            let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
            let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
            if let jsonResult = jsonResult as? [Dictionary<String, String>] {
                for result in jsonResult {
                    if !jsonData.contains(where: { $0.section == result["Section"] }) {
                        let section = Section(section: result["Section"] ?? "", pdfs: [])
                        jsonData.append(section)
                    }
                    
                    let pdf = PDF(code: result["Code"] ?? "", name: result["Filename"] ?? "", airport: result["Name"] ?? "")
                    let index = jsonData.firstIndex(where: { $0.section == result["Section"] })
                    if let index = index {
                        jsonData[index].pdfs.append(pdf)
                    }
                }
            }
        } catch {
            // Handle error
            print("error parsing json")
        }
    }
    
    // Sort data before use
    jsonData.sort(by: { $0.section < $1.section })
    for index in 0..<jsonData.count {
        jsonData[index].pdfs.sort(by: { $0.airport < $1.airport } )
    }
    
    filtedJsonData = jsonData
}

@objc func onWebTap() {
    var left:CGFloat = 0
    if tableViewLeft.constant == 0 {
        left = -320
    }
    tableViewLeft.constant = left
    showMenu(left != 0, animated: true)
    UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut, animations: {
        self.view.layoutIfNeeded()
    }, completion: nil)
}

func showMenu(_ show:Bool, animated:Bool) {
    if let image = UIImage(named: show ? "ico_open" : "ico_close") {
        btnMenuClose?.image = image
        //navigationItem.rightBarButtonItem?.image = image
    //}
    //var left:CGFloat = 20
    //if show == false {
    //    left = -64
    }
    //btnMenuLeft.constant = left
    UIView.animate(withDuration: animated ? 0.3 : 0.0, delay: 0, options: .curveEaseInOut, animations: {
        self.view.layoutIfNeeded()
    }, completion: nil)
}
}

// TableView
extension PdfVC: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
    return filtedJsonData.count
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    if filtedJsonData[section].pdfs.count == 0 {
        return nil
    }
    return filtedJsonData[section].section
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return filtedJsonData[section].pdfs.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "PdfCell", for: indexPath) as! PdfCell
    let pdf = filtedJsonData[indexPath.section].pdfs[indexPath.row]
    cell.setupCell(pdf: pdf)
    return cell
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    dismissKeyboard()
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let pdf = filtedJsonData[indexPath.section].pdfs[indexPath.row]
    //THIS IS WHERE I'M STUCK<<<<<<<<<
    self.title = pdf.airport
}
}

// SearchBar
extension PdfVC: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    for (index, data) in jsonData.enumerated() {
        // Filter pdfs by code and name
        let filtedPdf = data.pdfs.filter { $0.code.lowercased().prefix(searchText.count) == searchText.lowercased() || $0.airport.lowercased().prefix(searchText.count) == searchText.lowercased() }
        
        filtedJsonData[index].pdfs = filtedPdf
    }
    
    tableView.reloadData()
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    searchBar.text = ""
    tableView.reloadData()
}
}

【问题讨论】:

  • 我对你的 PDF 模型有点困惑。最初,我以为name 指的是机场名称,但后来我意识到这是一个文件名。那是对的吗?您的 pdf 文件是否已保存在捆绑包中?当用户在didSelectRowAt中选择一个单元格时你需要实现什么
  • pdf 在资源包中。当用户选择单元格时,webview 加载 pdf 文件,tableview “撤回”

标签: json swift pdf tableview


【解决方案1】:

想通了。感谢所有花时间阅读我的问题的人。我改了如下

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let pdf = filtedJsonData[indexPath.section].pdfs[indexPath.row]
self.fileName = pdf.name
self.title = pdf.airport

DispatchQueue.main.async {
self.reloadWebView()
}
}

并添加

private func reloadWebView() {
// Setup WebView
if let fileName = fileName {
isVideo = fileName.contains(".mp4")
if let range = fileName.range(of: isVideo ? ".mp4" : ".pdf") {
self.fileName!.removeSubrange(range)
}
}

if let file = Bundle.main.url(forResource: fileName ?? "", withExtension: isVideo ? ".mp4" : ".pdf", subdirectory: nil, localization: nil) {
let request = URLRequest(url: file)
webView.load(request)
}
}

【讨论】:

    猜你喜欢
    • 2016-08-09
    • 2015-11-01
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-25
    相关资源
    最近更新 更多