【问题标题】:Add SwiftUI on a UIView which is Inside of a UITableViewCell [duplicate]在 UITableViewCell 内部的 UIView 上添加 SwiftUI [重复]
【发布时间】:2021-12-04 21:21:42
【问题描述】:

如何在 UITableViewCell 内部的 UIView 上添加 SwiftUI,通常使用 uihostingcontroller 可以将 SwiftUI 视图作为子级添加到 ViewController 但我们该怎么做这在 UITableViewCell

【问题讨论】:

    标签: swift swiftui swift3


    【解决方案1】:

    我能够得到这样的工作:

    import UIKit
    import SwiftUI
    import PlaygroundSupport
    
    let cellIdentifier = "Swift Content"
    
    struct CellContent : View {
        let title : String
    
        init(title: String) {
            self.title = title
        }
    
        var body : some View {
            Text(title)
        }
    }
    
    class SwiftUITableCell : UITableViewCell {
        var swiftContent = UIHostingController(rootView: CellContent(title: "Placeholder}"))
    }
    
    let tableView = UITableView(frame: CGRect(x: 0,y: 0,width: 320,height: 480))
    let dataSource = UITableViewDiffableDataSource<Int,String>(tableView: tableView) {
        (tableView: UITableView, indexPath: IndexPath, itemIdentifier: String) -> UITableViewCell? in
        let newCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as!SwiftUITableCell
    
        newCell.swiftContent = UIHostingController.init(rootView: CellContent(title: itemIdentifier))
        newCell.swiftContent.view.frame = newCell.contentView.bounds.inset(by: UIEdgeInsets(top: 4, left: 4, bottom: 4, right: 4))
        newCell.contentView.addSubview(newCell.swiftContent.view)
    
        return newCell
    }
    
    tableView.register(SwiftUITableCell.self, forCellReuseIdentifier: cellIdentifier)
    tableView.dataSource = dataSource
    
    var currentSnapshot = NSDiffableDataSourceSnapshot<Int, String>()
    currentSnapshot.appendSections([0])
    currentSnapshot.appendItems(["Foo", "Bar", "Baz"], toSection: 0)
    dataSource.apply(currentSnapshot)
    
    PlaygroundSupport.PlaygroundPage.current.liveView = tableView
    

    为了使这更加“真实”,您必须设置您的 swift 视图来处理UITableViewCell 可能发生的所有各种配置更改。

    【讨论】:

      【解决方案2】:

      使用 @Binding 更新状态

      import SwiftUI
      import UIKit
      
      class TableTestVC: UIViewController, UITableViewDataSource, UITableViewDelegate {
          @IBOutlet weak var tableView: UITableView!
          var count = 50
      
          let demo = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
      
          override func viewDidLoad() {
              super.viewDidLoad()
      
              tableView.register(TableTestCell.self, forCellReuseIdentifier: "TableTestCell")
          }
      
          func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
              let range = (0 ... demo.count).randomElement() ?? 0
              let cell = tableView.dequeueReusableCell(withIdentifier: "TableTestCell") as! TableTestCell
              cell.label = String(demo.prefix(range))
              return cell
          }
      
          func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
              return count
          }
      }
      
      class TableTestCell: UITableViewCell {
          lazy var view = TableTestCellView(label: self.labelBinder)
          var label: String = "none"
      
          lazy var labelBinder = Binding { self.label } set: { self.label = $0 }
      
          override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
              super.init(style: style, reuseIdentifier: reuseIdentifier)
      
              let sub = UIHostingController(rootView: view).view!
              contentView.addSubview(sub)
              sub.translatesAutoresizingMaskIntoConstraints = false
              sub.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
              sub.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
              sub.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
              sub.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
          }
      
          @available(*, unavailable)
          required init?(coder: NSCoder) {
              fatalError("init(coder:) has not been implemented")
          }
      }
      
      struct TableTestCellView: View {
          @Binding var label: String
      
          var body: some View {
              Text(label)
                  .padding()
                  .multilineTextAlignment(.leading)
                  .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
          }
      }
      
      struct ContentView_Previews: PreviewProvider {
          static var previews: some View {
              TableTestCellView(label: .constant("Testing\nHello world"))
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多