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

iOS问题:Xib自定义头部视图切换页面后向右移出屏幕

通用Xib头部视图返回页面后偏移问题

我用Xib实现了一个通用头部视图,正常显示状态:
正常显示的头部视图

当用户切换到下一个ViewController再返回原页面时,该视图会向右移出屏幕,异常状态:
偏移后的头部视图

我已为该视图设置Auto Layout,箭头图标右侧留有10pt边距,但不清楚为何会出现偏移。相关代码如下:

func setHeader(headerView : UIView, vc : UIViewController)
{
    vc1 = vc
    
   
    customView.removeFromSuperview()
    customView = UINib(nibName:"ViewHeader",bundle:.main).instantiate(withOwner: nil, options: nil).first as! HeaderView
    
    customView.btnNotification.setTitle("", for: .normal)
    customView.btnReward.setTitle("", for: .normal)
    customView.btnSideMenu.setTitle("", for: .normal)
    customView.viewUnread.layer.cornerRadius = customView.viewUnread.frame.size.width/2
    customView.viewUnread.clipsToBounds = true

    customView.btnSideMenu.addTarget(self, action: #selector(Commons.openDrawer(_:)), for: .touchUpInside)
    customView.lblPoints.text = String(Constants.CUSTOMERPOINTS)
    customView.btnReward.addTarget(self, action: #selector(Commons.openReward(_:)), for: .touchUpInside)
    customView.btnNotification.addTarget(self, action: #selector(Commons.openNotification(_:)), for: .touchUpInside)
    var w = String(format: "%f", Commons.screenWidth)
    var h = String(format: "%f", Commons.screenHeight)
    print("screenSize ye ha --> height: " + w + " - Width:" + h)
    if(Commons.screenHeight > 400 && Commons.screenHeight <= 750 )
    {
        customView.frame.size.height = 80.0
    }
    else if(Commons.screenHeight > 750 && Commons.screenHeight <= 850 )
    {
      //  customView.ic_centerMargin.constant = -20
        customView.frame.size.height = 80.0
    }
    else if(Commons.screenHeight > 850 && Commons.screenHeight <= 900 )
    {
        customView.frame.size.height = 80.0
    }
    else if (Commons.screenHeight > 900)
    {
        customView.frame.size.height = 80.0
    }
    let group = DispatchGroup()
       group.enter()

    Commons.getPoints()
    { [self] json, error in
               // will be called at either completion or at an error.
             
                           // will be called at either completion or at an error.
        DispatchQueue.main.async { [self] in
            customView.lblPoints.text = String(Constants.CUSTOMERPOINTS)

        }
        group.leave()
           }
       group.wait()
    headerView.addSubview(customView)
   // customView.center = vc1.view.center;
}

问题原因及解决办法

  • 手动修改frame与Auto Layout冲突
    代码里直接修改customView.frame.size.height,但视图已设置Auto Layout约束,手动改frame会破坏约束系统的布局逻辑,页面返回重新布局时就会出现偏移。
    解决:删除所有手动设置frame的代码,在Xib中给头部视图添加高度约束的IBOutlet(比如命名为headerHeightConstraint),通过修改约束的constant值调整高度:

    headerHeightConstraint.constant = 80.0
    
  • 未给customView添加父视图约束
    customView添加到headerView后,没有设置与父视图的约束,导致布局未被固定。
    解决:在headerView.addSubview(customView)后添加约束代码:

    customView.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        customView.topAnchor.constraint(equalTo: headerView.topAnchor),
        customView.leadingAnchor.constraint(equalTo: headerView.leadingAnchor),
        customView.trailingAnchor.constraint(equalTo: headerView.trailingAnchor),
        customView.bottomAnchor.constraint(equalTo: headerView.bottomAnchor)
    ])
    
  • DispatchGroup.wait()阻塞主线程
    group.wait()会阻塞当前线程,可能导致UI卡顿或布局时机异常。
    解决:移除DispatchGroup相关代码,直接在异步回调更新UI:

    Commons.getPoints() { [self] json, error in
        DispatchQueue.main.async {
            customView.lblPoints.text = String(Constants.CUSTOMERPOINTS)
        }
    }
    

内容的提问来源于stack exchange,提问作者Muhammad Umair

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:26:08