如何通过UITableView.automaticDimension在uitableviews静态单元格内使用uiscrollview

时间:2019-03-23 11:42:31

标签: ios swift xcode uitableview uiscrollview

我已经创建了一个滑块,如此处所述:https://medium.com/@anitaa_1990/create-a-horizontal-paging-uiscrollview-with-uipagecontrol-swift-4-xcode-9-a3dddc845e92

使用Xcode 10.1,Swift 4.2.1

我有一个额外的用户界面视图,如本教程中一样,仅包含一个uiimageview和4个约束:

  • 安全区域底部=图像视图底部
  • 图像视图顶部=安全区域顶部
  • 图像视图centerx =超级视图centerx
  • 图片视图宽度=超级视图宽度

所以它的自定义类是:

class ImageSlide: UIView {

    @IBOutlet weak var mainImageView: UIImageView!   
}

我有一个带有Tableview控制器的情节提要。表格视图的内容与Static cells设置为automaticDimension。 使用此约束进行滚动视图

enter image description here

控制器生命周期:

override func viewDidLoad() {
    ...
    self.tableView.rowHeight = UITableView.automaticDimension
    self.tableView.estimatedRowHeight = 40.0
    ...
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    setupSlideScrollView(with: slides)
}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    setupSlideScrollView(with: slides)
}

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

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // time consuming (pictures fetched over the network)
    slides = createSlides()
    setupSlideScrollView(with: slides)
}
private func createSlides() -> [ImageSlide] {

    // slides will be fetched over the network
    // testing the scaleAspects
    ...
    slide1.mainImageView.image = ...
    slide1.mainImageView.contentMode = .scaleAspectFill

    slide2.mainImageView.image = ...
    slide2.mainImageView.contentMode = .scaleAspectFit

    return [slide1, slide2]
}
private func setupSlideScrollView(with slides: [ImageSlide]?) {

    sliderScrollView.contentSize = CGSize(width: view.frame.width * CGFloat(slides?.count ?? 1), height: 300.0)
    sliderScrollView.frame.size = CGSize(width: view.frame.width, height: 300.0)

    if let imageSlides = slides {

        for i in 0..<imageSlides.count {
            imageSlides[i].frame = CGRect(x: view.frame.width * CGFloat(i), y: 0, width: view.frame.width, height: 300.0)

            sliderScrollView.addSubview(imageSlides[i])
        }

        print("scroll view frame height: \(sliderScrollView.frame.height)")
        print("scroll view contentsize height: \(sliderScrollView.contentSize.height)")
        print("slides[0] frame height: \(imageSlides[0].frame.height)")

    }

}

我正在使用300.0的硬编码高度值进行测试。在iPad Pro 12.9英寸第三代上运行此设备,可以得到一个高度约为40或50的单元。第一张幻灯片在整个宽度上拉伸,第二张幻灯片非常小,适合于高度(因此远远超出了scaleAspectFill / scaleAspectFit)。 日志显示:

[Warning] Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.
scroll view frame height: 300.0
scroll view contentsize height: 300.0
slides[0] frame height: 300.0
scroll view frame height: 300.0
scroll view contentsize height: 300.0
slides[0] frame height: 300.0

我在表格视图中确实有一些空单元格,不知道警告是由于它们还是由于滑块。 旋转设备时,给定幻灯片的高度似乎为300.0,但是单元格更大(充满了整个屏幕)。

我不明白为什么开始时单元格高度大约为40或50,并显示警告消息。为什么单元格无法自动适应指定的300高度? 例如,我想说的是,滑块的高度应始终为例如view.frame.height/3。细胞也应该如此。我放入滑块中的图像应遵守scaleAscpectFill并填满整个宽度。但是不知道怎么办。

1 个答案:

答案 0 :(得分:0)

休息片刻后,我想出了一个解决方案,实际上我不确定是解决方案还是解决方法。

我添加了一个计算属性

var sliderHeight: CGFloat! {
    get {
        return view.frame.width/2
    }
}

并更改了

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath.section == 0, indexPath.row == 0 {
        return sliderHeight
    }
    return UITableView.automaticDimension
}

分别将setupSlideScrollView方法更改为不使用300.0的硬编码高度,而使用sliderHeight。它仍然不是完美的(缺少页面控件视图,现在来看一下),但是到目前为止单元格的高度似乎是正确的。 顺便说一句,第一篇文章的警告也消失了。 您认为家伙是什么,一个适当的解决方案,或者只是一种解决方法?