ios - 尽管使用了 safeAreaLayoutGuide,但以编程方式在视图中创建约束并不是导航控制器的原因
问题描述
我创建了一个 UINavigationController 类,它允许用户注销并显示应用程序的标题。然后,我在其 viewControllers 数组中添加了一个 UITabController 作为其唯一的 viewController:
let homeController = HomeController()
viewControllers = [homeController]
这个 UITabController (HomeController()) 然后填充了一些 UIViewControllers - 其中一个将显示一个 Profile 页面。这是我的第一个项目,我不会使用故事板,所以事情是一个很大的挑战!
我在类中和我的个人资料页面的 viewDidLoad 中创建了一个 UIImageView 对象,我使用:self.view.addSubview(imageView)
添加到视图,然后:imageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
试图将图像锚定到屏幕顶部的 UINavigationController 栏的底部。然而,结果将图像放在屏幕的最顶部,就好像导航栏不被识别为可见一样。我在这篇文章中读到:https ://medium.com/@amlcurran/a-quick-guide-to-laying-out-views-in-ios-471e92deb74,'.topLayoutGuide.bottomAnchor' 代表导航的底部吧,但这现在已经贬值到我上面的例子了。有没有人知道什么是错的?还有任何好的资源让我完全理解以编程方式约束我的元素!谢谢大家!
https://gist.github.com/JoeMcGeever/a5ce3be94fc49a8f27b1a2867bd9495b
该链接显示了到目前为止的一些代码 - 我知道其他元素也固定在顶部;我只是想先解决这个关于导航栏的错误。
解决方案
您真的应该阅读几个自动布局教程。那里有很多很多。在你完成了十几个工作之后,你应该对需要做什么有一个很好的了解。
与此同时,这是您的ProfileViewController
编辑,让您了解自己做错了什么:
class ProfileViewController : UIViewController {
let imageView : UIImageView = { //creates an image view with the name "imageView"
let image = UIImage(named: "logo")
let imageView = UIImageView(image: image)
return imageView
}()
let usernameLabel = UILabel()
// if you're addint a target referring to "self", this must be a lazy var
lazy var editProfileButton : UIButton = {
let editButton = UIButton()
editButton.backgroundColor = .orange
editButton.setTitle("Edit Profile", for: .normal)
editButton.setTitleColor(.white, for: .normal)
editButton.addTarget(self, action: #selector(handleEdit), for: .touchUpInside)
return editButton
}()
@objc func handleEdit(){
//edit handle button
print("Edit profile")
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
self.title = "Profile"
usernameLabel.text = "Username Here"
// we're going to use auto-layout
[imageView, usernameLabel, editProfileButton].forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
}
self.view.addSubview(imageView)
self.view.addSubview(usernameLabel)
self.view.addSubview(editProfileButton)
// need FULL sets of constraints, not just TOP anchors
// respect safe-area
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// image view at upper-left
// image view 8-pts from top of safe area
imageView.topAnchor.constraint(equalTo: g.topAnchor, constant: 8.0),
// and 8-pts from left
imageView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0),
// give it a width of, for example, one-quarter the view width
imageView.widthAnchor.constraint(equalTo: g.widthAnchor, multiplier: 0.25),
// give it a 1:1 ratio (square)
imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor),
// button at upper-right
editProfileButton.topAnchor.constraint(equalTo: g.topAnchor, constant: 8.0),
editProfileButton.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0),
// no width or height... let the button size itself
// label below the image view
usernameLabel.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 8.0),
usernameLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0),
// no width or height... let the label size itself
])
// give the name label a background color so we can see its frame
usernameLabel.backgroundColor = .cyan
}
}
查看代码中的注释以了解我做了什么。
结果看起来像这样(我使用了一个随机图像作为徽标):
推荐阅读
- api - 在 ActiveCollab 中按 ID 查找任务
- azure-databricks - 从 Azure Databricks DBFS REST 2.0 API 读取文件
- java - spring-boot-starter-data-jpa@ManyToMany 集合未填充
- sql - 使用递归函数模拟 group_concat
- javascript - Bootstrap Multiselect 未发布选项
- ios - UINavigationController navBar 内的 UIPageViewController 中的 UITableViewController 不反弹
- bootstrap-4 - 有没有办法确定表格是否已经过验证?
- r - 将字符格式的时间转换为日期格式
- php - 写入单个名称四次连接到四个不同课程的while循环,如何修复
- javascript - V-model 未绑定到 DOM 元素中