Swift 4:如何根据选中选项让视图控制器加载不同UIView
用单个视图控制器加载不同自定义UIView的解决方案
看起来你已经搞定了菜单跳转和导航栏标题的部分,接下来只需要让selectionController根据选中的菜单选项加载对应的UIView就行,我给你两种可行的实现方式,按需选择:
方式一:用枚举匹配(类型安全,推荐)
首先把你的MenuOption改成枚举,这样能避免字符串拼写错误,扩展性也更好:
// 定义菜单选项枚举,对应你所有的视图选项 enum MenuOption: String, CaseIterable { case settings = "Settings" case profile = "Profile" case notifications = "Notifications" // 继续添加其他15+选项... }
然后创建每个选项对应的自定义UIView,比如SettingsView:
class SettingsView: UIView { override init(frame: CGRect) { super.init(frame: frame) // 这里写Settings视图的布局和逻辑 backgroundColor = .white let titleLabel = UILabel() titleLabel.text = "Settings Page" titleLabel.font = UIFont.systemFont(ofSize: 24, weight: .bold) titleLabel.translatesAutoresizingMaskIntoConstraints = false addSubview(titleLabel) // AutoLayout约束,让标题居中 NSLayoutConstraint.activate([ titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor), titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor) ]) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
接下来修改HomeController里的displayController方法,根据枚举值加载对应的View:
func displayController(menuOption: MenuOption) { let selectionController = UIViewController() selectionController.navigationItem.title = menuOption.rawValue selectionController.view.backgroundColor = .blue // 根据菜单选项创建对应的自定义View var contentView: UIView! switch menuOption { case .settings: contentView = SettingsView() case .profile: contentView = ProfileView() // 对应你的Profile视图 case .notifications: contentView = NotificationsView() // 对应你的通知视图 // 依次添加其他选项的匹配逻辑 } // 将自定义View铺满selectionController的视图 contentView.translatesAutoresizingMaskIntoConstraints = false selectionController.view.addSubview(contentView) NSLayoutConstraint.activate([ contentView.topAnchor.constraint(equalTo: selectionController.view.topAnchor), contentView.leadingAnchor.constraint(equalTo: selectionController.view.leadingAnchor), contentView.trailingAnchor.constraint(equalTo: selectionController.view.trailingAnchor), contentView.bottomAnchor.constraint(equalTo: selectionController.view.bottomAnchor) ]) navigationController?.navigationBar.tintColor = .white navigationController?.pushViewController(selectionController, animated: true) }
方式二:给MenuOption绑定View类型(更简洁,扩展性强)
如果不想写长长的switch语句,可以给你的MenuOption结构体添加一个viewType属性,直接绑定对应的View类型:
struct MenuOption { let name: String let viewType: UIView.Type // 存储对应的View类型 } // 初始化你的菜单选项数组时,直接绑定View let menuOptions = [ MenuOption(name: "Settings", viewType: SettingsView.self), MenuOption(name: "Profile", viewType: ProfileView.self), MenuOption(name: "Notifications", viewType: NotificationsView.self), // 其他选项... ]
然后修改displayController方法,直接通过viewType实例化View:
func displayController(menuOption: MenuOption) { let selectionController = UIViewController() selectionController.navigationItem.title = menuOption.name selectionController.view.backgroundColor = .blue // 直接实例化对应的View let contentView = menuOption.viewType.init(frame: selectionController.view.bounds) // 设置autoresizingMask让View自动适配控制器视图尺寸 contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight] selectionController.view.addSubview(contentView) navigationController?.navigationBar.tintColor = .white navigationController?.pushViewController(selectionController, animated: true) }
注意事项
- 每个自定义
UIView要自己处理内部的布局和交互逻辑,比如按钮点击、表单输入等,这样代码职责更清晰 - 如果需要和
selectionController通信(比如View里的操作需要更新导航栏),可以通过代理模式或者闭包实现 - 确保自定义View的布局适配不同屏幕尺寸,推荐用AutoLayout而不是固定frame
内容的提问来源于stack exchange,提问作者Chandler Long
相关产品推荐
相关产品推荐

