添加的子视图位置稍微偏离 - 我怎样才能将它放回原位?

Posted

技术标签:

【中文标题】添加的子视图位置稍微偏离 - 我怎样才能将它放回原位?【英文标题】:Added subview is positioned slightly off - how can I get it back into place? 【发布时间】:2019-06-16 16:08:18 【问题描述】:

更新:已解决!虽然pianoNoteDisplayed 和piano_background 的contentMode 确实相同,但显然对于添加的子视图而言并非如此。我只是将 subview.contentMode = superview.contentMode 行添加到建议的函数 vdmzz 中,现在所有 4 种屏幕尺寸上的一切看起来都正确。

有两个图像视图:一个名为“piano_background”的视图包含背景图像(钢琴键盘),另一个将用于显示突出显示的音符。第二个受限于第一个:

(宽度约束可能是不必要的,因为已经设置了前导和尾随约束,对吧?)

为了显示多个突出显示的键,我以编程方式将子视图添加到 piano_note 视图并激活 NSLayoutConstraints 以使其就位(否则它会显示出位置不正确),如下所示:

pianoNoteDisplayed.image = nil

if !notesAlreadyAttempted.contains(currentUserAnswer) 

   let wrongNoteImageName = "large_\(currentUserAnswer)_wrong"
   let wrongNoteImage = UIImage(named: wrongNoteImageName)
   let wrongNoteImageView = UIImageView(image: wrongNoteImage!)

   wrongNoteImageView.translatesAutoresizingMaskIntoConstraints = false
   pianoNoteDisplayed.addSubview(wrongNoteImageView)

   NSLayoutConstraint.activate([
       wrongNoteImageView.widthAnchor.constraint(equalToConstant: pianoNoteDisplayed!.frame.width),
       wrongNoteImageView.heightAnchor.constraint(equalToConstant: pianoNoteDisplayed!.frame.height)
   ])

   

   notesAlreadyAttempted.append(currentUserAnswer)

问题是子视图显示稍微偏离,我似乎无法弄清楚原因:

(如您所见,高光看起来在垂直方向上略微压缩......顶部正确着陆,但底部距离不够远约 5px)

我已经尝试以多种方式居中和约束子视图,使用堆栈上大约 5 个不同答案的建议,以及我发现的其他几篇文章。我使用的图像(钢琴背景和重叠的音符突出显示子视图)大小相同。我尝试在界面构建器中添加或多或少的约束,并且尝试将子视图添加到原始的piano_background 视图而不是第二个pianoNoteDisplayed 视图-结果相同。顺便说一句,使用pianoNoteDisplayed 视图本身来显示突出显示的音符效果很好:

这些都是使用通常的 .image 方法显示的:

pianoNoteDisplayed.image = UIImage(named: "large_\(currentCorrectAnswer)_right")

对于如何进一步解决问题有什么建议吗?

【问题讨论】:

我怀疑您的问题是对安全区域的 centerY 约束,因为在所有情况下安全区域都不是以屏幕为中心的。如果图像尺寸相同,则将前导、顶部、尾随和底部约束设置为相等,并确保 imageViews 的 contentModes 相同。 如果这不起作用,我认为约束不是你的问题。 您是否尝试过使用调试视图层次结构查看它?那里可能有一些关于视图大小是否正确和/或图像由于某种原因绘制不正确的线索...... @Matvey - 将您的个人图像添加到您的问题中,以及对每个图像设置的约束的完整描述。 @Matvey - 您的图像似乎没有问题...仔细检查并确保您的所有图像视图都具有相同的.contentMode 设置。 【参考方案1】:

首先,据我了解pianoNoteDisplayed 不需要是 UIImageView。 其次,如果您将piano_backgroundpianoNoteDisplayed 按顶部、前导、后沿和底部边缘对齐,则其中一个将完全位于另一个之上。或者您可以将它们设置为相等的高度、宽度和中心位置。 您当前的一组约束的问题是 piano_background 的 Y 位置由安全区域确定,因此可能会延迟 pianoNoteDisplayed 的 Y 位置。

尝试使用此功能:

func addSameSize(subview: UIView, onTopOf superview: UIView) 
    superview.addSubview(subview)

    subview.translatesAutoresizingMaskIntoConstraints = false

    subview.centerXAnchor.constraint(equalTo: superview.centerXAnchor).isActive = true
    subview.centerYAnchor.constraint(equalTo: superview.centerYAnchor).isActive = true
    subview.widthAnchor.constraint(equalTo: superview.widthAnchor).isActive = true
    subview.heightAnchor.constraint(equalTo: superview.heightAnchor).isActive = true

    subview.contentMode = superview.contentMode

例如

addSameSize(subview: wrongNoteImageView, onTopOf: pianoNoteDisplayed)

它将添加您的图像视图与pianoNoteDisplayed 视图完全对齐

【讨论】:

谢谢,但不幸的是我得到了相同的结果......使用这样的单独函数肯定更干净,所以它仍然是一个改进:) 您提到“pianoNoteDisplayed 不需要是 UIImageView”——您认为这很关键吗?我在代码的其他几个部分将它用作 UIImageView(例如:pianoNoteDisplayed.image = UIImage(named: "large_(currentCorrectAnswer)_right"),因为我只需要显示一个图像。 另外,我没有更改情节提要上的任何约束,因为我假设编程约束会覆盖这些约束——这是正确的吗? 天啊,我想我修好了。仍然不确定问题是什么,但我认为这是一种奇怪的钢琴背景约束情况。我删除了它的所有约束并重新做了,现在它工作得很好。奇怪的是,pianoNoteDisplayed.image = UIImage(named: "large_(currentCorrectAnswer)_right 之前工作得很好......但现在一切都很顺利,耶! 如果您非常确定您的约束是正确的,您可能需要检查您的 UIImageViews contentMode 是否相同。

以上是关于添加的子视图位置稍微偏离 - 我怎样才能将它放回原位?的主要内容,如果未能解决你的问题,请参考以下文章

基数排序

删除焦点上的初始inputfield值。。把它放回模糊状态以防

合并排序中子排序结果放回原数组时应注意的问题

如何将视图添加为某些控制器的子视图

我怎样才能更好地将这个按钮与中间的内容对齐?对我来说似乎偏离了中心:

添加全屏视图作为视图控制器的子视图