ios - Swift 中一个垂直 ScrollView 中的多个水平 ScrollView ?

标签 ios swift

我正在尝试在 Swift 的应用程序中实现最标准的布局之一。
这基本上是在一个垂直 ScrollView 中有多个水平 ScrollView 。
这些子水平 ScrollView 中的每一个都将包含一些带有图像的 View 。
像这样的东西:
enter image description here
实现这一目标的最佳方法是什么?
附言我需要使用代码来执行此操作,因为内容是通过远程 JSON 文件提取的。
任何指针将不胜感激。

最佳答案

我会做以下事情。

  • 使用 UITableView 对于垂直 ScrollView 。
  • class TableViewController: UITableViewController {
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.tableView.register(TableViewCell.self, forCellReuseIdentifier: TableViewCell.identifier)
            self.tableView.register(TableViewHeader.self, forHeaderFooterViewReuseIdentifier: TableViewHeader.identifier)
            
            self.tableView.dataSource = self
            self.tableView.delegate = self
        }
    }
    
    
    extension TableViewController {
        
       override func numberOfSections(in tableView: UITableView) -> Int {
            return 10
        }
        
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 1
        }
        
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: TableViewCell.identifier,
                                                     for: indexPath) as! TableViewCell
            return cell
        }
    }
    
    
    extension TableViewController {
        override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return 250
        }
        
        override  func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
            let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: TableViewHeader.identifier)
            header?.textLabel?.text = "Header \(section)"
            return header
        }
        
        
        override   func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
            return 50
        }
    }
    
    
    
  • 使用 UICollectionView 对于水平 ScrollView 。
  • class CollectionView: UICollectionView {
        override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
            super.init(frame: frame, collectionViewLayout: layout)
            self.backgroundColor = .white
            self.register(CollectionViewCell.self, forCellWithReuseIdentifier: CollectionViewCell.identifier)
            
            self.dataSource = self
            self.delegate = self
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    
    
    extension CollectionView: UICollectionViewDataSource {
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return 10
        }
        
        func collectionView(_ collectionView: UICollectionView,
                            cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CollectionViewCell.identifier,
                                                          for: indexPath) as! CollectionViewCell
            cell.index = indexPath.row
            return cell
        }
    }
    
    
    
    extension CollectionView: UICollectionViewDelegateFlowLayout {
        func collectionView(_ collectionView: UICollectionView,
                            layout collectionViewLayout: UICollectionViewLayout,
                            sizeForItemAt indexPath: IndexPath) -> CGSize {
            return CGSize(width: 200, height: 250)
        }
        
        func collectionView(_ collectionView: UICollectionView,
                            layout collectionViewLayout: UICollectionViewLayout,
                            minimumLineSpacingForSectionAt section: Int) -> CGFloat {
            return 20
        }
        
        func collectionView(_ collectionView: UICollectionView,
                            layout collectionViewLayout: UICollectionViewLayout,
                            minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
            return 0
        }
    }
    
    
    class CollectionViewCell: UICollectionViewCell {
        static let identifier = "CollectionViewCell"
        
        var index: Int? {
            didSet {
                if let index = index {
                    label.text = "\(index)"
                }
            }
        }
        
        private let label: UILabel = {
            let label = UILabel()
            return label
        }()
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            self.contentView.backgroundColor = .red
            self.contentView.addSubview(label)
    
            let constraints = [
                label.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
                label.centerXAnchor.constraint(equalTo: contentView.centerXAnchor)
            ]
    
            NSLayoutConstraint.activate(constraints)
    
            label.translatesAutoresizingMaskIntoConstraints = false
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
    }
    
    
    
  • 每个 UITableViewCell 包含 UICollectionView (水平 ScrollView )。
  • class TableViewCell: UITableViewCell {
        static let identifier = "TableViewCell"
        
        override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            self.backgroundColor = .white
            
            let layout = UICollectionViewFlowLayout()
            layout.scrollDirection = .horizontal
            
    
            let subView = CollectionView(frame: .zero, collectionViewLayout: layout)
    
            self.contentView.addSubview(subView)
    
            let constraints = [
                subView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 1),
                subView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 1),
                subView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 1),
                subView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 1)
            ]
    
            NSLayoutConstraint.activate(constraints)
    
            subView.translatesAutoresizingMaskIntoConstraints = false
            
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    
    
    
  • 使用 UITableViewHeaderFooterView ( tableView(_:viewForHeaderInSection:) ) 用于水平 ScrollView 的标题
  • 
    class TableViewHeader: UITableViewHeaderFooterView {
        static let identifier = "TableViewHeader"
    }
    

    我添加了一个完整的工作示例的代码。只需使用 TableViewController你很高兴去。

    更新
    UITableViewCells 应该具有动态单元格高度。
    经过测试,我发现最好使用固定单元格大小而不是动态单元格,因为单元格可能具有不同的高度应该使用 UITableView.automaticDimension

    关于ios - Swift 中一个垂直 ScrollView 中的多个水平 ScrollView ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65936627/

    相关文章:

    ios - 如何在我的 Swift 类中使用 Objective-c 方法

    ios - iphone 6 中 UITableViewCell 的默认宽度

    ios - 即使条件为假,代码也会执行

    带有增量的 Swift 3 for 循环

    ios - 如何打开已在搜索栏中输入特定测试的维基百科主页

    ios - 为什么是 "picker.delegate = self necessary"?

    ios - UISwitch 不应该以相反的方式工作吗?

    iphone - beginBackgroundTaskWithExpirationHandler 永远不会被调用

    iphone - ABAddressBookCreate() , ABAddressBookGetGroupCount , ... 返回 @"0x00000000 <nil>"?

    ios - Web 请求确实无法正常工作