You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS开发:根据用户登录状态切换菜单内容求助

解决根据登录状态动态切换菜单的问题

你的问题核心在于settings数组是静态初始化的——它只在SettingLauncher对象创建时计算一次,之后哪怕登录状态改变,这个数组也不会自动更新。要实现菜单随登录状态动态切换,我们需要让菜单选项每次显示时都根据当前登录状态重新生成。

解决方案步骤:

1. 将settings改为计算属性

把原来的常量数组改成计算属性,这样每次访问settings时都会重新读取Keychain的登录状态并生成对应菜单:

// 替换原来的let settings: [Setting] = { ... }()
var settings : [Setting] {
    let isLoggedIn = KeychainWrapper.standard.string(forKey: "myKey") == "true"
    
    // 定义所有可能的菜单选项
    let settingOne = Setting(name: .Profile, imageName: "profile-icon")
    let settingTwo = Setting(name: .Login, imageName: "login-icon")
    let settingThree = Setting(name: .Orders, imageName: "orders-icon")
    let settingFour = Setting(name: .Category, imageName: "category-icon")
    let settingSix = Setting(name: .SignOut, imageName: "login-icon")
    
    // 根据登录状态返回对应菜单
    if isLoggedIn {
        return [settingOne, settingThree, settingFour, settingSix]
    } else {
        return [settingTwo, settingThree, settingFour]
    }
}

2. 修正showHambuger方法,确保显示最新菜单

在显示菜单前先刷新CollectionView的数据,保证展示的是最新的选项:

func showHambuger(){
    guard let window = UIApplication.shared.keyWindow else { return }
    
    blackView.backgroundColor = UIColor(white: 0, alpha: 0.5)
    blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleCancel)))
    
    // 先刷新CollectionView数据,确保菜单是最新的
    collectionView.reloadData()
    
    window.addSubview(blackView)
    window.addSubview(collectionView)
    
    let height = CGFloat(settings.count) * cellHeight
    let y = window.frame.height - height
    
    collectionView.frame = CGRect(x: 0, y: window.frame.height, width: window.frame.width, height: height)
    blackView.frame = window.frame
    blackView.alpha = 0
    
    UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut) {
        self.blackView.alpha = 1
        self.collectionView.frame = CGRect(x: 0, y: y, width: self.collectionView.frame.width, height: self.collectionView.frame.height)
    }
}

3. 修复handleCancel的参数问题

原来的handleCancel方法参数在手势触发时会报错(手势不会传递Setting参数),我们拆分方法处理两种场景:

// 处理黑色区域点击(无Setting参数)
@objc func handleCancel() {
    animateMenuDismissal()
}

// 处理菜单选项点击(带Setting参数)
private func handleCancelWithSetting(_ setting: Setting) {
    animateMenuDismissal { completed in
        if setting.name != .Cancel {
            self.defaultController?.showControllerForSetting(setting: setting)
        }
    }
}

// 提取动画逻辑为公共方法
private func animateMenuDismissal(completion: ((Bool) -> Void)? = nil) {
    UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut) {
        self.blackView.alpha = 0
        if let window = UIApplication.shared.keyWindow {
            self.collectionView.frame = CGRect(x: 0, y: window.frame.height, width: self.collectionView.frame.width, height: self.collectionView.frame.height)
        }
    } completion: { completed in
        completion?(completed)
    }
}

// 更新didSelectItemAt方法
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let setting = settings[indexPath.item]
    handleCancelWithSetting(setting)
}

4. 确保登录/登出操作更新Keychain

在你的登录/登出逻辑中,确保成功后正确修改Keychain的值:

// 登录成功时
KeychainWrapper.standard.set("true", forKey: "myKey")

// 登出成功时
KeychainWrapper.standard.removeObject(forKey: "myKey")
// 或者设置为"false",根据你的判断逻辑调整

这样修改后,每次点击汉堡按钮显示菜单时,都会重新读取当前登录状态并生成对应的菜单选项,完美实现动态切换的效果。

内容的提问来源于stack exchange,提问作者Kaveh Naseri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:46:28