在单个屏幕中拥有一些UITableViews和一些UICollectionViews

时间:2019-04-01 10:25:57

标签: ios swift uitableview uiviewcontroller uicollectionview

我目前正在处理一个特殊的问题,我必须在一个屏幕上添加一个UITableView和几个UICollectionViews以及几个标签。

这是样机:-

The screen I need to build

现在,这就是我的视图外观(我现在仅在UI上工作):-

The current screen I have built

“立即直播”和“相关故事”下面的UICollectionViews可水平滚动,并且在这些UICollectionViews的中间是UITableView

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

我考虑过使用包含所有视图(集合视图和表视图)的另一个UITableview,但是随后,该特定表视图的滚动会导致我不得不添加的表视图的不良滚动体验。 / p>

上面说的是使用UIScrollView(要添加的UICollectionViews不会出现问题,因为它们是水平滚动的。)

最好使用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)
}
}

4 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:1)

您可以使用单个表视图进行全屏显示,并通过在其中添加UICollectionView来创建自定义单元格。

答案 2 :(得分:0)

具有嵌套的滚动视图可能违反HIG准则,该准则主张不要将滚动视图放置在另一个滚动视图内部。

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

有关更多详细信息,请参阅https://developer.apple.com/design/human-interface-guidelines/ios/views/scroll-views/上的HIG文档

答案 3 :(得分:0)

您可以执行此操作,而无需在更新下方的代码中进行任何重大更改。

  1. 首先,需要设置Tableview Height的约束出口。例如consTblHeight
  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()
        }