1

我正在使用 MacOs Big Sur 和 Xcode 12.2 编写应用程序。

我正在尝试为联系人列表实现表格视图(来自互联网上的示例)。

大部分代码是针对 IOS 的,很难移植到 MacOS 上。

对于大多数功能,该应用程序运行良好。

我无法成功实现节的页眉/页脚。

我之前围绕 CollectionView 构建的项目确实取得了成功。

但是我看不到 CollectionView 和 TableView 之间的类比。在 CollectionView 中,我为页眉/页脚使用了笔尖。

以下是 Diffable Datasource 示例的代码片段。

我希望有人可以帮助解决我的问题。

'''
override func viewDidLoad() {
   tableView.delegate = self
   DataSource = makeDataSource()        
   tableView.dataSource = DataSource
   update(with:ContactList(all: Contact.all, 
          friends: [], 
          family: [], 
          coworkers: []),    
          animate: true)
}


func makeDataSource() -> NSTableViewDiffableDataSource<Section, Contact> {
    let reuseIdentifier = ContactTableCell.reuseIdentifier
    return NSTableViewDiffableDataSource( tableView: tableView, cellProvider: { tableView, column, indexPath, contact  in
        guard let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(reuseIdentifier), owner: self) as? ContactTableCell else {
            print("Failed to create results cell")
            return NSView()
        }
        cell.configure(with: contact)
        return cell
    }
    )
}

func update(with list: ContactList, animate: Bool = true) {
    var snapshot = NSDiffableDataSourceSnapshot<Section, Contact>()
    snapshot.appendSections([Section.all, Section.family,Section.coworkers,Section.friends])
    
    snapshot.appendItems(list.all, toSection: .all)
    snapshot.appendItems(list.family, toSection: .family)
    snapshot.appendItems(list.coworkers, toSection: .coworkers)
    snapshot.appendItems(list.friends, toSection: .friends)
    
    DataSource.apply(snapshot, animatingDifferences: animate)
}

class ContactTableCell: NSTableCellView{

    @IBOutlet weak var firstname: NSTextField!
    @IBOutlet weak var lastname: NSTextField!
    @IBOutlet weak var email: NSTextField!
    @IBOutlet weak var userView: NSImageView!

    static var reuseIdentifier: String {
        return NSUserInterfaceItemIdentifier(String(describing: ContactTableCell.self)).rawValue
    }

    func configure(with contact:Contact){
        print("\(#function)")
        self.userView.imageScaling = .scaleProportionallyDown
        self.userView.image = NSImage(contentsOfFile:contact.imagePath)
        self.firstname.stringValue = contact.firstName //"\(contact.firstName) \(contact.lastName)"
        self.lastname.stringValue = contact.lastName  //contact.emailAddress
        self.email.stringValue = contact.emailAddress
    }
}

class SectionHeaderView: NSTableHeaderView {
static var reuseIdentifier: String {
    return NSUserInterfaceItemIdentifier(String(describing: SectionHeaderView.self)).rawValue
}

lazy var headerLabel: NSTextField = {
    print("\(#function)")
    let label = NSTextField()
    label.textColor = .red
    label.font = NSFont.systemFont(ofSize: 15, weight: .medium)
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()
    
override  func draw(_ dirtyRect: NSRect) {
    print("\(#function)")
    super.draw(dirtyRect)
    // Drawing code here.
}

required  init?(coder: NSCoder) {
    print("\(#function)")
    super.init(coder: coder)
    setupView()
}

func setupView() {
    print("\(#function)")
    addSubview(headerLabel)
    setupLayout()
}

func setupLayout() {
    print("\(#function)")
    NSLayoutConstraint.activate([
        headerLabel.topAnchor.constraint(equalTo: self.topAnchor ,constant: 2),
        headerLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, 
                                            constant: -2),
        headerLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor,
                                             constant: 8),
        headerLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor,
                                            constant: -8),
    ])
}

} '''

4

2 回答 2

1

macOS 中的表格视图的工作方式有点不同,因为没有像 iOS 中那样明确的部分。节标题是作为数据源数组的一部分内联的组行。

要在 diffable 数据源中显示节标题,请创建一个结构而不是枚举

struct Section : Hashable {
    let name : String
}

延长makeDataSource()

func makeDataSource() -> NSTableViewDiffableDataSource<Section, Contact> 
{
    let reuseIdentifier = ContactTableCell.reuseIdentifier
    let dataSource = NSTableViewDiffableDataSource<Section,Contact>( tableView: tableView, cellProvider: { tableView, column, row, contact  in
        let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(reuseIdentifier), owner: self) as! ContactTableCell
        cell.configure(with: contact)
        return cell
    })

    dataSource.sectionHeaderViewProvider = { tableView, row, section in
        let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "group"), owner: self) as! NSTableCellView
        cell.textField?.stringValue = section.name
        return cell
    }
    return dataSource
}

并填充数据源

func update(with list: ContactList, animate: Bool = true) {
    var snapshot = NSDiffableDataSourceSnapshot<Section, Contact>()
    let sections = [Section(name: "all"), Section(name: "family"), Section(name: "coworkers"), Section(name: "friends")

    snapshot.appendSections(sections)
    snapshot.appendItems(list.all, toSection: sections[0])
    snapshot.appendItems(list.family, toSection: sections[1])
    snapshot.appendItems(list.coworkers, toSection: sections[2])
    snapshot.appendItems(list.friends, toSection: sections[3])
    DataSource.apply(snapshot, animatingDifferences: animate)
}
于 2022-01-01T18:55:55.973 回答
0

我遇到了类似的问题,并查看源代码,在您的情况下可能需要做的是将这些设置为您的 diffableDataSource:

@property (copy, nullable) NSTableViewDiffableDataSourceRowProvider rowViewProvider;

@property (copy, nullable) NSTableViewDiffableDataSourceSectionHeaderViewProvider sectionHeaderViewProvider;

我认为没有节页脚 API,因此您可能需要在节中的最后一个单元格项目上显示某种页脚。

于 2021-07-28T16:49:40.133 回答