首页 > 解决方案 > 段控制器没有正确滚动

问题描述

我正在尝试实现一种方法,我有一个 tableviewcontroll,它有一个标题,它显示一个头部图片以及另一个包含用户信息和个人资料图片的部分。在头部下方,我希望有一个像 twitter 这样的段控件,它允许用户在不同的 tableview 之间切换。我希望该段控件位于标题视图下方,因此当用户下拉时,段控件会随着标题视图向下移动,当您向上滚动时,段控件会随着标题视图向上移动,但随后会粘在导航栏下方,类似于如何twitter 和 instagram 的 UI 可以正常工作。我已经实现了下面的代码,但是当我向上滚动时,段控制器不会移动,但是当我在屏幕上下拉时,段控制器会随着标题视图向下移动。

这是代码

class RandomTableViewController: UITableViewController {

    @IBOutlet weak var trackImage: UIImageView!

 private let tableHeaderViewHeight: CGFloat = 320.0
        private let tableHeaderViewCutAway: CGFloat = 0.1

        var headerView: HeaderView!
        var headerMaskLayer: CAShapeLayer!

        override func viewDidLoad() {
            super.viewDidLoad()

            self.automaticallyAdjustsScrollViewInsets = false

            tableView.estimatedSectionHeaderHeight = 40.0

            navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
            navigationController?.navigationBar.shadowImage = UIImage()



            tableView.tableFooterView = UIView()

            headerView = tableView.tableHeaderView as! HeaderView
//            headerView.imageView = trackImage
            tableView.tableHeaderView = nil
            tableView.addSubview(headerView)

            tableView.contentInset = UIEdgeInsets(top: tableHeaderViewHeight, left: 0, bottom: 0, right: 0)
            tableView.contentOffset = CGPoint(x: 0, y: -tableHeaderViewHeight + 64)

            //cut away header view
            headerMaskLayer = CAShapeLayer()
            headerMaskLayer.fillColor = UIColor.black.cgColor
            headerView.layer.mask = headerMaskLayer

            let effectiveHeight = tableHeaderViewHeight - tableHeaderViewCutAway/2
            tableView.contentInset = UIEdgeInsets(top: effectiveHeight, left: 0, bottom: 0, right: 0)
            tableView.contentOffset = CGPoint(x: 0, y: -effectiveHeight)

            updateHeaderView()
        }

        func updateHeaderView() {
            let effectiveHeight = tableHeaderViewHeight - tableHeaderViewCutAway/2
            var headerRect = CGRect(x: 0, y: -effectiveHeight, width: tableView.bounds.width, height: tableHeaderViewHeight)

            if tableView.contentOffset.y < -effectiveHeight {
                headerRect.origin.y = tableView.contentOffset.y
                headerRect.size.height = -tableView.contentOffset.y + tableHeaderViewCutAway/2
            }

            headerView.frame = headerRect

            let path = UIBezierPath()
            path.move(to: CGPoint(x: 0, y:0))
            path.addLine(to: CGPoint(x: headerRect.width, y: 0))
            path.addLine(to: CGPoint(x: headerRect.width, y: headerRect.height))
            path.addLine(to: CGPoint(x: 0, y: headerRect.height - tableHeaderViewCutAway))

            headerMaskLayer?.path = path.cgPath
        }

          override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
              self.tableView.decelerationRate = UIScrollView.DecelerationRate.fast
          }

          override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
              return UITableView.automaticDimension
          }



        @IBAction func backButton(_ sender: Any) {
            dismiss(animated: true, completion: nil)
        }

    }

    extension RandomTableViewController {



        override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
             let v = UIView()
            v.backgroundColor = .white
             let segmentedControl = UISegmentedControl(frame: CGRect(x: 10, y: 5, width: tableView.frame.width - 20, height: 30))
             segmentedControl.insertSegment(withTitle: "One", at: 0, animated: false)
             segmentedControl.insertSegment(withTitle: "Two", at: 1, animated: false)
             segmentedControl.insertSegment(withTitle: "Three", at: 2, animated: false)
             v.addSubview(segmentedControl)
             return v
        }



        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            100

        }

        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell: UITableViewCell! = tableView.dequeueReusableCell(withIdentifier: "CellID")
            cell.textLabel?.text = "\(indexPath.row)"
            return cell
        }


    }


    extension RandomTableViewController {
        override func scrollViewDidScroll(_ scrollView: UIScrollView) {
            updateHeaderView()
        }
    }

我有自定义 HeaderView 代码是

import UIKit

class HeaderView: UIView {


    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var trackImage: UIImageView!
    @IBOutlet weak var backButton: UIButton!

}

这是它正在做的事情

图像1

图2

更新:

我实现了分组表视图并在 viewForSectionInHeader 中设置了estimateSectioHeaderHeight,现在分段控件上下移动,但向上滚动时它没有粘在导航栏下方。现在似乎还有格式问题。这是模拟器的外观

在此处输入图像描述 在此处输入图像描述

标签: iosswiftxcodeuitableviewuisegmentedcontrol

解决方案


将表格样式更改为分组并在 heightForHeaderInSection 中设置分段视图的高度。检查它是否有效。


推荐阅读