ios - 你如何使用 UIEdgeInsets?
问题描述
我一直在 Playground 上尝试不同的方式,但没有实现边距。我试图了解使用UIEdgeInsets
(和NSDirectionalEdgeInsets
)的正确方法。
期望超级视图应该具有指定大小的边距,而子视图应该在该边距内,有点像不可见的边框。
以下没有显示超级视图的任何边距:
import UIKit
import PlaygroundSupport
let rootView = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
rootView.layoutMargins = UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100)
let subview = UIView()
subview.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
subview.widthAnchor.constraint(equalToConstant: 100),
subview.heightAnchor.constraint(equalToConstant: 100)
])
subview.backgroundColor = .red
rootView.addSubview(subview)
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = rootView
我也尝试过:
rootView.layoutMargins.top = 100
或代替自动布局:
let subview = UIView(frame: CGRect(origin: .zero, size: .init(width: 100, height: 100)))
试过NSDirectionEdgeInsets
了,但没有用:
rootView.directionalLayoutMargins = NSDirectionalEdgeInsets(top: 100, leading: 100, bottom: 100, trailing: 100)
最后,我在视图控制器中尝试了它,但仍然是徒劳的:
class MyVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let rootView = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
rootView.layoutMargins = UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100)
self.view.addSubview(rootView)
let subview = UIView()
subview.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
subview.widthAnchor.constraint(equalToConstant: 100),
subview.heightAnchor.constraint(equalToConstant: 100)
])
subview.backgroundColor = .red
rootView.addSubview(subview)
}
}
解决方案
布局边距不能替代原本会指定视图位置的约束,它们与此类约束一起工作。您给出的示例不包含此类约束,因此布局边距不会产生任何影响。更重要的是,我的猜测是设置明确的高度和宽度约束会导致任何布局边距被忽略。
这张图片中展示的布局是使用下面的代码生成的,它利用 Auto Layout 的视觉格式语言来生成所需的约束。第一个约束将红色视图的垂直边缘固定到灰色视图的垂直边缘,而第二个约束对水平边缘执行相同的操作。至关重要的是,格式字符串包含的连字符向自动布局引擎发出信号,表明任何指定的布局边距也应该得到尊重,因此最终布局的红色视图边缘从灰色视图的边缘插入。如果您删除这些连字符(例如|[redView]|
),自定义布局边距将被忽略,您只会让红色视图与灰色视图的边缘齐平。
override func viewDidLoad() {
super.viewDidLoad()
let grayView = UIView(frame: CGRect(x: 0, y: 100, width: 300, height: 500))
let customInsets = NSDirectionalEdgeInsets(top: 40, leading: 5, bottom: 20, trailing: 15)
grayView.directionalLayoutMargins = customInsets
grayView.backgroundColor = .lightGray
view.addSubview(grayView)
let redView = UIView()
redView.backgroundColor = .red
redView.translatesAutoresizingMaskIntoConstraints = false
grayView.addSubview(redView)
let vrtConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|-[redView]-|", options: [], metrics: nil, views: ["redView":redView])
let hrzConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-[redView]-|", options: [], metrics: nil, views: ["redView":redView])
NSLayoutConstraint.activate(verticalEdgeConstraints + horizontalEdgeConstraints)
}
当然,您不必使用可视格式字符串来获得要尊重的布局边距:您也可以通过界面生成器“选择加入”。此选项在 Apple 的Positioning Content With Layout Margins指南中进行了探讨
推荐阅读
- spring - 请求被拒绝,因为 HTTP 方法“CONNECT”未包含在白名单中 [HEAD, DELETE, POST, GET, OPTIONS, PATCH, PUT]
- python - 一个处理程序可以在龙卷风中同时处理 post 和 get 的不同 URL
- android - 从两项活动中访问一项服务
- python - 带有变量的python中的awk命令
- ionic-framework - 我想在 Branch.io 中使用相同帐户和另一个帐户设置旧域名
- node.js - Node.JS 服务器、WebSockets 和 HTTP 与 HTTPS
- python - 我无法在列表中填充字典
- javascript - OAuth 弹窗跨域安全 React.js
- c# - 使用半正弦公式计算地理坐标距离会给出错误的输出
- python - 使用python从UDP数据包中删除前几个字节