首次加载正常,返回Segue后导航栏与图片重叠问题求助
解决导航栏Logo返回Segue后重叠的问题
这个问题我之前也碰到过!本质是导航栏的Logo视图被重复添加了——第一次加载视图时正常,但从Segue返回后,你的代码又把新的Logo容器加到了导航栏上,旧的实例没被移除,最终导致多层重叠。下面给你几个靠谱的解决思路:
方案1:确保Logo只初始化一次(推荐)
把Logo相关的视图改成控制器的实例属性,避免每次视图出现时重复创建,同时添加前检查是否已经存在:
class YourViewController: UIViewController { // 把视图变量提升为实例属性,只初始化一次 private let logoContainer = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 67)) private let imageView = UIImageView(frame: CGRect(x: 0, y: -30, width: 200, height: 67)) override func viewDidLoad() { super.viewDidLoad() setupNavbarLogo() } private func setupNavbarLogo() { // 检查导航栏标题视图是否已存在,避免重复添加 guard navigationItem.titleView == nil else { return } imageView.contentMode = .scaleAspectFit imageView.image = UIImage(named: "navbarlogo") logoContainer.addSubview(imageView) navigationItem.titleView = logoContainer } }
方案2:添加前清空旧的标题视图
如果不想用实例属性,可以在每次设置Logo前,先清空导航栏的titleView,确保只有最新的视图存在:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 先移除旧的标题视图 navigationItem.titleView = nil let logoContainer = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 67)) let imageView = UIImageView(frame: CGRect(x: 0, y: -30, width: 200, height: 67)) imageView.contentMode = .scaleAspectFit imageView.image = UIImage(named: "navbarlogo") logoContainer.addSubview(imageView) navigationItem.titleView = logoContainer }
额外优化:用AutoLayout替代Frame布局
你当前用Frame设置位置,容易在不同设备上出现适配问题,建议换成AutoLayout,同时也能避免一些奇怪的偏移:
private func setupNavbarLogo() { guard navigationItem.titleView == nil else { return } let logoContainer = UIView() logoContainer.translatesAutoresizingMaskIntoConstraints = false let imageView = UIImageView(image: UIImage(named: "navbarlogo")) imageView.contentMode = .scaleAspectFit imageView.translatesAutoresizingMaskIntoConstraints = false logoContainer.addSubview(imageView) // 用约束精确控制位置和大小 NSLayoutConstraint.activate([ imageView.widthAnchor.constraint(equalToConstant: 200), imageView.heightAnchor.constraint(equalToConstant: 67), imageView.centerYAnchor.constraint(equalTo: logoContainer.centerYAnchor, constant: -30), imageView.leadingAnchor.constraint(equalTo: logoContainer.leadingAnchor), imageView.trailingAnchor.constraint(equalTo: logoContainer.trailingAnchor), logoContainer.widthAnchor.constraint(equalToConstant: 200), logoContainer.heightAnchor.constraint(equalToConstant: 67) ]) navigationItem.titleView = logoContainer }
问题根源补充
之所以返回后出现重叠,大概率是你把Logo设置代码放在了viewWillAppear这类每次视图显示都会执行的方法里,而不是只执行一次的viewDidLoad。如果必须在viewWillAppear里设置,就一定要做“去重”处理,要么提前判断,要么先清空旧视图。
内容的提问来源于stack exchange,提问作者Utku Dalmaz
相关产品推荐
相关产品推荐

