【问题标题】:Having some UITableViews and some UICollectionViews in a single screen在一个屏幕中拥有一些 UITableViews 和一些 UICollectionViews
【发布时间】:2019-08-22 11:45:25
【问题描述】:

我目前正在解决一个特定问题,我必须在一个屏幕中添加一个 UITableView 和几个 UICollectionView 以及几个标签。

这是模型:-

现在,这就是我的视图的样子(我现在只是在处理 UI):-

“Live now”和“Related Stories”下方的 UICollectionView 可以水平滚动,并且在这些 UICollectionView 中间是一个 UITableView

我不想在我构建的 UIViewController 类中压缩这些子视图,而是希望以这样的方式重新制作它,使整个视图可以滚动,同时保持视图中当前设置的子视图的相同滚动体验。

我考虑使用另一个包含所有视图(集合视图和表格视图)的 UITableview,但是,滚动该特定表格视图会导致我必须添加的表格视图的滚动体验不佳。

上面可以说是使用 UIScrollView (将添加的 UICollectionView 没有问题,因为它们是水平滚动的)。

最好使用 UICollectionView 吗?

欢迎任何可以提供帮助的建议。如果我身边有任何事情,请告诉我

这是我的源代码:

import UIKit
import SnapKit
import EasyPeasy

class ArticleViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UITableViewDelegate, UITableViewDataSource {

var liveLabel = UILabel()
var engageLabel = UILabel()
var storyLabel = UILabel()

var livelayout = UICollectionViewFlowLayout.init()
var storylayout = UICollectionViewFlowLayout.init()
var liveCollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout.init())
var storyCollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout.init())

var liveRows = [
    "https://images.sportsflashes.com/australia-win-first-t20i-after-nail-biting-finish-at-vizag1551028137.jpg",
    "https://images.sportsflashes.com/australia-win-first-t20i-after-nail-biting-finish-at-vizag1551028137.jpg",
    "https://images.sportsflashes.com/australia-win-first-t20i-after-nail-biting-finish-at-vizag1551028137.jpg",
    "https://images.sportsflashes.com/australia-win-first-t20i-after-nail-biting-finish-at-vizag1551028137.jpg",
    "https://images.sportsflashes.com/australia-win-first-t20i-after-nail-biting-finish-at-vizag1551028137.jpg",
    "https://images.sportsflashes.com/australia-win-first-t20i-after-nail-biting-finish-at-vizag1551028137.jpg",
    "https://images.sportsflashes.com/australia-win-first-t20i-after-nail-biting-finish-at-vizag1551028137.jpg"
]

var articleRows = [
    "https://c.ndtvimg.com/2019-03/6dkbrsrg_varun-dhawan_625x300_14_March_19.jpg",
    "https://c.ndtvimg.com/2019-03/6dkbrsrg_varun-dhawan_625x300_14_March_19.jpg",
    "https://c.ndtvimg.com/2019-03/6dkbrsrg_varun-dhawan_625x300_14_March_19.jpg",
    "https://c.ndtvimg.com/2019-03/6dkbrsrg_varun-dhawan_625x300_14_March_19.jpg",
    "https://c.ndtvimg.com/2019-03/6dkbrsrg_varun-dhawan_625x300_14_March_19.jpg",
    "https://c.ndtvimg.com/2019-03/6dkbrsrg_varun-dhawan_625x300_14_March_19.jpg",
    "https://c.ndtvimg.com/2019-03/6dkbrsrg_varun-dhawan_625x300_14_March_19.jpg",
    "https://c.ndtvimg.com/2019-03/6dkbrsrg_varun-dhawan_625x300_14_March_19.jpg",
    "https://c.ndtvimg.com/2019-03/6dkbrsrg_varun-dhawan_625x300_14_March_19.jpg"
]

var storyRows = [
    "https://www.anime-planet.com/images/characters/takuma-mamizuka-83947.jpg",
    "https://www.anime-planet.com/images/characters/takuma-mamizuka-83947.jpg",
    "https://www.anime-planet.com/images/characters/takuma-mamizuka-83947.jpg",
    "https://www.anime-planet.com/images/characters/takuma-mamizuka-83947.jpg",
    "https://www.anime-planet.com/images/characters/takuma-mamizuka-83947.jpg",
    "https://www.anime-planet.com/images/characters/takuma-mamizuka-83947.jpg",
    "https://www.anime-planet.com/images/characters/takuma-mamizuka-83947.jpg",
    "https://www.anime-planet.com/images/characters/takuma-mamizuka-83947.jpg",
    "https://www.anime-planet.com/images/characters/takuma-mamizuka-83947.jpg"
]

let table = UITableView()

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.view.backgroundColor = UIColor.white

    if self.navigationController == nil {
        return
    }

    self.navigationController?.isNavigationBarHidden = false
    self.navigationItem.leftBarButtonItem = UIBarButtonItem(image:(UIImage(named: "back_arrow")?.withRenderingMode(.alwaysOriginal)), style:.plain, target:self, action:#selector(backPress))

    var dateBarButtonItem = UIBarButtonItem(title: "Mar 2019", style: .plain, target: self, action: nil)
    dateBarButtonItem.tintColor = UIColor.black
    self.navigationItem.rightBarButtonItem = dateBarButtonItem

    // Create a navView to add to the navigation bar
    let navView = UIView()

    // Create the label
    let nameLabel = UILabel()
    nameLabel.text = "Pavan Vasan"
    nameLabel.sizeToFit()
    nameLabel.center = navView.center
    nameLabel.textAlignment = NSTextAlignment.center

    // Create the image view
    let image = UIImageView()
    image.image = UIImage(named: "twitter")
    // To maintain the image's aspect ratio:
    let imageAspect = image.image!.size.width/image.image!.size.height
    // Setting the image frame so that it's immediately before the text:
    image.frame = CGRect(x: nameLabel.frame.origin.x-nameLabel.frame.size.height*imageAspect, y: nameLabel.frame.origin.y, width: nameLabel.frame.size.height*imageAspect, height: nameLabel.frame.size.height)
    image.contentMode = UIView.ContentMode.scaleAspectFit
    // Add both the label and image view to the navView
    navView.addSubview(nameLabel)
    navView.addSubview(image)

    // Set the navigation bar's navigation item's titleView to the navView
    self.navigationItem.titleView = navView

    // Set the navView's frame to fit within the titleView
    navView.sizeToFit()
}

override func viewDidLoad() {
    super.viewDidLoad()
    setupLiveCollectionView()
    setupTable()
    setupStoryCollectionView()
}

func setupLiveCollectionView() {
    self.view.addSubview(self.liveLabel)
    self.liveLabel.text = "Live now"
    self.liveLabel.font = UIFont.boldSystemFont(ofSize: 17.5)
    self.liveLabel.textColor = UIColor.black
    self.liveLabel.textAlignment = .center
    self.liveLabel.easy.layout(
        Left(10).to(self.view),
        Top(75).to(self.view)
    )

    livelayout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
    livelayout.itemSize = CGSize(width: 75, height: 75)
    livelayout.scrollDirection = .horizontal

    liveCollectionView = UICollectionView(frame: CGRect(x: 0, y: 100, width: self.view.frame.width, height: 95), collectionViewLayout: livelayout)
    liveCollectionView.dataSource = self
    liveCollectionView.delegate = self
    liveCollectionView.register(LiveViewCell.self, forCellWithReuseIdentifier: "MyCell")
    liveCollectionView.backgroundColor = UIColor.white
    liveCollectionView.showsHorizontalScrollIndicator = false
    self.view.addSubview(liveCollectionView)
}

func setupStoryCollectionView() {
    self.view.addSubview(self.storyLabel)
    self.storyLabel.text = "Related Stories"
    self.storyLabel.font = UIFont.boldSystemFont(ofSize: 17.5)
    self.storyLabel.textColor = UIColor.black
    self.storyLabel.textAlignment = .center
    self.storyLabel.easy.layout(
        Left(10).to(self.view),
        Top(15).to(self.table)
    )

    storylayout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
    storylayout.itemSize = CGSize(width: 120, height: 120)
    storylayout.scrollDirection = .horizontal

    storyCollectionView = UICollectionView(frame: CGRect(x: 0, y: 250 + self.view.bounds.height*0.40, width: self.view.frame.width, height: 130), collectionViewLayout: storylayout)
    storyCollectionView.dataSource = self
    storyCollectionView.delegate = self
    storyCollectionView.register(StoryViewCell.self, forCellWithReuseIdentifier: "StoryCell")
    storyCollectionView.backgroundColor = UIColor.white
    storyCollectionView.showsHorizontalScrollIndicator = false
    self.view.addSubview(storyCollectionView)
}

func setupTable() {

    table.delegate = self
    table.dataSource = self
    table.register(ArticleTableViewCell.self, forCellReuseIdentifier: "ArticleCell")
    table.separatorStyle = .none

    self.view.addSubview(table)
    self.table.easy.layout(
        Top(15).to(self.liveCollectionView),
        Left(0).to(self.view),
        Width(self.view.bounds.width),
        Height(self.view.bounds.height*0.4)
    )
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if collectionView == self.liveCollectionView {
        return self.liveRows.count
    } else if collectionView == self.storyCollectionView {
        return self.storyRows.count
    }
    return 0
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    if collectionView == self.liveCollectionView {
        let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath as IndexPath) as! LiveViewCell
        myCell.configure(self.liveRows[indexPath.row])
        return myCell
    } else if collectionView == self.storyCollectionView {
        let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "StoryCell", for: indexPath as IndexPath) as! StoryViewCell
        myCell.configure(self.storyRows[indexPath.row])
        myCell.layer.borderColor = UIColor.black.cgColor
        myCell.layer.cornerRadius = 15
        myCell.layer.borderWidth = 0.5
        myCell.layer.masksToBounds = true
        return myCell
    }
    return UICollectionViewCell()
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.articleRows.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ArticleCell", for: indexPath) as! ArticleTableViewCell
    cell.configure(self.articleRows[indexPath.row])
    return cell
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 325
}

@objc func backPress(sender:UIButton!) {
    self.navigationController?.popViewController(animated: true)
}
}

【问题讨论】:

  • 使用带有自定义单元格的单个表格视图 - 一些单元格将仅包含 UICollectionView。您可以在需要时获得一致的垂直滚动和独立的水平滚动。
  • @Losiowaty :如果我必须采用您的方法,我还必须在主表视图中包含一个表视图。由于父表视图也会有垂直滚动,单元格中的子表视图(具有垂直滚动)不会有滚动问题吗?如果我只有收藏视图,故事会有所不同
  • 为什么是另一个表格视图?只需将该表格视图中的单元格用作主表格视图的单元格。
  • @PavanVasan 您可以在单个表格视图中添加多个自定义单元格,并在特定位置添加多个集合视图,或者您也可以添加页眉或页脚。
  • @Losiowaty,我去看看,谢谢。而且,你是对的。我不需要另一个表格视图。感谢您指出了这一点。直到现在才意识到

标签: ios swift uitableview uiviewcontroller uicollectionview


【解决方案1】:

您无需对更新下方的代码进行任何重大更改即可做到这一点。

  1. 首先需要设置Tableview Height的约束出口。例如 constTblHeight
  2. 添加 Tableview 大小更改观察器。
func setupTable() {
    table.addObserver(self, forKeyPath: "contentSize", options: NSKeyValueObservingOptions.new, context: nil)
}
  1. 观察者法
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
            self.consTblHeight.constant = self.table.contentSize.height
            self.view.layoutIfNeeded()
        }

【讨论】:

    【解决方案2】:

    嵌套滚动视图可能违反 HIG 准则,该准则提倡不要将滚动视图放置在另一个滚动视图中。

    事实上,与我们的用例类似,Apple 给出了他们的 Stocks 应用程序的示例,其中股票报价在水平滚动的公司特定信息上方垂直滚动。

    更多详情请参考HIG文档https://developer.apple.com/design/human-interface-guidelines/ios/views/scroll-views/

    【讨论】:

      【解决方案3】:

      您可以将单个表格视图用于全屏并通过在其中添加 UICollectionView 创建自定义单元格。

      【讨论】:

        【解决方案4】:

        在复杂的屏幕中最好只使用一种主列表视图类型(UITableView 或 UICollectionView)。

        你可以在其中添加 UIStackView 或更多 UITableViews 或 UICollectionView。

        在您的情况下,我会使用 UICollectionView 并根据您的需要更改单元格的大小

        【讨论】:

          猜你喜欢
          • 2017-05-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-14
          相关资源
          最近更新 更多