使用导航栏注意事项获取屏幕中心
Get the center of screen with Navigation Bar considerations
我正在尝试将 UIActivityIndicator 居中并在我的应用程序中重复使用它。我面临一个问题,我的某些视图必须位于导航栏下方,而另一些则不是。这恰好使我的 activity 指示器在视图不在导航栏下方的视图上显示低于中心。例如:
Whosebug 上的所有答案似乎都属于图片 #2。
我只是对 UIView 进行了扩展,通过将 activity 指示器添加为子视图覆盖来显示和隐藏它。检查 Whosebug 上的多个帖子,我没有发现任何可以重复这个问题的内容。
我的问题是,在生产应用程序中,如何在仅使用一个功能的情况下成功地将此视图居中,但仍支持 IOS 版本回到 9.3
你可以得到屏幕高度+顶部和底部
var height: CGFloat {
let heightTop = UIApplication.shared.statusBarFrame.height + (
(self.navigationController?.navigationBar.intrinsicContentSize.height) ?? 0)
let heightBottom = self.tabBarController?.tabBar.frame.height ?? 0
return UIScreen.main.bounds.height + (heightTop+heightBottom)
}
// 然后
indicator.center = CGPoint(x: self.view.frame.width/2.0, y: height/2.0 )
你可以使用safeAreaLayoutGuide
它给你可见屏幕的区域
let indicator: UIActivityIndicatorView = {
let indicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
indicator.translatesAutoresizingMaskIntoConstraints = false
return indicator
}()
self.view.addSubview(indicator)
let safeAreaGuide = self.view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
indicator.centerXAnchor.constraint(equalTo: saveAreaGuide.centerXAnchor),
indicator.centerYAnchor.constraint(equalTo: saveAreaGuide.centerYAnchor)
])
你可以使用这个:
func setActivityIndicatorTo(view: UIView, indicator: UIActivityIndicatorView){
indicator.setTranslatesAutoresizingMaskIntoConstraints(false)
view.addConstraint(NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))
}
Or you can found center of screen below:
let w = UIScreen.main.bounds.width
let h = UIScreen.main.bounds.height
activity.center = CGPoint(x: w / 2, y: h / 2)
SWIFT 3:
Extension 将子视图置于您 App delegate 的 keyWindow 中...使其居中,无论它在您的应用程序中的什么位置:
extension UIView {
public func addSubviewScreenCenter() {
if let keyWindow = UIApplication.shared.keyWindow {
keyWindow.addSubview(self)
self.center()
}
}
public func removeFromWindowView() {
if self.superview != nil {
self.removeFromSuperview()
}
}
}
UIView
上有在不同视图坐标系之间转换点和框架的方法(iOS 2.0+、https://developer.apple.com/documentation/uikit/uiview/1622424-convert 支持)。
extension UIView {
func centerInContainingWindow() {
guard let window = self.window else { return }
let windowCenter = CGPoint(x: window.frame.midX, y: window.frame.midY)
self.center = self.superview.convert(windowCenter, from: nil)
}
}
A UIView
指定其相对于其父视图的坐标,因此 centerInContainingWindow()
使用 UIView.convert(_:from:)
获取相对于其父视图坐标的 window 的中心。
- 图#1,导航栏下视图:视图占满整个window,所以转换前后中心点相同
- 图#2,视图不在导航栏下:视图只填充了window的一部分,因此转换后window中心将移动到屏幕上的同一位置。
我正在尝试将 UIActivityIndicator 居中并在我的应用程序中重复使用它。我面临一个问题,我的某些视图必须位于导航栏下方,而另一些则不是。这恰好使我的 activity 指示器在视图不在导航栏下方的视图上显示低于中心。例如:
Whosebug 上的所有答案似乎都属于图片 #2。
我只是对 UIView 进行了扩展,通过将 activity 指示器添加为子视图覆盖来显示和隐藏它。检查 Whosebug 上的多个帖子,我没有发现任何可以重复这个问题的内容。
我的问题是,在生产应用程序中,如何在仅使用一个功能的情况下成功地将此视图居中,但仍支持 IOS 版本回到 9.3
你可以得到屏幕高度+顶部和底部
var height: CGFloat {
let heightTop = UIApplication.shared.statusBarFrame.height + (
(self.navigationController?.navigationBar.intrinsicContentSize.height) ?? 0)
let heightBottom = self.tabBarController?.tabBar.frame.height ?? 0
return UIScreen.main.bounds.height + (heightTop+heightBottom)
}
// 然后
indicator.center = CGPoint(x: self.view.frame.width/2.0, y: height/2.0 )
你可以使用safeAreaLayoutGuide
它给你可见屏幕的区域
let indicator: UIActivityIndicatorView = {
let indicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
indicator.translatesAutoresizingMaskIntoConstraints = false
return indicator
}()
self.view.addSubview(indicator)
let safeAreaGuide = self.view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
indicator.centerXAnchor.constraint(equalTo: saveAreaGuide.centerXAnchor),
indicator.centerYAnchor.constraint(equalTo: saveAreaGuide.centerYAnchor)
])
你可以使用这个:
func setActivityIndicatorTo(view: UIView, indicator: UIActivityIndicatorView){
indicator.setTranslatesAutoresizingMaskIntoConstraints(false)
view.addConstraint(NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))
}
Or you can found center of screen below:
let w = UIScreen.main.bounds.width
let h = UIScreen.main.bounds.height
activity.center = CGPoint(x: w / 2, y: h / 2)
SWIFT 3:
Extension 将子视图置于您 App delegate 的 keyWindow 中...使其居中,无论它在您的应用程序中的什么位置:
extension UIView {
public func addSubviewScreenCenter() {
if let keyWindow = UIApplication.shared.keyWindow {
keyWindow.addSubview(self)
self.center()
}
}
public func removeFromWindowView() {
if self.superview != nil {
self.removeFromSuperview()
}
}
}
UIView
上有在不同视图坐标系之间转换点和框架的方法(iOS 2.0+、https://developer.apple.com/documentation/uikit/uiview/1622424-convert 支持)。
extension UIView {
func centerInContainingWindow() {
guard let window = self.window else { return }
let windowCenter = CGPoint(x: window.frame.midX, y: window.frame.midY)
self.center = self.superview.convert(windowCenter, from: nil)
}
}
A UIView
指定其相对于其父视图的坐标,因此 centerInContainingWindow()
使用 UIView.convert(_:from:)
获取相对于其父视图坐标的 window 的中心。
- 图#1,导航栏下视图:视图占满整个window,所以转换前后中心点相同
- 图#2,视图不在导航栏下:视图只填充了window的一部分,因此转换后window中心将移动到屏幕上的同一位置。