自定义 UIView 重绘视图控制器
Posted
技术标签:
【中文标题】自定义 UIView 重绘视图控制器【英文标题】:Custom UIView Redrawing View Controller 【发布时间】:2018-09-22 08:23:36 【问题描述】:我的第一篇文章,所以我希望我在做正确的事情。
我有一个自定义 UIView,其中包含一组自定义 UIButton。
我已经覆盖了具有以下代码的 func draw(_ rect: CGRect):
override func draw(_ rect: CGRect)
// remove all buttons currently on the bar
self.subviews.forEach $0.removeFromSuperview()
// process all buttons that are not hidden
var i = 0
for btn in buttons
if !btn.button.isHidden
self.addSubview(btn.button)
// set constraints with SnapKit
btn.button.snp.makeConstraints (c) in
c.size.equalTo(buttonSize)
c.left.equalToSuperview().offset(padding.width + (isVertical ? 0 : (i * buttonSize.width)))
c.top.equalToSuperview().offset(padding.height + (isVertical ? (i * buttonSize.height) : 0))
i += 1
// set button bar's constraints
snp.updateConstraints (c) in
if isVertical
c.height.equalTo(max(visibleCount, 1) * buttonSize.height + 2 * padding.height)
else
c.width.equalTo(max(visibleCount, 1) * buttonSize.width + 2 * padding.width)
每当我执行 setNeedsLayout() 时,它都会按预期执行,但它也会在同一个超级视图中重新定位 UIImage。
这会导致问题,因为 UIImage 可以平移并重新居中不是预期的行为。
我通过注释不同的部分测试了上面的代码,发现正是当它定位按钮本身时才会导致这种行为。
当然,这不是我想要的行为。
欢迎任何帮助/想法/建议。
ViewController中添加子视图的顺序是……
private func setupViews()
view.backgroundColor = .green
view.addSubview(mapDisplay)
view.addSubview(contextMenu)
view.addSubview(FloatingMenu)
【问题讨论】:
您具体想要完成什么?我觉得你在滥用drawRect
... 在最基本的情况下,你应该绘图(贝塞尔路径,也许是图层)但删除子视图或更改约束?它们通常属于其他地方。
为简单起见,所有代码都在 draw func 中。它在 setupLayout、updateLayout 等单独的函数中。至于我想要完成什么?当按钮可见/隐藏时,按钮栏会增大/缩小。此功能基于用户选择。例如,如果他们单击“编辑”,则会显示两个控制编辑的按钮,“编辑”按钮会关闭编辑并隐藏这两个按钮。所有这些都有效 - 我的问题是它以某种方式影响了一个完全不相关的 UIImageView。
【参考方案1】:
拆开我的代码后,我自己解决了这个问题。
事实证明,我有一个空约束占位符用于有问题的 UIImageView,并且 SnapKit 将空约束作为显式指令来“删除”所有约束并将有问题的项目重置回“零”当其他东西调用时更新。
我认为这种行为是错误的,因为我的 UIView 是 View Controller 中的同级子视图,但是它确实存在......所以做类似的事情
mapDisplay.snp.makeConstraints (c) in
当 UIView 更新按钮位置时,由于某种原因,会使 UIImageView (mapDisplay) 快速回到屏幕中心。
我猜应该在他们的 gitHub 上发布。
【讨论】:
以上是关于自定义 UIView 重绘视图控制器的主要内容,如果未能解决你的问题,请参考以下文章