iOS:热点指示器抛出的视图定位
iOS: Positioning of view thrown off by hotspot indicator
当我们遇到错误时,我们在 table 视图上显示一个带有标签的矩形:
使用此代码:
// Fix location of message bar even as user scrolls table - per
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
let newY = self.tableView.contentOffset.y + self.navigationController!.navigationBar.frame.size.height + UIApplication.shared.statusBarFrame.height
// Show rectangle using 0 and newY ...
它运行良好但在某些情况下不起作用,例如启用个人热点时。导航栏和状态矩形之间有一个空隙:
始终将某些内容置于导航栏下方的正确方法是什么?
在第一种情况下,状态栏高度为 20,但在第二种情况下为 40。在这两种情况下,导航栏和内容偏移量都相同。即:
- 案例 #1:偏移:-64.0,导航栏高度:44.0 状态栏高度:20.0
- 案例 #2:偏移:-64.0,导航栏高度:44.0 状态栏高度:40.0
状态栏中的高度变化似乎并没有增加偏移量。
更新:查看(我的)接受的答案。我确定有更好的方法.. 如果您知道,请添加到线程中。
不要使用从框架派生的值来定位您的消息,而是使用自动版式来定位它。
有几种方法可以实现这一点 - 一种方法如下:
//... assuming this is being called from the parent view controller
//safely unwrap the reference to the navigation controller
guard let navController = self.navigationController else { return }
let message = UIView()
//arbitrary styles for example only
message.backgroundColor = UIColor.blue
//set translatesAutoresizingMaskIntoConstraints so constraints will work
message.translatesAutoresizingMaskIntoConstraints = false
//create constraints
let height = NSLayoutConstraint(item: message, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: 50)
let equalWidth = NSLayoutConstraint(item: message, attribute: NSLayoutAttribute.width, relatedBy: .equal, toItem: navController.navigationBar, attribute: .width, multiplier: 1.0, constant: 0)
let alignBottom = NSLayoutConstraint(item: message, attribute: .top, relatedBy: .equal, toItem: navController.navigationBar, attribute: .bottom, multiplier: 1, constant: 0)
//apply constraints
message.addConstraint(height)
navController.view.addSubview(message)
navController.view.addConstraints([equalWidth, alignBottom])
这也可以使用 VFL 来完成 - 但它的冗长在这里可能有点矫枉过正。
否则,您可以使用很棒的库,使它更具声明性并减少样板 - 例如 SnapKit
我的 "poor man's solution" 是硬编码 20 作为状态栏高度:
var newY = self.tableView.contentOffset.y
newY += self.navigationController!.navigationBar.frame.size.height
newY += 20
必须是更好的方法...但这似乎有效。
property view.frame
能够捕捉到这样的变化。因此,对任何位置使用 view.frame.height
都可以防止重新定位。
它在有和没有热点栏的情况下找到合适的视图高度的方式:
//with hotspot bar
print (view.frame.height) //540.0
//without hotspot bar
print (view.frame.height) //560.0
//setting a navigation bar at top using height of view frame
let navigationBar : UINavigationBar = UINavigationBar(frame: CGRect(x: 0, y: 0, width:view.frame.width, height: view.frame.height/10))
navigationBar.backgroundColor = .gray
navigationBar.setItems([UINavigationItem(title: "navigaion bar")], animated: true)
let statusbar = UITableView()
//placing the status bar below the navigation bar
statusbar.frame = CGRect(x: 0, y: navigationBar.frame.size.height, width:view.frame.width, height: view.frame.height/10) //any choice for height:
view.addSubview(statusbar)
view.addSubview(navigationBar)
当我们遇到错误时,我们在 table 视图上显示一个带有标签的矩形:
使用此代码:
// Fix location of message bar even as user scrolls table - per
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
let newY = self.tableView.contentOffset.y + self.navigationController!.navigationBar.frame.size.height + UIApplication.shared.statusBarFrame.height
// Show rectangle using 0 and newY ...
它运行良好但在某些情况下不起作用,例如启用个人热点时。导航栏和状态矩形之间有一个空隙:
始终将某些内容置于导航栏下方的正确方法是什么?
在第一种情况下,状态栏高度为 20,但在第二种情况下为 40。在这两种情况下,导航栏和内容偏移量都相同。即:
- 案例 #1:偏移:-64.0,导航栏高度:44.0 状态栏高度:20.0
- 案例 #2:偏移:-64.0,导航栏高度:44.0 状态栏高度:40.0
状态栏中的高度变化似乎并没有增加偏移量。
更新:查看(我的)接受的答案。我确定有更好的方法.. 如果您知道,请添加到线程中。
不要使用从框架派生的值来定位您的消息,而是使用自动版式来定位它。
有几种方法可以实现这一点 - 一种方法如下:
//... assuming this is being called from the parent view controller
//safely unwrap the reference to the navigation controller
guard let navController = self.navigationController else { return }
let message = UIView()
//arbitrary styles for example only
message.backgroundColor = UIColor.blue
//set translatesAutoresizingMaskIntoConstraints so constraints will work
message.translatesAutoresizingMaskIntoConstraints = false
//create constraints
let height = NSLayoutConstraint(item: message, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: 50)
let equalWidth = NSLayoutConstraint(item: message, attribute: NSLayoutAttribute.width, relatedBy: .equal, toItem: navController.navigationBar, attribute: .width, multiplier: 1.0, constant: 0)
let alignBottom = NSLayoutConstraint(item: message, attribute: .top, relatedBy: .equal, toItem: navController.navigationBar, attribute: .bottom, multiplier: 1, constant: 0)
//apply constraints
message.addConstraint(height)
navController.view.addSubview(message)
navController.view.addConstraints([equalWidth, alignBottom])
这也可以使用 VFL 来完成 - 但它的冗长在这里可能有点矫枉过正。
否则,您可以使用很棒的库,使它更具声明性并减少样板 - 例如 SnapKit
我的 "poor man's solution" 是硬编码 20 作为状态栏高度:
var newY = self.tableView.contentOffset.y
newY += self.navigationController!.navigationBar.frame.size.height
newY += 20
必须是更好的方法...但这似乎有效。
property view.frame
能够捕捉到这样的变化。因此,对任何位置使用 view.frame.height
都可以防止重新定位。
它在有和没有热点栏的情况下找到合适的视图高度的方式:
//with hotspot bar
print (view.frame.height) //540.0
//without hotspot bar
print (view.frame.height) //560.0
//setting a navigation bar at top using height of view frame
let navigationBar : UINavigationBar = UINavigationBar(frame: CGRect(x: 0, y: 0, width:view.frame.width, height: view.frame.height/10))
navigationBar.backgroundColor = .gray
navigationBar.setItems([UINavigationItem(title: "navigaion bar")], animated: true)
let statusbar = UITableView()
//placing the status bar below the navigation bar
statusbar.frame = CGRect(x: 0, y: navigationBar.frame.size.height, width:view.frame.width, height: view.frame.height/10) //any choice for height:
view.addSubview(statusbar)
view.addSubview(navigationBar)