代码之家  ›  专栏  ›  技术社区  ›  ttoggaiman

(ios)如何制作类似android sticky view的节头

  •  0
  • ttoggaiman  · 技术社区  · 3 年前

    我正在使用tableview的节标题。 https://www.youtube.com/watch?v=U3gqR4dRiT8

    如果你看的话,差不多到了最后

    当节头上升时,现有的顶部节头上升并碰撞并消失。

    顶部部分标题中的文本将被更改并浮动 但当我运行示例时,文本会发生变化。 它似乎没有向上推节头的效果。 我该怎么办?

    
    import UIKit
    
    class MyTableviewControllerTableViewController: UITableViewController {
    
        private let numberOfSections = 3
        var meat = ["Beef","Turkey","Fish", "Lamb", "Chicken", "Pork", "Beef","Turkey","Fish", "Lamb", "Chicken", "Pork"]
        var fruit = ["Apple","Banana","Cherry","Apple","Banana","Cherry","Apple","Banana","Cherry"]
        var vegetable = ["Lettuce","Broccoli","Cauliflower","Lettuce","Broccoli","Cauliflower","Lettuce","Broccoli","Cauliflower"]
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            // make the header sticky
            self.automaticallyAdjustsScrollViewInsets = false
        }
    
        // MARK: - Table view data source
    
        // return the number of sections
        override func numberOfSections(in tableView: UITableView) -> Int {
            return numberOfSections
        }
    
        // return the number of rows in the specified section
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            var rowCount = 0
            switch (section) {
            case 0:
                rowCount = meat.count
            case 1:
                rowCount = fruit.count
            case 2:
                rowCount = vegetable.count
            default:
                rowCount = 0
            }
            
            return rowCount
        }
    
        // Content Cell
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath)
    
            switch (indexPath.section) {
            case 0:
                cell.textLabel?.text = meat[indexPath.row]
            case 1:
                cell.textLabel?.text = fruit[indexPath.row]
            case 2:
                cell.textLabel?.text = vegetable[indexPath.row]
            default:
                cell.textLabel?.text = "Other"
            }
            return cell
        }
        
        // Header Cell
        override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
            let  headerCell = tableView.dequeueReusableCell(withIdentifier: "HeaderCell") as! CustomTableViewHeaderCell
            headerCell.backgroundColor = UIColor.gray
            
            switch (section) {
            case 0:
                headerCell.headerLabel.text = "Meat";
            case 1:
                headerCell.headerLabel.text = "Fruit";
            case 2:
                headerCell.headerLabel.text = "Vegetable";
            default:
                headerCell.headerLabel.text = "Other";
            }
            
            return headerCell
        }
        
        // Footer Cell
        override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
            let rect = CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: tableView.frame.size.width, height: 20))
            let footerView = UIView(frame: rect)
            footerView.backgroundColor = UIColor.darkGray
            return footerView
        }
        
        // footer height
        override func tableView(_ : UITableView, heightForFooterInSection section: Int) -> CGFloat {
            return 20.0
        }
    
    0 回复  |  直到 3 年前
        1
  •  1
  •   Fabio    3 年前

    你可以通过编程实现,结果非常完美。。。声明您的桌子视图,并随身携带 UIViewController (注意,这不是UITableViewController)类:

    class YourControllerClass: UIViewController {
    
    let tableView = UITableView()
    let cellId = "cellId"
    let headerId = "headerId"
    
    var meat = ["Beef","Turkey","Fish", "Lamb", "Chicken", "Pork", "Beef","Turkey","Fish", "Lamb", "Chicken", "Pork"]
    var fruit = ["Apple","Banana","Cherry","Apple","Banana","Cherry","Apple","Banana","Cherry"]
    var vegetable = ["Lettuce","Broccoli","Cauliflower","Lettuce","Broccoli","Cauliflower","Lettuce","Broccoli","Cauliflower"]
    

    立即在视图栏中配置和加载导航属性:

    override func viewDidLoad() {
        super.viewDidLoad()
        
        configureNavigationBar(largeTitleColor: .yourPreferColor, backgoundColor: .ultraDark, tintColor: .fuxiaRed, title: "My Title", preferredLargeTitle: true) // I use my function to configure navBar
    
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
        tableView.register(HeaderCell.self, forCellReuseIdentifier: headerId)
        tableView.backgroundColor = .yourPreferColor
        tableView.delegate = self
        tableView.dataSource = self
        tableView.separatorColor = UIColor(white: 1, alpha: 0.2)
        tableView.tableFooterView = UIView()
        tableView.translatesAutoresizingMaskIntoConstraints = false
        
        if #available(iOS 11.0, *) {
            tableView.contentInsetAdjustmentBehavior = .never
        } else {
            automaticallyAdjustsScrollViewInsets = false
        }
        
        if #available(iOS 15.0, *) {
            tableView.sectionHeaderTopPadding = 0
            tableView.sectionFooterHeight = 0
        } else {
            UITableView.appearance().sectionHeaderTopPadding = CGFloat(0)
            UITableView.appearance().sectionFooterHeight = CGFloat(0)
        }
        
        view.addSubview(tableView)
        tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    }
    

    现在为tableView委托和数据源创建一个扩展:

    extension NavBarAppearenceController: UITableViewDelegate, UITableViewDataSource {
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return 3
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 50 // header height
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        
        let headerView = UIView()
        let headerCell = tableView.dequeueReusableCell(withIdentifier: headerId) as! HeaderCell // header cell
        headerCell.translatesAutoresizingMaskIntoConstraints = false
        
        headerView.addSubview(headerCell)
        headerCell.topAnchor.constraint(equalTo: headerView.topAnchor).isActive = true
        headerCell.leadingAnchor.constraint(equalTo: headerView.leadingAnchor).isActive = true
        headerCell.trailingAnchor.constraint(equalTo: headerView.trailingAnchor).isActive = true
        headerCell.bottomAnchor.constraint(equalTo: headerView.bottomAnchor).isActive = true
    
        switch section {
        case 0:
            headerCell.label.text = "Meat"
        case 1:
            headerCell.label.text = "Fruit"
        default:
            headerCell.label.text = "Vegetables"
        }
        
        return headerView
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 60
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        switch section {
        case 0:
            return meat.count
        case 1:
            return fruit.count
        case 2:
            return vegetable.count
        default:
            return 0
        }
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
        
        let mySection = indexPath.section
        
        switch mySection {
        case 0:
            cell.textLabel?.text = "\(meat[indexPath.row])"
        case 1:
            cell.textLabel?.text = "\(fruit[indexPath.row])"
        default:
            cell.textLabel?.text = "\(vegetable[indexPath.row])"
        }
        cell.contentView.backgroundColor = .yourPreferColor
        cell.textLabel?.textColor = .white
        cell.selectionStyle = .none
        
        return cell
     }
    }
    

    创建自定义标题单元格:

    class HeaderCell: UITableViewCell {
    
    let myView: UIView = {
        let v = UIView()
        v.backgroundColor = .yourPreferColor
        v.translatesAutoresizingMaskIntoConstraints = false
        
        return v
    }()
    
    let label = UILabel()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        contentView.backgroundColor = .yourPreferColor
        
        label.textColor = .white
        label.font = .systemFont(ofSize: 20, weight: .bold)
        label.translatesAutoresizingMaskIntoConstraints = false
        
        contentView.addSubview(myView)
        myView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
        myView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20).isActive = true
        myView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
        myView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
        
        myView.addSubview(label)
        label.topAnchor.constraint(equalTo: myView.topAnchor).isActive = true
        label.leadingAnchor.constraint(equalTo: myView.leadingAnchor).isActive = true
        label.trailingAnchor.constraint(equalTo: myView.trailingAnchor).isActive = true
        label.bottomAnchor.constraint(equalTo: myView.bottomAnchor).isActive = true
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
     }
    }
    

    结果是:

    enter image description here

    奖金

    这是我的导航栏配置函数:

    func configureNavigationBar(largeTitleColor: UIColor, backgoundColor: UIColor, tintColor: UIColor, title: String, preferredLargeTitle: Bool) {
        
        if #available(iOS 13.0, *) {
            let navBarAppearance = UINavigationBarAppearance()
            navBarAppearance.configureWithOpaqueBackground()
            navBarAppearance.largeTitleTextAttributes = [.foregroundColor: largeTitleColor]
            navBarAppearance.titleTextAttributes = [.foregroundColor: largeTitleColor]
            navBarAppearance.backgroundColor = backgoundColor
            
            navigationController?.navigationBar.standardAppearance = navBarAppearance
            navigationController?.navigationBar.compactAppearance = navBarAppearance
            navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
            
            navigationController?.navigationBar.prefersLargeTitles = preferredLargeTitle
            navigationItem.largeTitleDisplayMode = .always
            navigationController?.navigationBar.tintColor = tintColor
            navigationItem.title = title
            
        } else {
            // Fallback on earlier versions
            navigationController?.navigationBar.barTintColor = backgoundColor
            navigationController?.navigationBar.tintColor = tintColor
            navigationController?.navigationBar.isTranslucent = false
            navigationItem.title = title
        }
    }