Swift 4导航栏按钮顺序不受系统语言影响的实现方案问询
解决导航栏按钮顺序不受语言切换影响的思路
核心问题
系统默认导航栏按钮(尤其是返回按钮)会跟随系统的语义布局(RTL/LTR)自动调整顺序,直接修改导航栏的semanticContentAttribute无法覆盖系统按钮的默认行为。
具体解决步骤
替换系统返回按钮为自定义按钮
系统自带的返回按钮会强制跟随语义翻转,所以自己创建一个自定义返回按钮,完全控制其位置和样式:// 创建自定义返回按钮 let backButton = UIButton(type: .custom) backButton.setImage(UIImage(named: "back_arrow"), for: .normal) backButton.addTarget(self, action: #selector(backAction), for: .touchUpInside) backButton.frame = CGRect(x: 0, y: 0, width: 44, height: 44) // 包装成UIBarButtonItem let backBarItem = UIBarButtonItem(customView: backButton)实现返回的点击事件:
@objc func backAction() { navigationController?.popViewController(animated: true) }用容器视图固定左侧按钮顺序
把返回按钮和电话按钮放到同一个UIView中,设置容器视图的语义为强制从左到右,再包装成UIBarButtonItem添加到导航栏:// 创建容器视图 let leftContainer = UIView(frame: CGRect(x: 0, y: 0, width: 88, height: 44)) // 添加返回按钮到容器左侧 leftContainer.addSubview(backButton) backButton.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ backButton.leadingAnchor.constraint(equalTo: leftContainer.leadingAnchor), backButton.centerYAnchor.constraint(equalTo: leftContainer.centerYAnchor), backButton.widthAnchor.constraint(equalToConstant: 44), backButton.heightAnchor.constraint(equalToConstant: 44) ]) // 创建电话按钮并添加到容器右侧 let phoneButton = UIButton(type: .custom) phoneButton.setImage(UIImage(named: "phone_icon"), for: .normal) phoneButton.addTarget(self, action: #selector(phoneAction), for: .touchUpInside) leftContainer.addSubview(phoneButton) phoneButton.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ phoneButton.leadingAnchor.constraint(equalTo: backButton.trailingAnchor), phoneButton.centerYAnchor.constraint(equalTo: leftContainer.centerYAnchor), phoneButton.widthAnchor.constraint(equalToConstant: 44), phoneButton.heightAnchor.constraint(equalToConstant: 44) ]) // 设置容器视图的语义为强制从左到右,避免跟随系统翻转 leftContainer.semanticContentAttribute = .forceLeftToRight // 将容器包装成UIBarButtonItem,设置到导航栏左侧 navigationItem.leftBarButtonItem = UIBarButtonItem(customView: leftContainer)单独设置每个按钮的语义属性
如果不想用容器视图,也可以给每个自定义的UIBarButtonItem单独设置语义:backBarItem.customView?.semanticContentAttribute = .forceLeftToRight let phoneBarItem = UIBarButtonItem(image: UIImage(named: "phone_icon"), style: .plain, target: self, action: #selector(phoneAction)) phoneBarItem.semanticContentAttribute = .forceLeftToRight // 按顺序添加到左侧按钮数组 navigationItem.leftBarButtonItems = [backBarItem, phoneBarItem]注意:必须确保所有按钮都是自定义的,系统自带的返回按钮无法通过这种方式修改顺序。
关键注意点
- 不要依赖系统默认的返回按钮,自定义返回按钮才能完全控制顺序。
- 容器视图或单个按钮的
semanticContentAttribute必须设置为.forceLeftToRight,覆盖系统的语义布局影响。 - 在
viewWillAppear中设置这些属性,确保每次视图出现时都能正确应用,避免语言切换后缓存的布局导致错乱。
内容的提问来源于stack exchange,提问作者waleed.makarem
相关产品推荐
相关产品推荐

