Swift使用SideMenu时如何在侧边栏底部添加固定不滚动的退出按钮
实现侧边菜单固定底部Sign-out按钮的方案
现有UITableViewController的tableFooterView默认跟随列表滚动,要实现固定不滚动的底部退出按钮,可选择以下两种实现方式:
方案1:将MenuListController改为普通UIViewController(推荐)
把原本UITableViewController的结构改成普通UIViewController,内部手动添加tableView和固定在底部的sign-out按钮,从根本上避免tableView覆盖整个视图导致按钮无法固定的问题。
修改后代码:
import UIKit import SideMenu // 替换原有MenuListController实现 class MenuListController: UIViewController { var menuItems = [[String: String]]() // 手动添加列表视图 private let tableView = UITableView() // 底部固定退出按钮 private let signOutButton = UIButton() override func viewDidLoad() { super.viewDidLoad() setupBaseUI() setupTableView() setupSignOutButton() // 原有菜单项初始化逻辑不变 menuItems.append(["name": "隐私设置", "img": "privacy", "key" : "privacy"]) menuItems.append(["name": "反馈问题", "img": "report_issue", "key": "report_issue"]) } private func setupBaseUI() { view.backgroundColor = .white // 列表和按钮都添加到根视图 [tableView, signOutButton].forEach { $0.translatesAutoresizingMaskIntoConstraints = false view.addSubview($0) } } private func setupTableView() { tableView.dataSource = self tableView.delegate = self tableView.separatorStyle = .none tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") // 列表约束:顶部到导航栏底部,底部到退出按钮顶部 NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), tableView.bottomAnchor.constraint(equalTo: signOutButton.topAnchor, constant: -16) ]) } private func setupSignOutButton() { signOutButton.setTitle("退出登录", for: .normal) let color = UIColor.init(hexString: "#1A73E9") signOutButton.setTitleColor(color, for: .normal) signOutButton.addTarget(self, action: #selector(signOutButtonTapped), for: .touchUpInside) // 按钮约束:固定在底部安全区 NSLayoutConstraint.activate([ signOutButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), signOutButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20), signOutButton.heightAnchor.constraint(equalToConstant: 40) ]) } @objc func signOutButtonTapped(_ sender: AnyObject?) { print("触发退出登录逻辑") } } extension MenuListController: UITableViewDataSource, UITableViewDelegate { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { menuItems.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) if menuItems.indices.contains(indexPath.row) { let dict = menuItems[indexPath.row] cell.textLabel?.text = dict["name"] if let img = dict["img"] { cell.imageView?.image = UIImage(named: img) } } return cell } }
方案2:不修改MenuListController继承关系,直接将按钮添加到侧边栏容器视图
如果你不想改动现有MenuListController的UITableViewController继承结构,可以在配置侧边菜单的时候,直接把退出按钮加到SideMenuNavigationController的根视图上,同时给tableView加底部内边距避免列表内容被按钮遮挡。
修改configureSideMenu方法代码:
func configureSideMenu() { let menuListVC = MenuListController() menu = SideMenuNavigationController(rootViewController: menuListVC) guard let menu = menu else { return } // 原有导航栏配置逻辑保持不变 menu.navigationBar.setBackgroundImage(UIImage(named: "top_navbrBG"), for: .default) let firstFrame = CGRect(x: 20, y: 0, width: menu.navigationBar.frame.width ?? 0/2, height: menu.navigationBar.frame.height ?? 0) let firstLabel = UILabel(frame: firstFrame) firstLabel.text = "设置" menu.navigationBar.addSubview(firstLabel) SideMenuManager.default.addPanGestureToPresent(toView: self.view) let screenSize = UIScreen.main.bounds let screenHeight = screenSize.height + 40 let leftBorderView = UIView(frame: CGRect(x: 1, y: -40, width: 1, height: screenHeight)) leftBorderView.backgroundColor = UIColor.init(hexString: "#cfcfcf") menu.navigationBar.addSubview(leftBorderView) // 新增:添加固定底部的退出按钮 let signOutBtn = getSignOutButton() signOutBtn.translatesAutoresizingMaskIntoConstraints = false menu.view.addSubview(signOutBtn) NSLayoutConstraint.activate([ signOutBtn.leadingAnchor.constraint(equalTo: menu.view.leadingAnchor, constant: 20), signOutBtn.bottomAnchor.constraint(equalTo: menu.view.safeAreaLayoutGuide.bottomAnchor, constant: -20), signOutBtn.heightAnchor.constraint(equalToConstant: 40) ]) // 给列表加底部内边距,避免滚动到最下方时内容被按钮遮挡 menuListVC.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 70, right: 0) // 注意:需要删除原有MenuListController里的`tableView.tableFooterView = getSignOutButton()`代码,避免重复添加按钮 }
内容的提问来源于stack exchange,提问作者user10469417
相关产品推荐
相关产品推荐

