【问题标题】:Setting constraints to UITableView Footer Swft为 UITableView 页脚 Swft 设置约束
【发布时间】:2021-05-06 23:56:21
【问题描述】:

我正在尝试使用 UIButton 放置页脚,现在我只将它放置在框架中,当我在苹果的 iphone 上尝试它时,由于我没有设置任何自动 -布局,问题是我试图为页脚设置自动布局,但它总是失败,我不确定它是否可能这样做,很想得到一个方便的帮助,甚至是提示:)。 这是我的 tableView 代码:

import UIKit
import PanModal

protocol FilterTableViewDelegate {
    func didUpdateSelectedDate(_ date: Date)
}

class FilterTableViewController: UITableViewController, PanModalPresentable {
    
    var panScrollable: UIScrollView? {
        return tableView
    }
    
    
    var albumsPickerIndexPath: IndexPath? //  indexPath of the currently shown albums picker in tableview.
    var delegate: FilterTableViewDelegate?
    
    var datesCell = DatesCell()
    
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupTableView()
        //        registerTableViewCells()
        
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        //        tableView.frame = view.bounds
    }
    
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
    
    
    
    // MARK: - View Configurations
    
    func setupTableView() {
        
        
        tableView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true
        tableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
        tableView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true
        tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
        
        
        tableView.separatorStyle = .singleLine
        tableView.isScrollEnabled = false
        tableView.allowsSelection = true
        
        
        tableView.rowHeight = UITableView.automaticDimension
        tableView.estimatedRowHeight = 600
        
        
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        tableView.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
        
    }
    
    
    
    func indexPathToInsertDatePicker(indexPath: IndexPath) -> IndexPath {
        if let albumsPickerIndexPath = albumsPickerIndexPath, albumsPickerIndexPath.row < indexPath.row {
            return indexPath
        } else {
            return IndexPath(row: indexPath.row + 1, section: indexPath.section)
        }
    }
    
    
    // MARK: - UITableViewDataSource
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // If datePicker is already present, we add one extra cell for that
        if albumsPickerIndexPath != nil {
            return 5 + 1
        } else {
            return 5
        }
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        switch indexPath.row {
        case 0:
            
            let byActivityCell = UINib(nibName: "byActivityCell",bundle: nil)
            self.tableView.register(byActivityCell,forCellReuseIdentifier: "byActivityCell")
            let activityCell = tableView.dequeueReusableCell(withIdentifier: "byActivityCell", for: indexPath) as! byActivityCell
            activityCell.selectionStyle = .none
            
            return activityCell
            
        case 1:
            let byTypeCell = UINib(nibName: "ByType",bundle: nil)
            self.tableView.register(byTypeCell,forCellReuseIdentifier: "byTypeCell")
            let typeCell = tableView.dequeueReusableCell(withIdentifier: "byTypeCell", for: indexPath) as! ByType
            typeCell.selectionStyle = .none
            return typeCell
            
        case 2:
            let byHashtagsCell = UINib(nibName: "ByHashtags",bundle: nil)
            self.tableView.register(byHashtagsCell,forCellReuseIdentifier: "byHashtagsCell")
            let hashtagsCell = tableView.dequeueReusableCell(withIdentifier: "byHashtagsCell", for: indexPath) as! ByHashtags
            hashtagsCell.selectionStyle = .none
            
            return hashtagsCell
            
        case 3:
            let byDatesCell = UINib(nibName: "DatesCell",bundle: nil)
            self.tableView.register(byDatesCell,forCellReuseIdentifier: "byDatesCell")
            let datesCell = tableView.dequeueReusableCell(withIdentifier: "byDatesCell", for: indexPath) as! DatesCell
            datesCell.selectionStyle = .none
            datesCell.datesTableViewCellDelegate = self
            
            return datesCell
            
            
        case 4:
            let byAlbumCell = UINib(nibName: "AlbumCell",bundle: nil)
            self.tableView.register(byAlbumCell,forCellReuseIdentifier: "byAlbumCell")
            let albumCell = tableView.dequeueReusableCell(withIdentifier: "byAlbumCell", for: indexPath) as! AlbumCell
            albumCell.configureCell(choosenAlbum: "Any")
            albumCell.selectionStyle = .none
            
            return albumCell
            
            
            
        case 5:
            let albumPickerCell = UINib(nibName: "AlbumsPickerTableViewCell", bundle: nil)
            self.tableView.register(albumPickerCell, forCellReuseIdentifier: "albumPickerCell")
            let albumsPicker = tableView.dequeueReusableCell(withIdentifier: "albumPickerCell", for: indexPath) as! AlbumsPickerTableViewCell
            
            
            return albumsPicker
            
            
        default:
            return UITableViewCell()
        }
        
    }
    
    
    
    
    
    // MARK: - footer Methods:
    override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return getfooterView()
    }
    
    func getfooterView() -> UIView
    {
        let footerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 400))
        let applyFiltersBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 380, height: 40))
        
        
        applyFiltersBtn.center = footerView.center
        
        applyFiltersBtn.layer.cornerRadius = 12
        applyFiltersBtn.layer.masksToBounds = true
        applyFiltersBtn.setTitle("Apply Filters", for: .normal)
        applyFiltersBtn.backgroundColor = #colorLiteral(red: 0.1957295239, green: 0.6059523225, blue: 0.960457623, alpha: 1)
        
        
        //        doneButton.addTarget(self, action: #selector(hello(sender:)), for: .touchUpInside)
        
        
        
        footerView.addSubview(applyFiltersBtn)
        
        
        return footerView
    }
    
    override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 10
    }
    
    
    
    
    
    
    // MARK: TableViewDelegate Methods:
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: false)
        
        
        tableView.beginUpdates()
        
        // 1 - We Delete the UIPicker when the user "Deselect" thr row.
        if let datePickerIndexPath = albumsPickerIndexPath,   datePickerIndexPath.row - 1 == indexPath.row {
            tableView.deleteRows(at: [datePickerIndexPath], with: .fade)
            self.albumsPickerIndexPath = nil
        } else {
            // 2
            //            if let datePickerIndexPath = albumsPickerIndexPath {
            //                tableView.deleteRows(at: [datePickerIndexPath], with: .fade)
            //            }
            albumsPickerIndexPath = indexPathToInsertDatePicker(indexPath: indexPath)
            tableView.insertRows(at: [albumsPickerIndexPath!], with: .fade)
            tableView.deselectRow(at: indexPath, animated: true)
        }
        
        
        
        tableView.endUpdates()
        
    }
    
    
    override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
        if indexPath.row == 4  {
            return indexPath
        } else {
            return nil
        }
        
        
    }
    
    
}


extension FilterTableViewController: DatesTableViewCellDelegate {
    
    func didButtonFromPressed() {
        print("Button From is Pressed")
        let pickerController = CalendarPickerViewController(
            baseDate: Date(),
            selectedDateChanged: { [weak self] date in
                guard let self = self else { return }
                
                //          self.item.date = date
                //TODO: Pass the date to the DatesCell to update the UIButtons.
                self.delegate?.didUpdateSelectedDate(date)
                
                self.tableView.reloadRows(at: [IndexPath(row: 3, section: 0)], with: .fade)
            })
        
        present(pickerController, animated: true, completion: nil)
        
    }
    
    
    
    func didButtonToPressed() {
        //TODO: Present our custom calendar
        let calendarController = CalendarPickerViewController(
            baseDate: Date(),
            selectedDateChanged: { [weak self] date in
                guard let self = self else { return }
                
                self.tableView.reloadRows(at: [IndexPath(row: 3, section: 0)], with: .fade)
            })
        
        
        
        self.present(calendarController, animated: true, completion: nil)
        
    }
    
    
}

【问题讨论】:

  • 您正在创建框架高度为400 的footerView?这是您想要的每个部分页脚的高度吗?或者,您希望按钮高度为40,顶部和底部留出一点空间?
  • 而且...这应该是 Table 页脚吗?还是每个部分的页脚?
  • @DonMag 我将 UIButton 的高度设置为 400,但问题是页脚不是自动布局,当我在 iphone pro 上试用时(我在 iphone11 上工作)然后按钮向下:\它应该是一个部分的表格页脚 - 只是作为底部带有 uibutton 的页脚

标签: ios swift uitableview autolayout


【解决方案1】:

首先,提示(基于您发布的这个问题和其他问题):简化您正在做的事情。当您发布引用 5 个不同单元格类的代码以及用于处理单元格操作委托、插入和删除等的代码时...但是您的问题是关于节页脚布局的,它很难得到帮助。

所以,这里有一个简单的表格视图控制器的示例,它使用默认单元格类,并为部分页脚自定义UITableViewHeaderFooterView:

class MySectionFooterView: UITableViewHeaderFooterView {
    
    let applyFiltersBtn = UIButton()
    
    override init(reuseIdentifier: String?) {
        super.init(reuseIdentifier: reuseIdentifier)
        configureContents()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        configureContents()
    }
    
    func configureContents() {

        applyFiltersBtn.translatesAutoresizingMaskIntoConstraints = false
        applyFiltersBtn.layer.cornerRadius = 12
        applyFiltersBtn.layer.masksToBounds = true
        applyFiltersBtn.setTitle("Apply Filters", for: .normal)
        applyFiltersBtn.backgroundColor = #colorLiteral(red: 0.1957295239, green: 0.6059523225, blue: 0.960457623, alpha: 1)

        contentView.addSubview(applyFiltersBtn)

        let g = contentView.layoutMarginsGuide
        
        NSLayoutConstraint.activate([

            // use layoutMarginsGuide for top and bottom
            applyFiltersBtn.topAnchor.constraint(equalTo: g.topAnchor, constant: 0.0),
            applyFiltersBtn.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0),
            
            // inset button 20-pts from layoutMarginsGuide on each side
            applyFiltersBtn.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
            applyFiltersBtn.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
            
            // make button height 40-pts
            applyFiltersBtn.heightAnchor.constraint(equalToConstant: 40.0),
        ])
        
    }
}

class SectionFooterViewController: UITableViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // register cell class for reuse
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        
        // register Section Footer class for reuse
        tableView.register(MySectionFooterView.self, forHeaderFooterViewReuseIdentifier: "mySectionFooter")

        tableView.sectionFooterHeight = UITableView.automaticDimension
        tableView.estimatedSectionFooterHeight = 50
    }
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 8
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = "\(indexPath)"
        return cell
    }

    override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        let view = tableView.dequeueReusableHeaderFooterView(withIdentifier:"mySectionFooter") as! MySectionFooterView
        return view
    }
}

要处理点击部分页脚中的按钮,您可以在viewForFooterInSection 中为其分配一个动作,或者将该动作构建到MySectionFooterView 类中并使用闭包或协议/委托模式。

【讨论】:

  • 知道了 :) 会尝试一下,很抱歉下次我会更清楚?
  • 我试过你的代码,但问题是页脚不在底部:\
  • 这就是为什么我问...你希望它是 section 页脚还是 table 页脚,你说的是“section”。你想把它放在表格视图的底部吗?
  • “我只想让tableView的页脚在底部” ...在什么的底部?在最后一行的底部?在视图框架的底部?在最后一行的底部,除非有足够的行将“页脚”推到视图框架的底部?请参阅:imgur.com/a/v1A4Il2 了解差异。如果您希望“页脚”位于 视图框架 的底部,即使只有几行,您也需要将页脚添加为表格子视图或将其移出表格视图本身。
  • 好的 - 你几乎肯定想更改为标准的UIViewController,其中包含一个 tableView 和你的 view-with-button 作为子视图。为了将来节省大量时间和精力,您可能需要查看 Stack Overflow 的How to Ask。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多