iOS 11中横屏模式下RightBarButton位置下移问题咨询
Hey there, sorry to hear you're dealing with this annoying right bar button position issue when rotating your iOS device to landscape—nothing breaks the UI flow quite like misaligned controls! Let’s walk through the most common causes and actionable fixes to get this sorted out quickly.
1. Double-Check Your Layout Constraints (For Custom Bar Buttons)
If you’re using a custom UIView or UIButton wrapped in a UIBarButtonItem, misaligned constraints are the #1 culprit here.
- Avoid fixed vertical offsets (like a hardcoded bottom margin) that don’t adapt to navigation bar height changes (some iOS versions have shorter landscape nav bars).
- Instead, pin your custom view’s top and bottom edges to the navigation bar’s edges, or set its vertical center to match the nav bar’s center. For example, in code:
let customButton = UIButton(type: .system) // ... configure button content ... let barButton = UIBarButtonItem(customView: customButton) // Add constraints to keep the button vertically centered customButton.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ customButton.centerYAnchor.constraint(equalTo: self.navigationController!.navigationBar.centerYAnchor), customButton.widthAnchor.constraint(equalToConstant: 44), customButton.heightAnchor.constraint(equalToConstant: 44) ]) - If you’re using Storyboards/XIBs, ensure your custom button’s vertical constraints are set to center vertically relative to the navigation bar, not fixed to the bottom.
2. Fix Custom Button Content & Autoresizing
Even with correct constraints, your button’s internal content might be causing the shift:
- Set your button’s
contentVerticalAlignmentto.centerto keep text/images aligned properly:customButton.contentVerticalAlignment = .center - For image-based buttons, set the image’s
contentModeto.scaleAspectFitor.centerso it doesn’t stretch or push the button’s bounds downward. - Add autoresizing masks to let the button adapt to nav bar size changes:
customButton.autoresizingMask = [.flexibleTopMargin, .flexibleBottomMargin]
3. Check Navigation Bar & Bar Button Configuration
Sometimes the issue stems from navigation bar settings or bar button adjustments:
- Verify you haven’t accidentally set a vertical
positionAdjustmenton the bar button item. This is an easy mistake! Check for code like this and remove it (or adjust it dynamically):// Remove this if it's causing landscape shift navigationItem.rightBarButtonItem?.positionAdjustment = UIOffset(horizontal: 0, vertical: 8) - Toggle the navigation bar’s
translucentproperty if you haven’t already—translucent nav bars have slightly different layout insets that can affect button positioning. Try settingnavigationController?.navigationBar.isTranslucent = false(or true, depending on your current setting) to see if it fixes the shift.
4. Dynamic Adjustment On Rotation
If the above fixes don’t work, you can explicitly adjust the button’s position when the device rotates:
- Register for orientation change notifications and update the button’s position accordingly:
override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(handleOrientationChange), name: UIDevice.orientationDidChangeNotification, object: nil) } @objc private func handleOrientationChange() { let isLandscape = UIDevice.current.orientation.isLandscape // Adjust position only if needed—tweak the vertical offset as required navigationItem.rightBarButtonItem?.positionAdjustment = isLandscape ? .zero : .zero } deinit { NotificationCenter.default.removeObserver(self) }
5. Custom Navigation Bar Layout Issues
If you’re using a subclassed UINavigationBar, make sure your layoutSubviews method isn’t messing with bar button positioning:
- Always call
super.layoutSubviews()first, then ensure bar button containers are vertically centered. For example:override func layoutSubviews() { super.layoutSubviews() // Locate the right bar button stack view and center it vertically if let contentView = subviews.first(where: { $0.classForCoder.description() == "_UINavigationBarContentView" }), let rightButtonStack = contentView.subviews.first(where: { $0.classForCoder.description() == "_UIButtonBarStackView" }) { rightButtonStack.centerY = self.centerY } }
Start with the constraint and content alignment checks first—those usually resolve this issue quickly. If you’re still stuck, try isolating the problem by testing with a default UIBarButtonItem (no custom view) to see if the shift persists, which will help narrow down if the issue is with your custom view or the navigation bar itself.
内容的提问来源于stack exchange,提问作者Jerome Dreyer

