เลื่อนอย่างต่อเนื่องระหว่าง tableView และ scrollView

ฉันมีมุมมองเลื่อนหลักพร้อมส่วนหัว uiview และมุมมองตาราง ฉันกำลังพยายามมีพฤติกรรมคล้ายกับหน้าโปรไฟล์ Twitter หรือ Instagram คุณเริ่มเลื่อนมุมมองการเลื่อนหลัก และทันทีที่ส่วนหัวหายไป จะมีการเปลี่ยนแปลง ต่อเนื่อง จากมุมมองเลื่อนที่เลื่อนไปยังมุมมองตาราง โดยไม่จำเป็นต้องยกนิ้วขึ้นและแทนที่ในมุมมองตาราง . ตอนนี้พฤติกรรมตอนนี้ก็จะเพี้ยนๆ หน่อย ฉันต้องยกนิ้วขึ้นและวางลงบนมุมมองตารางหลังจากที่ออฟเซ็ตเนื้อหามุมมองเลื่อนเลยส่วนหัวไปแล้วเพื่อเริ่มปัดมุมมองตาราง

MainViewController

    import UIKit
    import XLPagerTabStrip

    class MainViewController: UIViewController {

        lazy var headerViewController: UIViewController = {
            let header = UIViewController()
            return header
        }()

        lazy var bottomViewControllers: BottomPageViewController = {
            let bvc = BottomPageViewController()
            return bvc
        }()

        lazy var scrollView: UIScrollView = {
            let sv = UIScrollView()
            sv.delegate = self
            sv.showsVerticalScrollIndicator = false
            sv.bounces = true
            sv.bounces = false
            return sv
        }()


    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(scrollView)
        let f = UIScreen.main.bounds
        scrollView.frame = CGRect(x: f.minX, y: f.minY, width: f.width, height: f.height)

        add(headerViewController, to: scrollView, frame: CGRect(x: 0, y: 0, width: f.width, height: 150))
        add(bottomViewControllers, to: scrollView, frame: CGRect(x: 0, y: headerViewController.view.bounds.height, width: f.width, height: f.height))
        scrollView.contentSize = CGSize(width: f.width, height: f.height * 2)

        if let vcs = bottomViewControllers.viewControllers as? [BottomViewController] {
            for vc in vcs {
                vc.delegate = self
            }
        }
    }

}

extension MainViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        guard let controllers = bottomViewControllers.viewControllers as? [BottomViewController] else { return }
        let selectedController = controllers[bottomViewControllers.currentIndex]
        if self.scrollView == scrollView {
            selectedController.tableView.isScrollEnabled = self.scrollView.contentOffset.y >= 150
            print(scrollView.contentOffset.y)
            scrollView.isScrollEnabled = !selectedController.tableView.isScrollEnabled
            bottomViewControllers.view.frame.origin.y = max(150, scrollView.contentOffset.y)
        }


    }
}

extension MainViewController: CustomScrollDelegate {
    func tableViewScroll(_ viewController: BottomViewController) {
        print(viewController.tableView.contentOffset.y)
        viewController.tableView.isScrollEnabled = viewController.tableView.contentOffset.y > 0
    }
}

คอนโทรลเลอร์ BottomView

import UIKit
import XLPagerTabStrip

protocol CustomScrollDelegate {
    func tableViewScroll(_ viewController: BottomViewController)
}

class BottomViewController: UITableViewController {

    var pageTitle: String?
    var pageIndex: Int = 0
    var delegate: CustomScrollDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .red
        self.tableView.isUserInteractionEnabled = false
        self.tableView.bounces = true
        self.tableView.showsVerticalScrollIndicator = true
        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "TETST")
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "TETST", for: indexPath) as? UITableViewCell else { return UITableViewCell() }
        return cell
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1000
    }

    override func scrollViewDidScroll(_ scrollView: UIScrollView) {
        delegate?.tableViewScroll(self)
    }

    init(pageTitle: String, pageIndex: Int) {
        self.pageTitle = pageTitle
        self.pageIndex = pageIndex
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

extension BottomViewController: IndicatorInfoProvider {
    func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo {
        return IndicatorInfo.init(title: pageTitle ?? "Tab \(pageIndex)")
    }
}

person joethemow    schedule 14.12.2019    source แหล่งที่มา


คำตอบ (1)


คุณควรเพิ่มส่วนหัวของคุณเป็นส่วนหัวของ UITableView (ไม่ใช่ส่วนหัวของส่วน!) และปล่อยให้มันเลื่อนไปพร้อมกับส่วนที่เหลือของ UITableView: จะเลื่อนส่วนหัวพร้อมกับ UITableView ได้อย่างไร

นอกจากนี้คุณยังสามารถสร้างลิงก์ UITableView เป็น contentSize ตรงความสูงได้ ดังนั้น UITableView จึงไม่เลื่อนเลย เช่นนี้: การปรับขนาด UITableView ให้พอดีกับเนื้อหา

ทุกอย่างขึ้นอยู่กับว่าคุณเพิ่มแถวแบบไดนามิกโดยการเพจ ฯลฯ ความซับซ้อนของโซลูชันของคุณจะเป็นอย่างไร แต่ฉันคิดว่าคุณจะไปถึงจุดนั้นได้เกือบตลอดเวลาโดยการตั้งค่าส่วนหัว UITableView ในโหมดที่ถูกต้อง

person Lucas van Dongen    schedule 14.12.2019
comment
ปัญหาคือฉันมีมุมมองตาราง 2 มุมมองเคียงข้างกัน ดังนั้นฉันจึงต้องการมุมมองแยกต่างหากสำหรับส่วนหัวร่วม - person joethemow; 14.12.2019
comment
ใช้ UIScrollView เพิ่ม UIView ภายใน เพิ่มส่วนหัวที่ด้านบน และ UITableViews ทั้งสองด้านล่าง จากนั้นตรวจสอบ contentSize ของมุมมองตาราง ทั้งสอง และตั้งค่านั้นเป็นความสูง ขั้นต่ำ ของ UITableView นั้นเป็นข้อจำกัด ตอนนี้ UITableView ที่สูงที่สุดจะดัน UIView ด้านในออกไปให้ได้ความสูงที่ถูกต้องเสมอ และ UITableView ที่สั้นที่สุดก็จะยาวขึ้นโดยไม่มีข้อผิดพลาดในการจัดวางใดๆ แจ้งให้เราทราบหากใช้งานได้และฉันจะอัปเดตคำตอบ - person Lucas van Dongen; 15.12.2019