【发布时间】:2022-01-02 04:41:50
【问题描述】:
我无法弄清楚如何完成看似非常简单的任务。我有一个 macOS 可可应用程序,它由一个带有自定义视图的窗口组成。视图为 600x500 点。在这个视图内部是一个子视图,它跨越了主视图的整个宽度,但只是视图高度的一小部分。它的垂直原点大约在 y=200。
子视图从左右边界开始 20 点开始绘制一个矩形,高度约为 30 点。它还使用它的层和一个 CAEmitter 层作为子层。这个发射器的位置可以由用户控制,因此它的位置将由从视图外部调用的函数更新。
我想要什么:
当用户调整窗口大小时,它应该只按比例缩放(我设法做到了),以便窗口的内容作为一个整体得到调整大小。任何子视图都不应该以任何方式重新排列,它们都应该保持它们的大小和位置相对于彼此,只是变大/变小。
我没有让这个工作。
到目前为止我所尝试的:
- 如果没有设置其他属性,我可以调整窗口大小,但是 subiew 根本不缩放,它坚持它在 监督。
- 我为 trailingAnchor 设置了
subView.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor).isActive = true和相同的设置,另外我设置了subView.autoresizingMask = [.width]现在子视图中绘制的矩形的宽度得到了调整,但矩形的边缘远离边界 20 个点。我也想缩放这个距离。 - 矩形的高度保持不变。当我将
-heigth添加到子视图的自动调整大小蒙版时,高度会以一种非常不成比例的方式扭曲(到顶部和底部边距的距离保持不变,因此虽然子视图的高度在开始时只有大约 30,但矩形在调整大小时会被炸毁. - 发射器未重新定位。它的水平位置是根据用户交互计算的,并且是相对于视图的边框,在调整大小后它会保持在其绝对位置。我通过调用 draw() 方法的计算函数解决了这个问题,但这对我来说似乎不正确
在 cocoa 框架中有太多关于大小、锚点、约束等的入口点,我根本不知道从哪里开始,所以任何帮助将不胜感激。
更新:我添加了精简到最小值的代码:
class MyViewController: NSViewController {
public init () {
super.init(nibName: nil, bundle: nil)
self.view = MyView(frame: NSRect(x: 0, y: 0, width: 600, height: 500))
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class MyView: NSView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
let subView = MySubView(frame: NSRect(x: 0, y: frame.height/3, width: frame.width, height: frame.height/10))
self.addSubview(subView)
subView.autoresizingMask = [.width, .height]
subView.translatesAutoresizingMaskIntoConstraints = true
subView.trailingAnchor.constraint(greaterThanOrEqualTo: self.trailingAnchor).isActive = true
subView.leadingAnchor.constraint(greaterThanOrEqualTo: self.leadingAnchor).isActive = true
}
required init?(coder decoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class MySubView: NSView {
override func draw(_ dirtyRect: NSRect) {
let context = NSGraphicsContext.current!.cgContext
context.setStrokeColor(.black)
context.setFillColor(CGColor.init(red: 0.7, green: 0.7, blue: 0.7, alpha: 1))
context.setLineWidth(2)
let borderRect = CGRect(x: constant.sideMargin, y: 5, width: frame.width-2*constant.sideMargin, height: frame.height-10)
let roundedRect = CGPath.init(roundedRect: borderRect, cornerWidth: 5, cornerHeight: 5, transform: nil)
context.addPath(roundedRect)
context.fillPath()
context.strokePath()
context.addPath(roundedRect)
context.strokePath()
}
}
【问题讨论】:
-
setBoundsSize 是您要找的吗?
-
提示:如果
translatesAutoresizingMaskIntoConstraints未关闭,autoresizingMask将转换为约束。 Xcode 可以在运行时显示视图和约束。 -
说实话,我还是没有头绪。我在精简版本中添加了我的代码。在 AppDelegate 中,我将窗口设置为固定的纵横比。调整窗口大小时,子视图内容(矩形)的左右边缘跟随边框,但即使这不是我想要的。它应该保持它的相对距离,所以边距应该变大一点。矩形的上边距似乎固定在视图的中心,而不是停留在高度的 ⅓。我迷路了!!!