通过 UITableViewCell 上的自定义按钮更新 Realm

Updating Realm through a custom button on the UITableViewCell

我有一个存储在 Realm 中的“书籍”表视图。我想在点击自定义 UITableViewCell 上的按钮时将“CurrentBook”属性 设置为“True”。

我认为我的错误与在“func selectCurrentBook”中获取正确的账面价值有关,当我使用如下所示的可选值时,没有任何反应。

@objc func selectCurrentBook(sender: UIButton) {
        try! realm.write {
            book?.currentlyReading = true
        }
    }

当我不使用 book 的可选值并使用 book.currentlyReading = true 时,我收到错误消息“在隐式展开可选值时意外发现 nil:”

我是否在某处错误地传递了账面价值?我似乎无法找出如何。也许我委派错了?

我的 TableViewCell 是:

import UIKit
import RealmSwift

protocol MyBooksDelegate {
    func currentlyReadingButton()
}

class MyBooksTableViewCell: UITableViewCell {
    
    let realm = try! Realm()
    
    @IBOutlet weak var titleLabel: UILabel!
    
    @IBOutlet weak var authorLabel: UILabel!
    
    @IBOutlet weak var smallThumbnailImageView: UIImageView!
    
    @IBOutlet weak var currentlyReadingButton: UIButton!
    
    @IBAction func currentlyReadingButton(_ sender: Any) {

    }
    
    private var book: Book!
    
    func loadImage(smallThumbnailURL: String) {
        let imageURL = URL(string: smallThumbnailURL ?? "")
        smallThumbnailImageView.sd_setImage(with: imageURL)
        }

    func configureCell(book: Book, delegate: MyBooksDelegate?) {
       titleLabel.text = book.bookTitle
       authorLabel.text = book.bookAuthor
        loadImage(smallThumbnailURL: book.bookSmallThumbnailImageURL)
        
        currentlyReadingButton.addTarget(self, action: #selector(selectCurrentBook(sender:)), for: .touchUpInside)
                        
    }
    
    @objc func selectCurrentBook(sender: UIButton) {
        try! realm.write {
            book?.currentlyReading = true
        }
    }
}

我的带有 TableView 的视图控制器是:

import SwiftyJSON
import RealmSwift

class BooksViewController: UIViewController, UITextFieldDelegate, UITableViewDataSource, UITableViewDelegate {
    
    
    @IBOutlet weak var myBooksTableView: UITableView!
    
    let realm = try! Realm()
    
    var books: Results<Book>?
    
    // Search Bar Properties
    var searchParameter = "intitle"
    
    var booksArray: [Book] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        
        loadBooks()
        // Setting up the TableView
               self.myBooksTableView.delegate = self
               self.myBooksTableView.dataSource = self
               self.myBooksTableView.rowHeight = 120.0
        
        // Setup Title
        title = "My Books"
       // navigationController?.navigationBar.prefersLargeTitles = true

    }
    
    override func viewWillAppear(_ animated: Bool) {
         navigationController?.navigationBar.barStyle = .black
        loadBooks()
     }
    
    func loadBooks() {
        books = realm.objects(Book.self).sorted(byKeyPath: "DateCreated", ascending: false)
        myBooksTableView.reloadData()
    }

    // TABLEVIEW
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return books?.count ?? 1
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "MyBooksTableViewCell", for: indexPath) as? MyBooksTableViewCell {
            cell.configureCell(book: (books?[indexPath.row])!, delegate: self as? MyBooksDelegate)
     //       cell.selectionStyle = UITableViewCell.SelectionStyle.none

            return cell
        } else {
            return UITableViewCell()
        }
    }
    
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.performSegue(withIdentifier: "myBooksTOMyBooksDetail", sender: self)
        myBooksTableView.deselectRow(at: indexPath, animated: true)
    }

我的图书模型是:

class Book: Object {
    @objc dynamic var bookTitle: String!
    @objc dynamic var bookAuthor: String!
    @objc dynamic var bookSmallThumbnailImageURL: String!
    @objc dynamic var bookThumbnailImageURL: String!
    @objc dynamic var bookDescription: String!
    @objc dynamic var bookISBN_13: String!
    @objc dynamic var currentlyReading = false
    @objc dynamic var DateCreated = Date()
    @objc dynamic var WordID = UUID().uuidString
    
    // words
    let words = List<Word>()
    
    override static func primaryKey() -> String? {
        return "WordID"
    }
}

最兼容的语法是

currentlyReadingButton.addTarget(self, action: #selector(selectCurrentBook), for: .touchUpInside)

@objc func selectCurrentBook(_ sender: UIButton) {

然而,由于单元格是自定义的,我更喜欢 IBAction 而不是 target/action

并且协议 MyBooksDelegate 似乎未被使用。


旁注:

强制展开单元格

let cell = tableView.dequeueReusableCell(withIdentifier: "MyBooksTableViewCell", for: indexPath) as! MyBooksTableViewCell

崩溃 - 带有报告 - 揭示了一个 设计 错误,可以立即修复。 if let 你什么也看不到,也不知道为什么。


更新:

出现崩溃是因为你没有在单元格中设置book,在{

之后添加第一行
func configureCell(book: Book, delegate: MyBooksDelegate?) {
   self.book = book
   titleLabel.text = book.bookTitle
   ...