iOS:热点指示器抛出的视图定位

时间:2017-04-18 00:44:04

标签: ios swift uinavigationbar cgrect

当我们遇到错误时,我们正在显示一个带有标签的矩形:

enter image description here

使用此代码:

    // Fix location of message bar even as user scrolls table - per http://stackoverflow.com/q/7537858/47281
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 ... 

它运行良好但在某些情况下不起作用,例如启用个人热点时。导航栏和状态矩形之间存在间隙:

enter image description here

在导航栏下始终定位内容的正确方法是什么?

在第一种情况下,状态栏高度为20,但在第二种情况下,它为40.在两种情况下,导航栏和内容偏移量都相同。即:

  • 案例#1:偏移:-64.0,导航栏高度:44.0状态栏高度:20.0
  • 案例#2:偏移:-64.0,导航栏高度:44.0状态栏高度:40.0

根据状态栏中的高度变化,似乎没有增加偏移量。

更新:查看(我的)已接受的答案。我确信有更好的方法..如果你知道一个,请加入主题。

3 个答案:

答案 0 :(得分:1)

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)

答案 1 :(得分:0)

不是使用从帧派生的值定位消息,而是使用autolayout定位它。

有几种方法可以实现这一点 - 您可以采用以下方法:

//... 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

答案 2 :(得分:0)

我的“穷人的解决方案”是硬编码20作为状态栏高度:

 var newY = self.tableView.contentOffset.y
 newY += self.navigationController!.navigationBar.frame.size.height
 newY += 20

必须是更好的方式......但这似乎有效。