自定义 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 重绘视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

使用来自多个视图控制器的自定义 UIView

在视图控制器中使用自定义 uiview

iOS - 将自定义 UIView 放在视图控制器中

自定义 UIView 标签和动画未显示在视图控制器中

将数据从自定义表格视图单元格传递到 UIView 控制器

如何以编程方式将自定义 uiview 添加到视图控制器 SWIFT