Self.frame 与设备尺寸不匹配

Self.frame does not match device dimensions

我正在尝试获取我的组件相对于设备的大小,但它忽略了实际大小并考虑了 xib 的“占位符”

这很有趣,因为我有两个具有相同组件的屏幕,一个 xib 的外观设置类似于 iPhone 11,另一个 iPhone SE(2s 代),当我 运行 项目时,布局计算和 self.frame 的值是不同的,即使两个屏幕具有相同的相同组件和相同的配置

Important I'm not using auto layout inside xib

It is not possible to use UIScreen in this case as we have other examples where the component is not centered on the screen.

private func drawPosition() {
    searchView.addSubview(searchIcon)
    searchView.backgroundColor = .red
    searchIcon.backgroundColor = .yellow
    
    let widht = self.frame.size.width - 12
    widthLeftView = widht / 2
    
    widthConstraint = searchView.widthAnchor.constraint(equalToConstant: widthLeftView)

    NSLayoutConstraint.activate([
        searchView.heightAnchor.constraint(equalToConstant: searchViewSize),
        widthConstraint,
        searchIcon.heightAnchor.constraint(equalToConstant: searchIconSize),
        searchIcon.widthAnchor.constraint(equalToConstant: searchIconSize),
        searchIcon.centerYAnchor.constraint(equalTo: searchView.centerYAnchor),
        searchIcon.trailingAnchor.constraint(
            equalTo: searchView.trailingAnchor,
            constant: 0)
    ])
    searchBarTextField.leftView = searchView
    searchBarTextField.leftViewMode = .always
}

我尝试在控制器中设置 didLayoutSubViews 但没有任何改变

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    
    self.searchBar.setNeedsLayout()
    self.searchBar.layoutIfNeeded()
}

xib:

我觉得如何:

要么添加一个超级视图来嵌入您的 searchView 和 searchIcon。 这是一个占位符视图,您可以将其约束设置为其父视图的一半(您对 self.frame.width 所做的)。
这样就不用再计算“-12”了。
只需让图标位于右侧,然后不设置 searchView 的宽度,而是将其前导设置为该占位符,将尾随设置为图标。

另一种方法是保留对宽度约束的引用:

var searchViewWidthConstraint: NSLayoutConstraint

并覆盖 layoutSubviews()(如果您在 UIView 中)或 viewDidLayoutSubviews(如果您在 (UIViewController) 中:

override func layoutSubviews() {
    super.layoutSubviews()
    searchViewWidthConstraint.constant = self.frame.width - 12
}

调用viewDidLoad()时,不同视图的框架是在InterfaceBuilder中看到的框架。然后,约束为 applied/calculated(并在每次需要时再次调用),并且框架会适应。这就是为什么 self.frame 还不正确