首页 > 解决方案 > 在 Swift IOS 应用程序中打印 TableView 的内容

问题描述

我正在制作一个包含表格视图的场景的应用程序。表格视图中的每个单元格都包含一个评级控件(由 5 颗星组成)和一个标签。单击按钮时,我想打印所有标签以及用户从整个表格视图的评级控件中单击的星数。到控制台。

我怎样才能做到这一点?

这是我的 tableview(_:cellForRowAt:) 方法

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // Configure the cell
    // Table view cells are reused and should be dequeued using a cell identifier
    let cellId = "cell"

    guard let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as? MatchingTableViewCell else {
        fatalError("The dequeued cell is not an instacne of MatchingTableViewCell")
    }

    // Fetches the appropriate match for the data source layout.
    let match = matching[indexPath.row]

    cell.nameLabel.text = match.name
    cell.photoImagView.image = match.photo
    cell.ratingControl.rating = match.rating

    return cell
}

数据模型对象是 Match 对象的结构数组:

import Foundation
import UIKit
import os.log

class Match: NSObject, NSCoding {
// MARK: Properties
var name: String
var photo: UIImage?
var rating: Int


// MARK: Archiving Paths
static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first
static let ArchiveURL = DocumentsDirectory?.appendingPathComponent("matching")

// MARK: Types
struct PropertyKey {
    static let name = "name"
    static let photo = "photo"
    static let rating = "rating"
}

init?(name: String, photo: UIImage?, rating: Int) {
    // The name must not be empty
    guard !name.isEmpty else{
        return nil
    }
    // The rating must be between 0 and 5 inclusively
    guard (rating >= 0) && (rating <= 5) else {
        return nil
    }
    // Initialize stored properties
    self.name = name
    self.photo = photo
    self.rating = rating
}

override var description : String {
    return "rating \(self.rating) \n"
}
// MARK: NSCoding
func encode(with aCoder: NSCoder) {
    aCoder.encode(name, forKey: PropertyKey.name)
    aCoder.encode(photo, forKey: PropertyKey.photo)
    aCoder.encode(rating, forKey: PropertyKey.rating)

}

required convenience init?(coder aDecoder: NSCoder) {
    // The name is required if we cannot decode a name string, the init should fail
    guard let name = aDecoder.decodeObject(forKey: PropertyKey.name) as? String else{
        os_log("Unable to decode the name for a Match object", log: OSLog.default, type: .debug)
        return nil
    }
    // Because the photo is an optional property of Match, just use conditional cast.
    let photo = aDecoder.decodeObject(forKey: PropertyKey.photo) as? UIImage
    let rating = aDecoder.decodeObject(forKey: PropertyKey.rating)

    // Must call designated init
    self.init(name: name, photo: photo, rating: rating as! Int)

}

}

RatingControl.swift:

import UIKit

@IBDesignable class RatingControl: UIStackView {



// MARK: Properties
private var ratingButtons = [UIButton]()
var rating = 0 {
    didSet {
        updateButtonSelectionStates()
    }
}

@IBInspectable var starSize: CGSize = CGSize(width: 44.0, height: 44.0) {// Defines size of buttons/
    didSet{
        setupButtons()
    }
}

@IBInspectable var starCount: Int = 5 {// Defines number of buttons
    didSet{
        setupButtons()
    }
}

// MARK: Initialization
override init(frame: CGRect) {
    super.init(frame: frame)
    setupButtons()
}

required init(coder: NSCoder) {
    super.init(coder: coder)
    setupButtons()
}

      // MARK: Private Methods
private func setupButtons(){


    // Clear any existing buttons
    for button in ratingButtons{
        removeArrangedSubview(button)
        button.removeFromSuperview()
    }
    ratingButtons.removeAll()

    // Load Button Images
    let bundle = Bundle(for: type(of: self))
    let filledStar = UIImage(named: "filledStar", in: bundle, compatibleWith: self.traitCollection)
    let emptyStar = UIImage(named: "emptyStar", in: bundle, compatibleWith: self.traitCollection)
    let highligtedStar = UIImage(named: "highlightedStar", in: bundle, compatibleWith: self.traitCollection)

    for _ in 0..<starCount {
    // Create the button
    let button = UIButton()

    // Set the button images
        button.setImage(emptyStar, for: .normal)
        button.setImage(filledStar, for: .selected)
        button.setImage(highligtedStar, for: .highlighted)
        button.setImage(highligtedStar, for: [.highlighted, .selected])

    // Adding constraints
    button.translatesAutoresizingMaskIntoConstraints = false // disables buttons automatically generated constraints
    button.heightAnchor.constraint(equalToConstant: starSize.height).isActive = true // defines height
    button.widthAnchor.constraint(equalToConstant: starSize.width).isActive = true // defines width

    //Setup the button action
    button.addTarget(self, action: #selector(RatingControl.ratingButtonTapped(button:)), for: .touchUpInside)

    // Add button to stack
    addArrangedSubview(button)

    // Add the new button to the rating button Array
    ratingButtons.append(button)
    }
    updateButtonSelectionStates()
}

// MARK: Button Action
@objc func ratingButtonTapped(button:UIButton){

    guard let index = ratingButtons.index(of: button) else {
        fatalError("The button, \(button), is not in the ratingButtons array: \(ratingButtons)")
    }
    // Calculate the rating of the selected button
    let selectedRating = index + 1
    if selectedRating == rating { // If the selected star represents the current rating, reset the rating to 0
        rating = 0
    } else{
        // Otherwise set the rating to the selected star
        rating = selectedRating
    }
}
private func updateButtonSelectionStates() { // Update buttons appearance
    for (index, button) in ratingButtons.enumerated() {
        // If the index of a button is less than the rating, that button should be selected
        button.isSelected = index < rating
    }
}

}

标签: iosswiftuitableview

解决方案


你搞错了。您的表格视图不保存数据,它显示它。您希望拥有一个数据模型来保存您从表视图中显示的值。这就是为您的 tableView 数据源方法提供的内容。通常它将是一个结构数组。

您想打印表格视图的数据模型的内容。

编辑:

现在您已经提供了该信息,我们可以为您提供帮助。

为您的数据模型添加CustomStringConvertible一致性:

class Match: NSObject, NSCoding, CustomStringConvertible  {

的唯一要求CustomStringConvertible是您提供的计算属性descriptionString

var description: String {
   return "Match(name:\(name),rating:\(rating))"
}

然后在您的按钮操作中

@IBAction func logInfo(sender: UIButton) {
    matching.forEach { print($0) }
}

由于您的Match类现在符合CustomStringConvertible,因此您可以直接打印Match对象。

或者,如果您想要索引:

@IBAction func logInfo(sender: UIButton) {
    matching.enumerated()forEach { print(String(format:"%02l", $0.0) + ": " + $0.1) }
}

推荐阅读